UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 

IIC Protocol and Programming Sequence

Moderator
Moderator
0 0 223

What is I2C?

In this article, you will learn about the basics of Inter-Integrated Circuit (I2C or IIC) and usage of this protocol bus for short distance communication.

I2C is a serial protocol for two-wire interface to connect low-speed devices like EEPROMs, Sensors, RTC, ADC/DAC, and other compatible I/O interfaces in embedded systems. 

Introduction to I2C

I2C consists of two wires: an SCL (serial clock) and an SDA (serial data). Both need to be pulled up with a resistor to Vcc. There are also I2C multiplexers which are used for accessing various channel to interface with peripherals and there can also be level shifters to translate the voltage levels on these two I2C wires/signals.

Note: SCL is the clock signal, and SDA is the data signal. 

The data transfer format for I2C is explained below.

A single data transfer consists of 9 clock pulses to drive 8 bits of data and a 1 bit ACK/NACK.

I2C Data Transfer.jpg

The Data transfer frame has a START and a STOP condition.

An address type transfer is initiated with a START condition followed by a 7 bit/10 bit Address, a 1 bit R/~W and a 1 bit ACK/NACK. Later, a data type transfer has 8 bits of data and a 1 bit ACK/NACK.

 

I2C bus conditions

Start condition -  The SCL line should be high when there is high to low transition on the SDA.

Stop condition -  The SCL line should be high when there is low to high transition on the SDA.

Data validity    -  Data on the SDA line is valid and stable when the SCL is in a high state.

Data change   -  Data change occurs on the SDA line when the SCL is in a low state

Bus busy         -  Bus is busy between START and STOP conditions.

ACK                -  At the 9th clock pulse on the SCL, the SDA should be low

NACK             -   At the 9th clock pulse on the SCL, the SDA should be high

 

Master Write Transfer

Master Write operation begins with a START condition followed by 7 bit/10 bit slave address and a one bit write operation (equal to 0). A successful slave addressing is acknowledged (ACK) by the slave. Later, the master initiates data write to the slave and its ACK in response is provided by the slave for N-1 bytes. Once N-1 bytes have been transferred, the master sends Not Acknowledged (NACK) on the Nth byte transfer to generate a STOP condition.

A failure in slave addressing by the master will generate a NACK on the bus. As a result, no data transfer will be initiated and a STOP condition will be generated. 

Master Write.jpg

Master Read Transfer

Master Read operation begins with a START condition followed by 7 bit/10 bit slave address and one bit read operation (equals to 1). A successful slave addressing is acknowledged (ACK) by the slave. Later, the slave sends data to the master and its ACK in response is provided by the master for N-1 bytes. Once N-1 bytes have been received by the master, it sends a NACK on the Nth byte transfer to generate a STOP condition.

A failure in slave addressing by the master will generate a NACK on the bus. As a result no data read will be initiated and a STOP condition is generated. Master Read.jpg

 

Clock Stretching

SCL is generated by the active bus master. Slave devices can force the clock low at times to delay the master sending more data (or if they  require more time to prepare data before the master attempts to clock it out). This is known as clock stretching or throttling. For more information, see the protocol page of https://learn.sparkfun.com/tutorials/i2c/all

 

Dynamic Programming Sequence

It is easy to understand the protocol behavior in Xilinx AXI IIC simulation by using pseudo steps like the examples below and comparing them against the behavior you are seeing.

Keep a copy of the following steps and you can then edit it if you are omitting or appending any steps in your own design.

Alternatively, just fill in whichever is applicable for your test case.

 

Initialization

  1. Set the RX_FIFO depth to maximum by setting RX_FIFO_PIRQ = 0x _ _
  2. Reset the TX_FIFO with 0x_ _
  3. Enable the AXI IIC, remove the TX_FIFO reset, and disable the general call

 

Read Bytes from an IIC Device Addressed as 0x_ _

  1. Check that all FIFOs are empty and that the bus is not busy by reading the Status register
  2. Write 0x___ to the TX_FIFO (set start bit, device address to 0x__, read access)
  3. Write 0x___ to the TX_FIFO (set stop bit, four bytes to be received by the AXI IIC)
  4. Wait until the RX_FIFO is not empty.

a) Read the RX_FIFO byte.

b) If the last byte is read, then exit; otherwise, continue checking while RX_FIFO is not empty.

 

