Overview
This application note describes how to implement I2C using National Instruments LabVIEW FPGA Module and off-the-shelf NI reconfigurable I/O (RIO) hardware. The LabVIEW FPGA Module is a graphical development environment for easily configuring FPGAs on RIO hardware to implement functionality that usually requires custom hardware. One such function is implementing digital communication protocols. Unlike developing custom hardware using FPGAs or ASICs, the LabVIEW FPGA Module allows you to develop, test, and debug new functionality quickly without the need for specialized or low-level development tools. I2C is just one example of a digital communication protocol that can be programmed in LabVIEW FPGA Module. Other examples of such protocols include S/PDIF, I2S, and SPI.
Table of Contents
I2C Protocol
The I2C (Inter-IC) bus protocol was developed by Phillips Electronics in 1982 to allow communication between integrated circuits (ICs) from different manufacturers. Applications that use the I2C bus include microcontrollers, LCD, memory, keyboards, PCs, cell phones, car radios, TVs, and blade servers.
The I2C bus uses two bidirectional signals, one as the serial clock (SCL) line and one as the serial data (SDA) line. Each device connected to the bus has a unique address used to identify the device in communication. The protocol is comprised of a set of conditions to establish or terminate communication, a designation to read or write, and the ability to address devices with an expanded address scheme. A simple master/slave relationship is present on the bus continuously, and any device on the line can act as the master or slave.
I2C has a data transfer rate of 400 kbits/s at a maximum length of 2 meters. It is possible to get a transfer rate of 3.4 Mbits/s at 0.5 meters on the high speed I2C bus, and by using signal buffers, one can go up to 100 meters on the I2C bus.
For more detailed information regarding the I2C bus protocol, see the Phillips website at:
http://www.semiconductors.philips.com/markets/mms/protocols/I2C/index.html
Communication Protocol Implementation
Within a pair of start and stop conditions, I2C uses two simple structures to write data to a device, one structure to write data and one structure to acknowledge receipt of the data. The I2C protocol is easily implemented by repeating these structures within the start and stop boundary conditions.
To start and stop communication a unique set of conditions are implemented between the data and clock lines. Figure 1 shows the relationship between the SDA and SCL at the start and stop of communication. An I2C protocol start occurs while the SCL is high and the SDA transitions from high to low. In order to stop communication, the SDA has a rising edge while the SCL is high.

Figure 1: Start and Stop Conditions for I2C protocol
Once the start condition is sent, all devices on the bus “listen” for their address from the master. Bidirectional data transfer in I2C begins with the master sending 8-bits on the SDA, 7-bits to address a device and 1-bit to designate whether the communication will be to read data from the slave or to write data to the slave. If the address is valid and the device receives its address, the device sends a 1-bit acknowledgement on the SDA to the master. Figure 2 depicts the 7-bit address, 1-bit read/write bit and acknowledgement. Note that the I2C protocol reads MSB (Most Significant Bit) first.
All future communication operations on the I2C continue in the same pattern as the address and acknowledge, 8-bits and one acknowledge, until the stop condition is sent. Therefore figure 2 also represents the transfer of one byte from the master to the slave.
I2C in LabVIEW FPGA
To implement the I2C protocol in the LabVIEW FPGA Module, we will use three LabVIEW FPGA-specific functions to control the digital input/output lines of the RIO (reconfigurable I/O) hardware. Those functions are:
· Digital Input
· Digital Enable

These same functions can program any NI RIO device with digital I/O to communicate with a different communication protocol or for a different operation.
We begin the protocol by generating the start condition, holding the clock line high while generating a high to low transition on the data line. After the start condition all of the devices on the line will monitor the bus for their address, which will follow either a 7-bit or 10-bit address scheme. After each bit (address, read/write, or data) is sent across the data line, the clock line cycles once and waits for an acknowledgement from the listener.
I2C Write in LabVIEW FPGA
To implement the protocol, we begin at the most basic transaction, writing one data bit to a device. The Digital Output function in the LabVIEW FPGA Module enables a digital line for output and sets the line to the specified state (high or low). Using the Digital Output function we write one data bit on the data line. One clock cycle on the SCL follows the output bit. Figure 3 shows one bit transferred on the SDA.

Figure 3: One bit transfer with single clock cycle.
The Wait functions in the block diagram with the SCL Digital Output will determine how long the SCL line is held high and low. The minimum bus timing is different depending upon whether the SCL is rising or falling. Bus timing can operate in standard, fast, or high speed mode. In the example program, the user can specify if the VI should run in standard mode, fast mode, or high-speed mode bus timing. In figure 3 and subsequent figures, depending on mode the user specifies, the bus timing will be either standard or fast.
Referring to the timing diagram in figure 2, we see that in the I2C protocol an acknowledge bit from the receiving device follows each byte. In figure 4 we use 1 bit transfer.vi in a FOR Loop to send a byte to the SDA. In the “Addressing I2C Devices in LabVIEW FPGA” section we will reuse this VI as well.

