I2C is a synchronous, serial communication bus which facilitates communication between a controller (or multiple controllers) and a single or multiple peripheral devices, using only 2 wires (SDA and SCL).

Figure 1: Typical example I2C Bus

Figure 1: Typical example I2C Bus

Data rates for I2C fall between asynchronous serial (like UART) and SPI; most I2C devices can communicate at 100kHz or 400kHz.

At a hardware level, each I2C bus consists of two signals, the clock signal (SCL) and the data signal (SDA). The clock signal is ALWAYS generated by the current bus controller, though some peripherals may force the clock low at times to delay the controller sending more data (aka clock stretching).

I2C bus drivers are "open drain", meaning they can pull the corresponding signal line low, but cannot drive it high (thus no bus contention where one device is trying to drive the line high, while another drives low → causing a short). Each signal has a pull-up resistor on it to restore the signal to high when no device is asserting it low as shown in Figure 1. Note, sometimes boards have internal pull-up resistors for this already.

An I2C message is broken up into two types of frame: an ADDRESS frame, where the controller indicates the peripheral to which the message is being sent, and one or more DATA frames, which are 8-bit data messages passed from controller to peripheral or vice-versa.

I2C Message Breakdown

I2C Message Breakdown