Thursday, October 3, 2013

I2C Bus

I2C is, it is a communications bus invented by Philips.Unlike the UART, which is an asynchronous form of communication, the I2C is synchronous. The master device sends both the data signal, as well as the clock signal, with the exception during data reads. The receiver syncs up with the clock signal, and samples the data on the rising edge of the clock. Ultimately, this means that the transmitter and receiver do not need to know the clock rate because a clock signal is sent along with data.
There are upper limits to how fast you can send the clock signal, but as long as you are below the upper limits, the bus will work fine. The I2C bus requires two wires to be connected between the master and slaves, as well as a return (GND) wire. This usually means that at least three wires needs to be connected from the master to the slave. However, there are several advantages over other forms of buses for communications between chips. Personally I prefer using the I2C for the ease of use and reliability of communications. The minimal clock calculations, most of the time as an afterthought is a huge advantage over the UART. In addition, you can also establish communications between more than just two chips. There are provisions in the I2C standard that allows for multiple devices, and layers of software and hardware to decode the transmission so that the packet sent by the master device gets accepted by the intended slave device, and only by the intended slave device. This is NOT the case in the UART.
There are two main types of operations the I2C bus. These are the random write command, and the random read command.

Three bytes are sent from the master device, and received by the slave if he is present on the bus. The first byte is the slave address and the read/write indicator. The first 7 bits is the slave device address. This value is always indicated in the data sheet of the slave address. In order for the I2C bus to allow for multiple slaves, the master must indicate which device the message is intended. The slave address, which begins every I2C transaction is the address that corresponds to a devices on the bus. Obviously there cannot be multiple slaves with the same address. This would create a collision on the I2C bus. The 8th bit of the first byte is the read/write indicator. If the bit is a 0, the master wants to write a byte, if it is a 1, the master intends to read. Next, on the 9th bit of the first byte, the master waits for an acknowledge bit from the slave. If the address sent by the master corresponds to the slave address of a slave device, the slave device MUST acknowledge on the 9th bit. If the /ACK is a 1, a non-acknowledge, then the master thinks there is no slave with the sent address. It terminates the packet with a STOP bit. However, if a slave does send back a /ACK with logical 0, then the master device begins sending the second byte. The second byte is usually the slave’s internal address (referred to as the “WORD ADDRESS” in the above drawing). For example, on the AT24C02B EEPROM, there are 256 memory locations of 8 bits each. Whenever I want to write to the device, I must specify which one of the 256 memory locations I wish to write to. This is what the second byte of the packet is usually used for. On the 9th byte of the second byte the slave device must acknowledge that the specified address exists as one of the slave device’s internal addresses. Lastly, the master device sends the data it intends to write. This is usually referred to as the data byte. Finally the slave device acknowledges the received byte, and the communications is terminated by a stop bit.

The second most commonly used command is the random read. It is called a random read because this is the ability to read any address at will, as opposed to a sequential read, everything must be read, until the correct piece of data is located. Think of it as a DVD, where you can access anything instantly, versus a VCR, where you need to wined the tape to the correct spot before watching a particular scene.
A random read must be done in the following manner. The master device must first act like it intends to do a random write by sending the slave device address with a write command bit (recall that the slave address is 7 bits long, NOT 8 bits long, the last bit of the first byte is reserved for the read/write command indicator). It then sends the internal address just as if it intends to do a device write. The slave address must send a /ACK on 9 th bit of both the bytes to indicate to the master device of its presence. However, at the end of the 2nd byte, the master device resents a start bit. For the 3rd byte, the master device resends the slave address, but with the read command bit for the 8th bit of the 3rd byte. At this point, after the slave address sends a /ACK back to the master, the roles are reversed between the slave and master. On the next byte, the slave device takes over the SDA line and waits for /ACKs from the master device. After the slave device takes over the SDA line, it starts transmitting the byte located at the internal address. The slave device starts manipulating the SDA line according to the clock. On each of the rising edge of the SCL line, sent by the master device, the slave device must be ready with the bit it intends the master device to read. After the 8th bit is sent, the master device must indicate a /NACK, the inverse of the inverse-ACK (logical 1) to tell the slave device to stop taking control of the SDA line. It ends the transmission with a stop bit.


The two advanced packet formats are the sequential write and the sequential read. As you can see from the two basic packet formats, there are a lot of overhead data required to write one or two bytes to a device. What I mean by this is that, if I want to write 8 bytes to an EEPROM device with my PIC24, I will need to actually send 24 bytes of data using random write commands. This is because 8 bytes of the data is used to send the slave address, 8 bytes of the data is used to send the internal address, and finally 8 bytes of data is the actual data that I wish to write. In addition, EEPROMs have long write cycles of several milliseconds. To get around these limitations, most EEPROM have the ability to write 8 or so bytes in one “sequential write”. In addition, most EEPROMs allow you to read all its data in one sequential read.
A sequential write is very similar to a random write. The master device sends the exact same packet as a single write. However, after the /ACK bit of the 3rd byte is sent, it DOES NOT send a stop bit. It continues to send data, expecting a /ACK from the slave after each byte. After each transmitted byte, the internal address of the slave device is automatically incremented, and therefore the master device does not have to manually select the next internal address. Usually sequential writes are limited to about 8 bytes before the internal buffer of the slave device is full, in which case it will stop sending /ACKs, indicating that something is wrong. After the last byte that the master wishes to send, and waiting for the corresponding /ACK signal from the slave device, the master device sends a stop bit to terminate the transmission.The master device sends the exact same packet as a single read. But whereas in a random read the master sends a /NACK to stop the transmission, this time it send a /ACK to indicate to the slave device that it wants more data. The internal address is automatically incremented and the next byte of data is sent by the slave. The slave will keep on sending data until it receives a /NACK, at which point the master device terminates the transmission with a stop bit. There are usually no limitations on how many bytes the slave is limited to sending. The slave device just keeps on sending data on the SDA line unit it receives a /NACK from the master.