The Inter-Integrated Circuit is a serial protocol (usually shortened to I²C or I2C), which allows multiple peripheral (or slave) chips to communicate with one or more controller (or master) chips. Many devices can be connected to the same I²C bus and messages can be sent to a particular device by specifying its I²C address. The protocol requires two signal wires and can only be used for short-distance communications within one device.

One of the signal lines is for data (SDA) and the other is for the clock signal (SCL). The lines are pulled-high by default with some resistors fitted somewhere on the bus. Any device on the bus (or even multiple devices simultaneously) can 'pull' either or both of the signal lines low. This means that no damage occurs if two devices try and talk on the bus at the same time - the messages are merely corrupted (and detectably so).

An I²C transaction consists of one or more messages. Each message is comprised of a start symbol, some words, and finally a stop symbol (or another start symbol if there is a follow-on message). Each word is eight bits, followed by an ACK (0) or NACK (1) bit which is sent by the recipient to indicate whether the word was received and understood correctly. The first word indicates both the 7-bit address of the device the message is intended for, plus a bit to indicate if the device is being read from or being written to. If there is no device of that address on the bus, the first word will naturally have a 'NACK' after it (because there is no device driving the SDA line low to generate an 'ACK' bit) and so you know there is no device present.

The clock frequency of the SCL line is usually 400 kHz but slower and faster speed are supported (standard speed are 100kHz-400kHz-1MHz).In our exercise, the configuration will be 400 kHz ( <MasterConfig as Default>::default().baudrate(400.kHz().into())).

To read three bytes from an EEPROM device, the sequence will be something like:

StepController SendsPeripheral Sends
2.Device Address + W
4.High EEPROM Address byte
6.Low EEPROM Address byte
9.Device Address + R
11.Data Byte from EEPROM Address
13.Data Byte from EEPROM Address + 1
15.Data Byte from EEPROM Address + 2
16.NAK (i.e. end-of-read)

I²C signal image

A sequence diagram of data transfer on the I²C bus:

  • S - Start condition
  • P - Stop condition
  • B1 to BN - transferring of one bit
  • SDA changes are allowed when SCL is low (blue), otherwise there will be a start or stop condition generated.

Source & more details: Wikipedia.