Step 8: TWI / I2C Explained

Picture of TWI / I2C Explained
I2C stands for Inter-Integrated Circuit. I2C busses are also known as TWI for Two Wire Interface, since it uses only two wires.

Related Readings:
On a TWI bus, the two signal wires are SDA and SCL, basically data and clock. These signals are open drain (meaning its logic level is either high impedance or low, it cannot ever be high), but there must be a pull-up resistor on each of these signals (we are using the AVR's internal pull-up resistors). This is significant because any device on a TWI bus can drive the signals low at any time, so the signal can only become high when all the devices allow it to become high. This allows devices to detect when the bus is occupied ("arbitration using SDA") and also allow a slow device to dictate the speed of the clock, or even pause a transmission if the slower device is too busy (doing this is called "clock stretching". These facts makes the TWI bus good for communication between a bunch of chips using only two wires.

Every transaction is between a master (the one driving the clock signal) and a slave device. Every transaction starts with a "start condition" and ends with a "end condition". A start condition is when the bus master drives SDA low first, then driving SCL low second. An end condition is when the master releases the TWI bus by releasing SCL and then releasing SDA.

After the start condition, the master has to choose which device to talk to by sending a 7 bit address byte. The 8th (last being sent) bit indicates whether or not the master wishes to read (1) from or write (0) to the slave being addressed. If the master is writing, it will then send more data. If the master is reading, it will release the SDA line so the slave sends data (but the master is still driving the clock). When addressed

All bytes are sent MSB first (most significant bit first). Every byte is optionally ended by an acknowledgement/nacknowledgement. Check the device datasheet to see what the device will expect or will send back. Usually, to quote Wikipedia: "If the master wishes to write to the slave then it repeatedly sends a byte with the slave sending an ACK bit. (In this situation, the master is in master transmit mode and the slave is in slave receive mode.) If the master wishes to read from the slave then it repeatedly receives a byte from the slave, the master sending an ACK bit after every byte but the last one. (In this situation, the master is in master receive mode and the slave is in slave transmit mode.)"

More intricate details are usually specific to a particular device, and such information will come from its datasheet.

When I use I2C/TWI with AVR microcontrollers, I use the low level layer of the "Wire" library for Arduino. The Wire library is the C++ wrapper for the lower level "twi.c" and "twi.h" module, which I modify slighly and compile into my own code (since I don't usually use C++). It takes care of almost everything.

The Wii Classic Controller has a I2C address of 0x52, keep that in mind. Using "twi.c" and "twi.h", to send some data to the Wii Classic Controller, start by creating a byte array containing the data to be sent, and then pass that to the "twi_writeTo" function, along with the destination address, the amount of data to send, and tell it "wait until all data is sent". The code will look like:
unsigned char dataArray[3] = { 'a', 'b', 'c', };
twi_writeTo(0x52, dataArray, 3, 1);

To read three bytes, use the function "twi_readFrom", and tell it the address, the data is saved to a array you pass in, and you specify the amount of data. The code looks like:
unsigned char dataArray[3];
twi_readFrom(0x52, dataArray, 3);

Remove these adsRemove these ads by Signing Up