8.1. Working#

We know that the voltage in both SCL and SDA lines is high during the idle state. The clock signal in SCL line is always generated by the controller. While the SDA line voltages can be changed by both the controller and the target. These changes are allowed to happen only when the SCL line is low except for Start and Stop conditions. Furthermore, the voltage measurement, indicating the value of a bit, is done only when the SCL line is high.

There are two challenges that needs to be tackled before the real information is communicated.

  1. The controller has to specify which target it wants to communicate with since there can be more than one targets.

  2. The controller has to define the flow of information since both the controller and a target cannot transmit data on the SDA line at the same time.

8.1.1. I2C Message#

Tackling of these challenges and the communication of the information is handled through I2C messages.

An I2C message always starts with a Start condition, where the controller pulls the SDA line low, i.e. the voltage is changed from 3.3V to 0V, while the SCL line is kept high.

The start condition is always followed by 7 or 10 bit Address. This is where the controller specifies which target it wants to communicate with. After the address, the controller sends a Read/Write bit. As the name suggests, it sends a 0 if it wants to write/transmit some data to the target otherwise it sends a 1 to read/receive some data. The controller releases the SDA line at this point for a target to change the voltage. If no target exists with the address specified by the controller, then the SDA line voltage stays high due to pull-up resistor representing a No acknowledgement. However, if a target does exist with the address specified, then it pulls the SDA line low as an Acknowledgement.

If the Ack was received and the Read/Write bit was 1 during the communication so far, then the control of SDA line is left with the target. Now the target can send 8-bits of data during next 8 clock cycles as shown in the figure below.

After the 8-bits of data, the controller sends an Ack to let the target know that it can send more data. This way, multiple bytes of data can be sent by the target. If the controller wants to stop receiving data, then it sends a Nack after any of the 8 data bits. This Nack bit can be followed by a Stop condition to indicate the end of a message, where the controller pulls the SDA line high while maintaining the SCL line as high.

To the contrary, if the Ack was received and the Read/Write bit was 0 during the initial communication, then the control handles the SDA line to transmit data in chunks of 8-bits as shown in the figure below.

Similar to the controller sending Ack after receiving every 8-bit chunk, here the target sends an Ack after receiving every 8-bit chunk. However, if the target sends a Nack after any byte then it can either mean that the target doesn’t understand the data received or the target is busy so it cannot process new data anymore. Regardless, the controller is allowed to end the message by sending the Stop condition after any of the Ack/Nack bit sent by the target.

The discussion of the I2C protocol so far is a concised version of the full I2C standard. This much information should be enough through this course. However, if you are interested in the I2C protocol further then the full specification is available here.

8.1.2. Example#

Let’s consider an example to better understand the I2C protocol. Following diagrams show I2C communication between the μC and an MCP9808 temperature sensor. Correct way to read these diagrams is to look for the SDA voltage values when SCL line is high.

In the diagram above, the μC sends a start bit. It is followed by the 7-bit target address, 0b0011000 defined on pg. 14 of the datasheet. Note that the information is sent MSB (Most Significant Bit) first here as opposed to LSB first in the case of UART. Finally, the controller specifies that it wants to write to the target by sending a 0. After this, the target sends an Ack by sending a 0.

Since the controller specified that it wants to write to the target, it sends 8-bits of data. This data is generally referred to as a Command or a Register. In this case, the command is 0b00000101, which tells the target that the controller wants to receive temperature values in the next message (pg. 16 of the datasheet). The target sends an Ack upon correctly identifying the command/register. Note that the end of the message should be indicated by the μC here by sending a stop condition. This would have been fine if there was only one controller present.

Instead, it sends a start condition. This situation is termed as Repeated Start. This is necessary if there are more than one controllers present and one of them wants to retain control of the SCL and SDA lines over multiple messages. Note that the complete communication in this example contains two messages that finally result in the controller attaining one reading from the temperature sensor. If the controller had sent a stop condition then another controller might have gained the control of SCL and SDA lines and this communication would not have completed. Apart from this, the other difference here is the μC now a read operation to the target, which is then acknowledged by the target.

Here, the target is sending first 8-bits of information, which is 0b00000001 in this case, and the controller is acknowledging the receipt of those 8-bits.

Here, the target is sending the second byte, which is 0b10010100, and then the controller indicates the end of message by sending a Nack and then a stop condition. Note that the number of bytes to be written or read by the controller is not predefined. It is up to the manufacturer to decide how the information should be formatted. Take a look at Section 5.1.3 of the datasheet to understand what the 2-bytes of data received by the controller mean.

8.1.3. Baud Rate#

Similar to UART, I2C protocol can also work at different Baud rates. Since I2C is a synchronous protocol, the devices communicating through I2C don’t have to know the baud rate. However, different devices may have a limitation on the maximum baud rate they support. So, the controller has to make sure that it is communicating at the baud rate that the target it is addressing to can handle. Following table lists the supported I2C baud rates.

Mode

Standard

Fast

Fast+

High-Speed

Ultra-Fast

Speed

100 kb/s

400 kb/s

1 Mb/s

3.4 Mb/s

5 Mb/s