I2C Interfacing To XC3S400 FPGA
I2C Interfacing To XC3S400 FPGA
I2C Interfacing To XC3S400 FPGA
XC2Sxx D-Board
Challenge’s / Solution
With a parallel architecture each peripheral component will have address lines,
data lines, a clock line and various other control signals. Address or data values
sent over the bus are transferred at the same time over all the parallel lines. This
makes it relatively easy to generate chip selects and trigger on the event of
interest using logic analyzers.
With serial bus architecture all this information must be sent serially on the same
few signal lines. This means that a single signal may include address, control,
data, and clock information.
This guide takes you through various steps in learning I2C features and how to
interface and debug these peripherals using capabilities of ADM’s new LGLite
Integrated Logic Analyzer/Pattern Generator. TKBase is equipped and fully
loaded with I2C based peripherals like ADC, DAC, EEPROM, RAM and RTC.
Format Description
Start Master is taking control and message will follow.
Address 8 or 10 bit number representing address of the device to
be read or written. The LSB bit defines the direction of
data flow (R/W bit)
R/W bit A one indicates that data will be read from else written to
the device.
ACK A bit from the slave device acknowledging the masters
action.
Data Data or message to be sent / received .
Stop Indicates the message is complete and master has
released the bus
BIT transfer
One data bit is transferred during each clock pulse. The data on the SDA line
must remain stable during the HIGH period of the SCL clock pulse as changes in
the data line at this time will be interpreted as a control signal.
Start and stop conditions
Both data and clock lines remain HIGH when the bus is not busy. A HIGH-to-
LOW transition of the data line, while the clock is HIGH, is defined as the start
condition (S). A LOW-to-HIGH transition of the data line while the clock is HIGH,
is defined as the stop condition (P).
Acknowledge
A slave receiver which is addressed must generate an acknowledge after the
reception of each byte. Also a master must generate an acknowledge after the
reception of each byte that has been clocked out of the slave transmitter. The
device that acknowledges has to pull down the SDA line during the acknowledge
clock pulse, so that the SDA line is stable LOW during the HIGH period of the
acknowledge related clock pulse. A master receiver must signal an end of data to
the transmitter by not generating an acknowledge on the last byte that has been
clocked out of the slave. In this event the transmitter must leave the data line
HIGH to enable the master to generate a stop condition.
PCF8591 – I2C ADC/DAC
GENERAL DESCRIPTION
Functional Description
Addressing
Each PCF8591 device in an I2C-bus system is activated by sending a valid address to the
device. The address consists of a fixed part and a programmable part. The programmable
part must be set according to the address pins A0, A1 and A2. The address always has to
be sent as the first byte after the start condition in the I2C-bus protocol. The last bit of the
address byte is the read/write-bit which sets the direction of the following data transfer.
Control byte
The second byte sent to a PCF8591 device will be stored in its control register and is
required to control the device function. The upper nibble of the control register is used for
enabling the analog output, and for programming the analog inputs as single-ended or
differential inputs. The lower nibble selects one of the analog input channels defined by
the upper nibble (see Fig.4). If the auto-increment flag is set the channel number is
incremented automatically after each A/D conversion.
D/A conversion
The third byte sent to a PCF8591 device is stored in the DAC data register and is
converted to the corresponding analog voltage using the on-chip D/A converter.
A/D conversion
The A/D converter makes use of the successive approximation conversion technique. The
on-chip D/A converter and a high-gain comparator are used temporarily during an A/D
conversion cycle. An A/D conversion cycle is always started after sending a valid read
mode address to a PCF8591 device.
We now understand what is I2C standard, and also know a little about
PCF8591 I2C device. The problem we face now is to use a standard Xilinx
Part like XC2S50 and interface the I2C device 8591, and demonstrate both
ADC and DAC working. To do this we need the following:
We start the vhdl design by defining the I2C master entity on the TKBASE evaluation
board as shown below.
entity I2C_ADC is
Port ( Header1 : out std_logic_vector(7 downto 0);
Header2 : out std_logic_vector(7 downto 0);
Header3 : out std_logic_vector(7 downto 0);
Header4 : out std_logic_vector(7 downto 0);
Header5 : out std_logic_vector(7 downto 0);
Header6 : out std_logic_vector(7 downto 0);
Header7 : out std_logic_vector(7 downto 0);
pfc_adc : inout std_logic;
clk100k : in std_logic);
end I2C_ADC;
The pin clk100k is the system clock and all other I2C bus clocking would be derived
using this clock. The pfc_adc is the SDA port on the I2C bus. The SCL is a derived clock
from the clk100k and is just an output on Header4. The VHDL code explaing the above
is given below.
P1:process (clk100k)
begin
if( rising_edge(clk100k)) then
clkdiv <= clkdiv + 1;
i2c_clk1 <= clkdiv(3); -- the base clock
i2c_clk2 <= clkdiv(4); -- base SCL clock
statedsp <= clkdiv(9 downto 8); -- 7seg mux
clkkey <= clkdiv(10); -- i2c r/w loop
end if;
end process P1;
The signal clkkey is used to generate I2C timing loops. We start the I2C cycle when
clkkey goes high. A state counter with 255 states is designed using i2c_clk1;
P4:process(i2c_clk2)
begin
if( falling_edge(i2c_clk2) ) then
Once the state counter is designed we now have to start coding for I2C-ADC protocol.
We should know the device address, and signals to generate and its timing.
I2C Start
We define the first state 00 as the initialization state, wherein we load all required I2C
device information register like device address and device control. The next state 01 is
used to generate the I2C Start condition. First, a start condition issued which is a high
to low-transition on SDA while SCL is high — and has to appear on the bus . To
isolate the bus and to trigger on this event, we generate a hardware bit i2c_start. The bit
i2c_start will be used by Logic Analyzer to trigger and view the I2C start condition.
P7:process(i2c_clk1)
begin
case i2c_count is
The states from 02 thru 09 defines generation of device address. The next 8 bits are
clocked into the PCF8591. The first seven bits (7 to 1) are the 7-bit slave address defined
by the manufacturer of the device, in our case 0x97. Because bit 0 dictates whether it is a
read or write command, we first have to write the control word,"1," for ADC read cycle.
To acknowledge this data, PCF8591 has to pull the SDA line low. Hence during the
address write cycle, the direction of SDA is output and during the acknowledge cycle the
direction is input. This direction can be viewed using the i2c_dir hardware bit. Note the
9th bit identifies the acknowledge cycle.
The first state is generation of Start , the next 8 are for transmitting device address and
the next 10th state is the acknowledge cycle, wherein the device informs the master that it
has received the information correctly by pulling SDA line low. Hence during this cycle
we have to make the SDA as input and monitor this input using the hardware bit
.i2c_ackreg going high.
An A/D conversion cycle is always started after sending a valid read mode address to a
PCF8591 device. This is what we did in previous states. Hence the next 8 states would be
the PCF8591 sending ADC data. We now have to shift in this serial data by creating a
shift clock named as i2c_adc_clk. This shift clock would latch the serial data and we can
then display this information(i2c_rdata) on a simple multiplexed 7 segment display. To
trigger the logic analyzer we create a hardware bit i2c_dreg.
The complete cycle for reading the ADC data and displaying them onto the 7 segment
display (20 bytes to transfer) takes about 7 milli-seconds and hence best seen using a real
time Logic analyzer like LG320/LGLite. These VHDL hardware triggers bits allow you
to isolate the particular bus traffic you’re interested in, and enables you to instantly see
the content of every message transmitted over the bus in your acquisition.
While there are many benefits in transitioning from parallel to serial buses in embedded
systems design, there are also a number of challenges the design engineer faces. With
traditional test and measurement tools like scope’s, it’s much more difficult to trigger on
the event you’re looking for, it can be nearly impossible to tell what information is
present by just looking at the analog signal and it’s an extremely time consuming and
error prone process to have to manually decode a long period of bus activity to diagnose
problems. The LG320/LGLite changes everything. With its powerful trigger, clocking,
and search capabilities today’s design engineers can solve embedded system design
issues with exceptional efficiency.