Figure 4: One byte transfer with single clock cycle.
I2C Acknowledgement in LabVIEW FPGA
After every byte is transferred on the SDA, an acknowledgement from the addressed device must occur. During the acknowledge bit, the data line is pulled low by the device during the high period of the clock pulse. Refer to the timing diagram in figure 2 to see the timing for the device acknowledge. ACK designates the location of an acknowledgement. An acknowledge bit occurs after the device address is sent and after every data byte until the stop condition.
In figure 5 the device acknowledges receipt of the data. In the first sequence frame, the Digital Enable function in LabVIEW FPGA sets the direction of the digital line to be ”input” so that the master can receive the acknowledgement from the device. Then the SCL cycles once before the Digital Enable function is used again to enable the data line for output. The data line direction is changed from “input” to “output” so that the SDA may transfer data to the device again.
In I2C the device can hold the SDA low as long as needed within a protocol-set timeline to acknowledge receipt of the data. Protocol times for set-up and hold can be obtained from Phillips Semiconductors. Two situations will cause data transfer to cease. If in the acknowledgement the device holds the SDA low beyond the protocol hold time, the master will abort the transfer. If the SDA is not pulled low by the device for the acknowledge bit, the data transfer will stop.
Combining the master to receive data transfer with the device acknowledgement, we have a block diagram similar to the one in figure 6. The WHILE Loop runs while there is data to write to the device and the acknowledgement on the SDA is not held low longer than a clock cycle of the bus. Using the Digital Input function in LabVIEW FPGA, we read the status of the digital line to determine if it is low or high from the acknowledge.
The I2C protocol is not limited to writing data to a device. A device may send data to the master. In such a case, the master acts as a master-receiver. The default direction for data is output from the master to the device. As in the 1 bit acknowledge.vi, we need to use the Digital Enable function in LabVIEW FPGA to disable the digital line from “output” to “input” to allow data flow from the device to the master. With the digital line set to input, the Digital Input function sends data to the master. Then the SCL cycles once. Unlike in 1 bit acknowledge.vi, the SDA is not set high after the clock cycle, since we want to read a byte of data from a device. Figure 7 depicts the 1-bit flow for a master-receiver to read data from a device.
Using a FOR Loop one byte is read by the master-receiver. Because the I2C protocol reads the MSB first, we use a Reverse 1D Array function in figure 8 to reverse the data array.

Figure 8: The one byte read uses a FOR Loop and a Reverse 1D Array function.
The complete read function is shown in figure 9 and is similar to the write function shown in figure 6.
In I2C it is possible to address a device in two different ways, with a 7-bit address and a 10-bit address. In the 7-bit address scheme the eighth bit designates whether the master will read from or write data to the device. Figure 10 includes the reversal of the 7-bit device address from LSB (Least Significant Bit) to MSB because in I2C protocol the address is written MSB first. The read/write bit is added to the address into the array as the LSB, which is written last. Note that the same 1 bit transfer.vi shown in the “I2C Write in LabVIEW FPGA” section is used again for the address.

Figure 10: 7-bit addressing scheme.
Phillips created a 10-bit address scheme as the number of available 7-bit addresses became too limited. Using a 10-bit address scheme allows for more address possibilities. The first five bits of the 10-bit address scheme follow the pattern 11110, which signifies that a 10-bit address will be used. The 10-bit address is split into two 8-bit packets. After the first five default bits, 11110, two bits of the 10-bit address and the read/write bit complete the first byte. More than one device may acknowledge the first byte packet. All devices that match the first packet will monitor the bus for the remaining eight bits of the 10-bit address. Figure 11 shows the block diagram for a 10-bit address. It should be noted, again, that throughout the VIs used in the I2C protocol, we are able to reuse 1 bit transfer.vi, regardless if we are transferring data to a device or sending out the address.
The block diagram for the complete I2C communication is shown in figure 12. In the first three frames of the sequence structure the I2C communication is initialized and started. In the fourth sequence frame the master addresses the device with either a 7-bit or 10-bit address, followed by the acknowledgement from the device. In the sixth sequence frame the master either writes data to or reads data from the device. The last two frames end the I2C communication with a device by bringing the SCL and SDA high.

[+] Enlarge Image
In this application note we showed how the I2C communication protocol is easily implemented in LabVIEW FPGA Module by reusing code and accessing only three digital functions on a RIO device. While this functionality is traditionally implemented using low-level development tools, LabVIEW FPGA and NI RIO hardware provide a solution to allow you to rapidly and intuitively implement I2C and other digital protocols.
Reader Comments | Submit a comment »
Even more mistakes...
In the "START" sequence (Fig.12), the SDA is
set to TRUE. It should be set to FALSE, as
described in Fig.1
This example doesn't work, even with the
"START" fixed.
- Sep 5, 2007
wrong diagram panel
I think that in figure 10: 7-bit addressing
a mistake is made.
In the example is from the address the 7
msb bits used instead of the 7 lsb bits.
when writting to address 0x51
(b"1010001) the byte sent should be
b"10100010" = 0xA2 instead of
b"01010000" = 0x50
- Miranda Buhler - van Rie, ASML. miranda.van.rie@asml.com - May 8, 2007
Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).