Write Bytes to an IIC Slave Device Addressed as 0x_ _

Place the data at slave device address 0x__:

  1. Check that all FIFOs are empty and that the bus is not busy by reading the SR
  2. Write 0x___ to the TX_FIFO (set the start bit, the device address, write access)
  3. Write 0x__ to the TX_FIFO (slave address for data)
  4. Write 0x__ to the TX_FIFO (byte 1)
  5. Write 0x__ to the TX_FIFO (byte 2)
  6. Write 0x__ to the TX_FIFO (stop bit, byte x)

 

Read Bytes from an IIC Slave Device Addressed as 0x_ _

The data is at slave address 0x _ _. 

First, a write access is necessary to set the slave device address, then a repeated start follows with the read accesses:

  1. Check that all FIFOs are empty and that the bus is not busy by reading the Status register.
  2. Write 0x_ _ _ to the TX_FIFO (set start bit, device address to 0x__, write access).
  3. Write 0x__ to the TX_FIFO (slave address for data).
  4. Write 0x___ to the TX_FIFO (set start bit for repeated start, device address 0x_ _, read access).
  5. Write 0x___ to the TX_FIFO (set stop bit, four bytes to be received by the AXI IIC).
  6. Wait until the RX_FIFO is not empty.

a) Read the RX_FIFO byte.

b) If the last byte is read, exit; otherwise, continue checking while RX_FIFO is not empty.

AXI IIC Simulation

A modified simulation test bench in a Vivado 2018.1 project is attached.

Please use the provided test bench with the AXI IIC IP. It has been tested and works in the Vivado environment.

Below are some recommended example programming sequences as per the AXI IIC product guide (PG090).

 

 

The example cases are explained below:

Test 1 - Recommended sequence

Place the data at slave device address 0x6C with one data byte.

  1. Check that all FIFOs are empty and that the bus is not busy by reading the SR.
  2. Write 0x1D8 to the TX_FIFO (set the start bit, the device address, write access).
  3. Write 0x212 to the TX_FIFO (stop bit, last byte)

AXI IIC-Test1_simulation.jpg

 

Test 2 - Recommended Sequence

Place the data at the slave device address 0x6C with two data bytes.

  1. Check that all FIFOs are empty and that the bus is not busy by reading the SR.
  2. Write 0x1D8 to the TX_FIFO (set the start bit, the device address, write access).
  3. Write 0x011 to the TX_FIFO (byte 1).
  4. Write 0x012 to the TX_FIFO (byte 2).
  5. Write 0x2EF to the TX_FIFO (stop bit, last byte)

AXI IIC-Test2_simulation.jpg

 

Test 3 - Recommended Sequence

Place the data at slave device address 0x6C with two data bytes. Restart with the wrong slave device address.

  1. Check that all FIFOs are empty and that the bus is not busy by reading the SR.
  2. Write 0x1D8 to the TX_FIFO (set the start bit, the device address, write access).
  3. Write 0x011 to the TX_FIFO (byte 1).
  4. Write 0x012 to the TX_FIFO (byte 2).
  5. Write 0x2EF to the TX_FIFO (stop bit, last byte)
  6. Reset the TX FIFO
  7. Write the wrong address 0x108 to the TX_FIFO (set the start bit, the device address, write access).

AXI IIC-Test3_simulation.jpg

 

Test 4  - Not Recommended

Place the data at the slave device address 0x6C with one data byte with START and STOP bits:

  1. Check that all FIFOs are empty and that the bus is not busy by reading the SR.
  2. Write 0x3D8 to the TX_FIFO (set the start bit, stop bit, the device address, write access).

 

Because this byte has a stop bit, it be will considered the last byte.

A TX FIFO empty interrupt transfer will not be generated for it, and therefore it will assert a bus not busy interrupt.

As per the IIC protocol we do not recommend having a byte with both a start and stop bit together in it.

 

Please see the example below of this behavior:AXI IIC-Test4_simulation.jpg

We would recommend following test cases 1, 2, and 3 but not 4.

This will also help you to follow the programming sequence.

Notes:

1) Refer to ISR interrupt(4) instead of interrupt(2) to detect the end of the last byte. Interrupts before the last byte can be monitored on interrupt(2) as usual.

2) Per the IIC protocol, do not have the start and stop bits together with data/address bytes.