I2C Protocol

Master the I2C (Inter-Integrated Circuit) protocol and its addressing and acknowledgment mechanisms

What is I2C?

The I2C (Inter-Integrated Circuit) protocol was developed by Philips Semiconductors (now NXP) in 1982. It enables communication between multiple devices using only two wires.

Key characteristics:

  • 2 wires: SDA (data) and SCL (clock)
  • Open-drain: lines require external pull-up resistors
  • Multi-master: hardware arbitration between multiple masters
  • Addressing: each slave has a unique address (7 or 10 bits)
  • ACK/NACK: acknowledgment after each byte

I2C Signals

SignalTypeDescription
SDABidirectional open-drainSerial Data
SCLBidirectional open-drainSerial Clock

Both lines are pulled high by pull-up resistors. Any device on the bus can pull a line low (open-drain), but none can force it high — only the pull-up resistors do that.


Start and Stop Conditions

I2C uses two special conditions that violate normal data transitions (data stable while SCL high):

I2C timing diagram

START condition: SDA falls while SCL is high. STOP condition: SDA rises while SCL is high.

SDA data must only change while SCL is low — except for START and STOP conditions.


I2C Frame

A typical I2C write transaction:

START | Address (7 bits) | R/W='0' | ACK | Data byte | ACK | STOP
  1. START: initiated by the master
  2. Address: 7 bits MSB first, identifies the target slave
  3. R/W bit: 0 = write (master → slave), 1 = read (slave → master)
  4. ACK: slave pulls SDA low to acknowledge
  5. Data: bytes transmitted, each followed by ACK/NACK
  6. STOP: initiated by master to release the bus

ACK and NACK

After each 8-bit byte, the receiver sends:

  • ACK (Acknowledge): SDA low during the 9th clock pulse — successful reception
  • NACK (Not Acknowledge): SDA high (released) — error or end of read

In read mode, the master sends NACK after the last byte to signal it wants no more data.


VHDL Implementation — I2C Master State Machine

library ieee;
use ieee.std_logic_1164.all;
 
entity i2c_master is
  generic (
    g_SYS_CLK_HZ : positive := 100_000_000;  -- 100 MHz
    g_I2C_CLK_HZ : positive := 400_000       -- 400 kHz (Fast mode)
  );
  port (
    i_clk     : in    std_logic;
    i_rst     : in    std_logic;
    i_start   : in    std_logic;
    i_rw      : in    std_logic;  -- '0'=write, '1'=read
    i_addr    : in    std_logic_vector(6 downto 0);
    i_data    : in    std_logic_vector(7 downto 0);
    o_data    : out   std_logic_vector(7 downto 0);
    o_busy    : out   std_logic;
    o_ack_err : out   std_logic;
    io_sda    : inout std_logic;
    io_scl    : inout std_logic
  );
end entity i2c_master;

A typical state machine includes states:

  • IDLESTARTADDRACK_ADDRDATAACK_DATASTOP

The full implementation is available in the corresponding exercise.


Clock Stretching

A slave can "stretch" SCL by holding it low to slow down the master. The master must monitor SCL and wait for it to rise before continuing.

This feature requires SCL to be open-drain (bidirectional) on the master side as well.


Multi-Master Arbitration

If two masters start a transaction simultaneously, arbitration is resolved automatically:

  • Each master compares what it drives on SDA with what it reads back
  • If a master drives '1' but reads '0', it lost arbitration and stops
  • The "winning" master continues uninterrupted

Standardized Speeds

ModeMax Speed
Standard Mode100 kbps
Fast Mode400 kbps
Fast Mode Plus1 Mbps
High Speed Mode3.4 Mbps

Advantages and Disadvantages

AdvantagesDisadvantages
Only 2 wiresSlower than SPI
Native multi-masterOpen-drain requires pull-up resistors
Addressing — no SS_NMore complex protocol
ACK/NACK for verificationBus capacitance limit (400 pF)