I2C Basics

I2C Basics

I2C is perhaps the most commonly used bus to connect ICs together. As such, firmware engineers encounter it on most projects. In this post, we explain how I2C works, explore common bugs and investigate how to debug these issues.

No alt text provided for this image

The I2C bus is a very popular and powerful bus used for communication between a master (or multiple masters) and a single or multiple slave devices. The above figure illustrates how many different peripherals may share a bus which is connected to a processor through only 2 wires, which is one of the largest benefits that the I2C bus can give when compared to other interfaces

Why use I2C

I2C has many advantages:

  • 1. It is cheaper to implement than comparable low-power buses, with fewer pins than SPI, and a simpler physical layer than CAN (no differential signalling).
  • 2. It supports up to 127 devices on a bus with only two pins.
  • 3. It has transfer rates up to 400Kbps, which is fast enough for many human interfaces as well as fan control, temperature sensing and other low-speed control loops.
  • 4. Historically, it has been less onerous for manufacturers to include than competing protocols like Maxim’s 1-wire protocol.

Many of the sensors and actuators in devices all around us use I2C: temperature sensors, accelerometers, gyroscopes, fans, video bridging chips, GPIO expanders, EEPROMs, …etc.

I2C is not appropriate for all applications however:

  • 1.When higher bandwidth is required, SPI may be the right choice and can be found in many NOR-flash chips. MIPI can go even faster, and is often used in displays and cameras.
  • 2.If reliability is a must, CAN is the bus of choice. It is found in cars and other vehicles.
  • 3.When a single device is on the bus, UART may work just as well.

Anatomy of an I2C transaction

I2C is made up of two signals: a clock (SCL), and a data line (SDA). By default, the lines are pulled high by resistors. To communicate, a device pulls lines low and releases them to let them rise back to high.

Ones and Zeroes

As a digital bus, I2C ultimately transmits 1s and 0s between two circuits. It does so using a very simple scheme: for pulse on the SCL line, one bit is sampled from the SDA line. For this to work properly, the SDA line must remain stable between the leading and falling edge of every SCL pulse. In other word, the value of the SDA line while the SCL line is high is the value of the transmitted bit.

For example, this is 0xC9 over I2C:

SDASCLbits11001001

General I2C Operation

The I2C bus is a standard bidirectional interface that uses a controller, known as the master, to communicate with slave devices. A slave may not transmit data unless it has been addressed by the master. Each device on the I2C bus has a specific device address to differentiate between other devices that are on the same I2C bus. Many slave devices will require configuration upon startup to set the behavior of the device. This is typically done when the master accesses the slave's internal register maps, which have unique register addresses. A device can have one or multiple registers where data is stored, written, or read.

The physical I2C interface consists of the serial clock (SCL) and serial data (SDA) lines. Both SDA and SCL lines must be connected to VCC through a pull-up resistor. The size of the pull-up resistor is determined by the amount of capacitance on the I2C lines (for further details, refer to I2C Pull-up Resistor

Data transfer may be initiated only when the bus is idle. A bus is considered idle if both SDA and SCL lines are high after a STOP condition.

The general procedure for a master to access a slave device is the following:

  • 1. Suppose a master wants to send data to a slave:
  • Master-transmitter sends a START condition and addresses the slave-receiver
  • Master-transmitter sends data to slave-receiver
  • Master-transmitter terminates the transfer with a STOP condition
  • 2. If a master wants to receive/read data from a slave:
  • Master-receiver sends a START condition and addresses the slave-transmitter
  • Master-receiver sends the requested register to read to slave-transmitter
  • Master-receiver receives data from the slave-transmitter
  • Master-receiver terminates the transfer with a STOP condition

Start and Stop

Since an I2C bus may have multiple masters, there must be a way to signal that the bus is in use. This is accomplished with the START and STOP conditions. Every I2C command starts with a START condition and ends with a STOP condition.

To send a START, an I2C master must pull the SDA line low while the SCL line is high. After a START condition, the I2C master must pull the SCL line low and start the clock.

To send a STOP, an I2C master releases the SDA line to high while the SCL line is high.

In the diagram below, we indicate the START and STOP condition with “S” and “P” respectively.

Addresses

I2C is a multi-slave bus, so we must have a way to indicate which slave we would like to send a given command to. This is accomplished with addresses. I2C addresses are 7 bits, a few addresses are reserved and the rest are allocated by the I2C-bus committee. Note that a 10-bit address extension does exist, but is extremely uncommon.

To communicate with a slave device, an I2C master simply needs to write its 7-bit address on the bus after the START condition. For example, the waveform below captures an I2C transaction to a slave with address 0x66:

SDASCLbits11001001

Address Conflicts: Since the I2C address space is so limited, address conflicts are not uncommon. For example, you may want to include multiple instances of the same sensor on a single I2C bus.To enable this use case IC designers typically allow their customers to set a few bits of a device’s I2C address, either by tying pins high or low, or by writing a register. If all else fails, you may use an I2C multiplexer to resolve addressing conflicts.

Reading and Writing

I2C masters may read or write to slave devices. This is indicated with a single bit transmitted after the address bits. A 1 means the command is a read, and a 0 means it is a write.

The example below shows a read sent to the slave device at address 0x66.

SDASCLbitsS1100110101PdataAddress: 0x66W

A common pattern is to send a write followed by a read. For example, many devices expose several registers that can be read/written by first sending the register address to the device in with a write command.

To achieve this, the I2C master must first send a write command with the register address, followed by a second START condition and a full read command (including the slave address).

For example, this is what a write-then-read transaction to read register 0x11 from the slave device at address 0x66 would look like:

SAddress: 0x66WReg Address: 0x11SAddress: 0x66RDataP

Note: I2C does not have a formal way for a slave device to send a command to a master device. Instead, most devices use an additional pin to signal to the master that it should get in touch. Typically, this ends up working like this: the slave device sets that GPIO to high, which raises an interrupt with the master device. The master device then reads a “interrupt source” register which indicates why the slave device raised the interrupt, and goes on to query the device for the information.

Ack/Nack

Each byte of data (including the address byte) is followed by one ACK bit from the receiver. The ACK bit allows the receiver to communicate to the transmitter that the byte was successfully received and another byte may be sent.

The I2C protocol specifies that every byte sent must be acknowledged by the receiver. This is implemented with a single bit: 0 for ACK and 1 for NACK. At the end of every byte, the transmitter releases the SDA line, and on the next clock cycle the receiver must pull the line low to acknowledged the byte.

When the line remains high during the next clock cycle, it is considered a NACK. This can mean one of several things:

  • 1. A NACK after an address is sent means no slave responded to that address
  • 2. A NACK after write data means the slave either did not recognize the command, or that it cannot accept any more data
  • 3. A NACK during read data means the master does not want the slave to send any more bytes.

When the SDA line remains high during the ACK/NACK-related clock period, this is interpreted as a NACK. There are several conditions that lead to the generation of a NACK:

  • 1. The receiver is unable to receive or transmit because it is performing some real-time function and is not ready to start communication with the master.
  • 2. During the transfer, the receiver gets data or commands that it does not understand.
  • 3. During the transfer, the receiver cannot receive any more data bytes.
  • 4. A master-receiver is done reading data and indicates this to the slave through a NACK.

Below is an example of a full I2C write command, with the ACK bits included. It writes 0x9C to the slave at address 0x66.

No alt text provided for this image
Note: A NACK is not necessarily an error condition, it sometimes can be used to end a read. For example, reading 8 bytes from an I2C EEPROM would be implemented by sending a write command to set the EEPROM address offset we want to read from, followed by command which would NACK the 8th byte to signal to the EEPROM device that no more bytes are needed.

I2C Data

Data must be sent and received to or from the slave devices, but the way that this is accomplished is by reading or writing to or from registers in the slave device. Registers are locations in the slave's memory which contain information, whether it be the configuration information, or some sampled data to send back to the master. The master must write information into these registers in order to instruct the slave device to perform a task.

While it is common to have registers in I2C slaves, please note that not all slave devices will have registers. Some devices are simple and contain only 1 register, which may be written directly to by sending the register data immediately after the slave address, instead of addressing a register. An example of a single-register device would be an 8-bit I2C switch, which is controlled via I2C commands.

Since it has 1 bit to enable or disable a channel, there is only 1 register needed, and the master merely writes the register data after the slave address, skipping the register number.

Clock Stretching

While control of the SCL line is the domain of the I2C master, an optional feature of the protocol allows slaves to temporarily control it to slow down transmission before it is ready to accept more data.

To stretch the clock, the slave device simply holds the SCL line down. In that state, the master device must wait for the clock rises back up to high before resuming transmission.

This feature is sometimes a source of trouble: not every device supports it, and a master device with no support for clock stretching will hit errors if a slave device attempts to hold the clock down.

To view or add a comment, sign in

More articles by KRISHNA N.

Explore content categories