Off-Chip Protocol

I2C – Inter-Integrated Circuit

I2C is a two-wire serial bus invented by Philips (now NXP) that lets multiple masters and multiple slaves share a single pair of lines. Its open-drain bus structure, built-in addressing, and ACK/NACK handshake make it the go-to interface for sensors, EEPROMs, RTCs, and display drivers — anywhere you need a low-pin-count, multi-device bus.

Wires — 2 (SDA + SCL)
Type — Synchronous, half-duplex
Topology — Multi-master, multi-slave
Speed — 100 kHz / 400 kHz / 1 MHz / 3.4 MHz
Addressing — 7-bit (128 devices) or 10-bit

Overview

I2C (Inter-Integrated Circuit, often pronounced "I-squared-C") was designed in 1982 for connecting slow peripheral ICs to a processor using the fewest possible wires. The defining constraint — only two wires for any number of devices — shapes every design decision in the protocol.

Because all devices share the same two lines, I2C solves the "who talks when" problem through a built-in addressing scheme: every transaction begins with the master broadcasting a 7-bit (or 10-bit) slave address, and only the matching slave responds. The bus is half-duplex — the master and slave take turns driving SDA, they never transmit simultaneously. Unlike SPI, there is no separate chip-select wire; addressing replaces it.

Two-wire simplicity has a cost: I2C is slower than SPI (max 3.4 MHz vs tens of MHz for SPI), and the protocol overhead (START, address, ACK, STOP) adds latency to every transaction. For bulk data transfers, SPI wins. For configuration registers and sensor reads across many devices, I2C wins.

Signals & Open-Drain Bus

SignalFull NameDirectionDescription
SDASerial DataBidirectionalCarries all data: addresses, data bytes, and ACK bits. The current bus owner drives SDA; receivers listen.
SCLSerial ClockMaster → Slave (normally)Clock generated by the master. Slaves can hold SCL low to pause the master (clock stretching). Normally driven by master only.

Open-drain and pull-up resistors

Both SDA and SCL are open-drain (or open-collector) lines. This means devices can only pull the line LOW — they cannot actively drive it HIGH. Instead, a pull-up resistor (typically 4.7 kΩ for 100 kHz, 2.2 kΩ for 400 kHz) connects each line to VCC, passively pulling it HIGH when no device is pulling it LOW.

This is crucial for two reasons:

VCC VCC 4.7kΩ 4.7kΩ SDA SCL Master Slave 1 Slave 2 Slave 3 0x48 0x50 0x68 All devices share one SDA + one SCL. Pull-ups restore HIGH when no device pulls LOW.

Pull-up resistor sizing matters: Too large (e.g. 10 kΩ) → slow rise times, corrupted bits at higher speeds. Too small (e.g. 1 kΩ) → excessive current draw and marginal drive strength. Always calculate R based on bus capacitance and target speed. The I2C spec defines maximum rise times that back-calculate the minimum pull-up value.

START and STOP Conditions

I2C has no separate chip-select wire. Instead, it uses special patterns on SDA that can only occur while SCL is HIGH — something that never happens during normal data transfer. These are the START and STOP conditions.

ConditionSymbolWhat happensEffect
STARTSSDA falls LOW while SCL is HIGHMarks the beginning of every transaction. All slaves watch for this.
STOPPSDA rises HIGH while SCL is HIGHReleases the bus. Slaves reset their state machines.
Repeated STARTSrAnother START without a preceding STOPChanges direction (write → read) or addresses a different slave without releasing the bus.

During normal data transfer, SDA is only allowed to change while SCL is LOW. This rule makes START and STOP instantly recognisable — they are the only events where SDA changes while SCL is HIGH.

IDLE START Data phase (SCL pulses, SDA changes only during SCL LOW) STOP IDLE SCL SDA SDA↓ while SCL HIGH SDA↑ while SCL HIGH SDA may change only here ↕ D1=1 D2=0 D3=0

SDA (teal) changes only when SCL (indigo) is LOW — except at START where SDA falls while SCL is HIGH, and at STOP where SDA rises while SCL is HIGH.

Data Frame & Bit Transfer

Every byte transferred on I2C (whether it is an address byte or a data byte) uses the same 9-bit frame: 8 data bits followed by 1 acknowledgement bit.

SCL SDA 9th bit D7 D6 D5 ··· D0 ACK ← Master (or slave) drives SDA → Receiver MSB first

The key rule: SDA must be stable (not changing) for the entire duration of each SCL HIGH pulse. The receiver samples SDA at each rising edge of SCL. Transitions on SDA are only allowed while SCL is LOW.

Every byte gets an ACK. After 8 data bits, the transmitter always releases SDA and generates the 9th clock pulse. The receiver pulls SDA LOW to confirm receipt. If the receiver fails to acknowledge (NACK), the master must either repeat the byte, send a STOP, or take corrective action — the protocol does not retry automatically.

Addressing

The first byte after every START is always the address byte. It identifies which slave should respond to this transaction.

7-bit addressing (most common)

The address byte contains a 7-bit slave address followed by a 1-bit R/W flag:

ADDR [6:0]7 bits — slave address
R/W̄1 = Read, 0 = Write
ACKslave pulls LOW

With 7-bit addressing, the bus can address up to 128 devices — though a handful of addresses are reserved. The most used reserved addresses are:

AddressReserved for
0x00General Call — all slaves respond (write only)
0x01CBUS compatibility
0x02–0x03Reserved for future use
0x04–0x07Reserved
0x78–0x7F10-bit address extension prefix

10-bit addressing

For large systems needing more than 112 usable addresses, I2C supports 10-bit addressing using a two-byte sequence:

11110XXMSB 2 bits + 10-bit prefix
R/W̄0 for write
ACKslave
ADDR [7:0]lower 8 address bits
ACKslave

The prefix 11110 in the first byte signals to all slaves that this is a 10-bit address. A 10-bit read transaction adds a Repeated START after the address phase.

ACK and NACK

After every 8-bit byte, the transmitter releases SDA (stops driving it). The receiver then drives the 9th bit:

9th bitNameSDA stateDriven byMeaning
ACKAcknowledgeLOWReceiver pulls SDA down"Byte received successfully, continue."
NACKNot AcknowledgeHIGHReceiver releases SDA (pull-up holds it high)"Stop sending" or "I'm busy" or "address not recognised."
ACK (SDA pulled LOW) NACK (SDA stays HIGH) Bit 8 ACK slave pulls 8th bit 9th (ACK) Bit 8 NACK 8th bit 9th (NACK) no pull → high SCL SCL

When does the master send NACK? During a read transaction, the master sends NACK after the last byte it wants to receive. This signals "I have enough data, stop." If the master sends ACK, the slave knows to prepare and send the next byte. If the master sends NACK, the slave releases the bus and the master follows with a STOP.

Write Transaction

A write transaction sends data from master to slave. The master drives SDA for both the address byte and every data byte. The slave only drives SDA during the ACK bits.

START / STOP
Master drives SDA
Slave drives SDA
SSTART
ADDR [6:0]slave address
0 = Write
ACKslave
DATA [7:0]first byte
ACKslave
DATA [7:0]next byte (optional)
ACKslave
PSTOP

Step-by-step:

  1. START — Master pulls SDA LOW while SCL is HIGH. All slaves detect this and begin listening.
  2. Address + W bit — Master sends 7-bit address with R/W = 0 (write). All slaves compare the address to their own.
  3. Slave ACK — The matching slave pulls SDA LOW during the 9th clock pulse. Unmatched slaves ignore the rest of the transaction.
  4. Data byte(s) — Master sends one or more data bytes, MSB first. After each byte, the slave ACKs.
  5. STOP — Master raises SDA while SCL is HIGH, releasing the bus.

A practical example: writing the value 0x72 to register 0x01 of a sensor at address 0x48 — the master sends three bytes: 0x90 (0x48 shifted left + W=0), 0x01 (register address), 0x72 (value). Each byte is followed by a slave ACK.

Read Transaction

A read transaction receives data from slave to master. After the address byte (with R/W = 1), the slave takes control of SDA and drives all subsequent data bytes. The master only drives SDA for the ACK/NACK bits.

SSTART
ADDR [6:0]slave address
R1 = Read
ACKslave
DATA [7:0]slave sends
ACKmaster
DATA [7:0]slave sends
NACKmaster (last)
PSTOP

Step-by-step:

  1. START — Master initiates the transaction.
  2. Address + R bit — Master sends 7-bit address with R/W = 1 (read).
  3. Slave ACK — Matching slave acknowledges. It then takes control of SDA to send data.
  4. Data bytes — Slave drives SDA with each byte. Master ACKs each byte it successfully receives.
  5. Master NACK on last byte — When the master has received all the bytes it needs, it sends NACK instead of ACK. This tells the slave to stop.
  6. STOP — Master releases the bus.

Direction switch on SDA: After the slave ACKs the address byte (slave drives SDA LOW), the slave must continue holding SDA and begin driving the first data byte. The master releases SDA at exactly this point. Timing this switch is critical — both devices must not drive SDA simultaneously.

Combined Transaction (Repeated START)

Many real devices require you to write a register address, then immediately read from it — without releasing the bus in between. Releasing the bus (STOP) would allow another master to steal it, and some devices reset their internal pointer on STOP.

The solution is the Repeated START (Sr): instead of sending STOP after the write phase, the master sends a new START condition directly. This changes direction (write → read) while keeping the bus locked.

SSTART
ADDR [6:0]slave addr
Write
ACKslave
REG [7:0]register ptr
ACKslave
SrRep. START
ADDR [6:0]same addr
RRead
ACKslave
DATAslave sends
NACKmaster
PSTOP

This combined pattern is extremely common. Reading a temperature from a sensor (e.g., LM75, BME280), fetching a byte from an EEPROM, or reading a gyroscope register — all use this write-address then read-data sequence with a Repeated START.

The bus stays locked from the initial START to the final STOP. Other masters on the bus must wait. If you do not need to hold the bus between the write and read, it is equally valid (and simpler) to use STOP followed by a new START.

Clock Stretching

A slow slave can pause the master using clock stretching: after a SCL falling edge, the slave holds SCL LOW (using its open-drain output) before releasing it. The master, which monitors SCL, sees that SCL has not risen as expected and waits.

SCL Slave holds SCL LOW (stretching) Master waits, SCL does not rise Slave releases, normal resumes Normal

Clock stretching is used when a slave needs extra time — for example, an ADC completing a conversion, or an EEPROM performing an internal write. The master cannot force the clock; it must wait. This is another feature that requires the SCL line to be open-drain: the slave needs to actively hold the line LOW, and the master must be able to detect this (rather than both driving the line to different levels).

Not all masters support clock stretching. Some low-cost microcontroller I2C peripherals use a strict timing model and will generate an error if SCL is not released within the expected window. Always check whether your master controller handles clock stretching before using a slave that uses it.

Speed Modes

ModeMax ClockTypical Pull-upNotes
Standard Mode (Sm)100 kHz4.7 kΩOriginal spec. Compatible with all I2C devices. Long traces, high capacitance tolerance.
Fast Mode (Fm)400 kHz2.2 kΩMost common in modern designs. Smaller pull-ups needed for rise time. Backward compatible.
Fast-Mode Plus (Fm+)1 MHz1 kΩ or active pull-upRequires stronger drivers. Devices must declare Fm+ support. Increasing adoption.
High-Speed Mode (Hs)3.4 MHzActive current sourceRequires current-source pull-ups and special Master Code handshake. Rarely used.
Ultra Fast-Mode (UFm)5 MHzPush-pull (no pull-up)Unidirectional only — no ACK, no clock stretching. Very uncommon.

All modes below Hs are backward compatible — a 400 kHz master can communicate with 100 kHz slaves at 100 kHz. High-Speed mode requires a special startup sequence and is mainly found in memory devices.

I2C vs SPI

FeatureI2CSPI
Wires2 (SDA + SCL)4 + 1 CS per slave
DuplexHalf-duplex (shared SDA)Full-duplex (separate MOSI + MISO)
Max speed3.4 MHz (Hs)Tens of MHz (device-limited)
Slave selectAddress in-band (no extra pin)Dedicated CS_N pin per slave
Multi-slaveYes — up to 112 (7-bit) on same 2 wiresYes — one CS pin per slave
Multi-masterYes — with arbitrationNo — single master only
ACK / error detectBuilt-in per byteNone — application layer
Protocol overheadSTART, address, ACK, STOP per transactionOnly CS assertion / deassertion
Best forMany low-speed peripherals, sensors, EEPROMsHigh-speed single slave — flash, ADC, display

Interview Q&A

Why does I2C use open-drain outputs instead of push-pull?
Open-drain enables the bus to be safely shared by multiple devices. If two devices simultaneously drive the line — one to HIGH and one to LOW — a push-pull design would create a direct short between VCC and GND, damaging output drivers. With open-drain, any device can only pull the line LOW. If multiple devices pull simultaneously, the line stays LOW without damage. The pull-up resistor returns the line HIGH when everyone releases. This also gives the "wired-AND" property needed for clock stretching and multi-master arbitration.
What is the difference between START and a regular data bit transition?
During normal data transfer, SDA is only allowed to change while SCL is LOW. A START condition is specifically defined as SDA going LOW while SCL is HIGH — a pattern that can never occur during normal data transfer. This is why slaves can unambiguously detect a START at any point, even mid-bus, without any additional framing. Similarly, STOP is SDA going HIGH while SCL is HIGH. These two illegal-during-data-transfer transitions serve as reliable bus control signals.
When does the master send a NACK instead of an ACK during a read?
The master sends NACK (leaves SDA HIGH) after the last byte it wants to receive. This is how it tells the slave "I have received everything I need, please stop driving SDA." If the master ACKed the last byte, the slave would immediately start sending the next byte — the master has no other way to stop it. After the NACK, the master generates STOP to release the bus. The NACK is not an error; it is a required part of every read transaction termination.
What is clock stretching and which side initiates it?
Clock stretching is initiated by the slave. After the master drives SCL LOW, the slave can hold SCL LOW (using its open-drain output) before releasing it. The master monitors SCL and waits for it to actually go HIGH before treating the clock edge as complete. This gives slow slaves time to process data — for example, completing an ADC conversion, retrieving a byte from internal EEPROM, or preparing a response. The master cannot proceed until the slave releases SCL. Not all I2C master controllers support this feature.
What happens if two masters simultaneously try to use the I2C bus?
I2C has a built-in arbitration mechanism. Each master monitors SDA while it drives it. If a master drives SDA HIGH but reads it back as LOW (because another master is driving it LOW), it knows it has lost arbitration — it immediately stops driving and backs off. The master driving LOW continues uninterrupted. Because of the open-drain wired-AND bus, the losing master cannot corrupt the winning master's data — the LOW level always wins, and the data on the bus reflects what the winning master intended to send. The losing master retries after the bus is free (after STOP).
Why use a Repeated START instead of STOP followed by a new START?
Two reasons: (1) Atomicity — sending STOP releases the bus, allowing another master to take it before your read transaction begins. Repeated START keeps the bus locked to you. (2) Device behaviour — some devices (particularly EEPROMs) reset their internal register pointer when they see a STOP. A Repeated START avoids this reset, allowing you to write a register address and then read from it without the pointer resetting in between. For simple single-master systems with devices that don't have this issue, STOP + START is functionally equivalent.
What is the I2C General Call address and what is it used for?
The General Call address is 0x00. When the master sends 0x00 as the address byte (with W = 0), all slaves that support General Call respond with ACK and listen to the following data byte. It is used for broadcast commands — for example, to software-reset all slaves simultaneously, or to issue a single command to every device on the bus without individual addressing. Not all slaves implement General Call; those that do must have it explicitly enabled. The General Call address cannot be used for reads — it is write-only by definition.
What is the difference between I2C and SMBus?
SMBus (System Management Bus) is a subset of I2C defined by Intel, used in PC motherboards for battery management (Smart Battery), temperature sensors, and power management ICs. Key differences: SMBus has a fixed maximum clock of 100 kHz (no Fast Mode+, no Hs); it adds packet error checking (PEC — a CRC byte at the end of transactions); it defines a timeout (35 ms minimum) so a hung device eventually releases the bus; and it defines specific transaction types (Quick Command, Send Byte, Read/Write Byte, Read/Write Word, Process Call). I2C devices often work on SMBus and vice versa, but the added constraints of SMBus can cause issues with pure I2C-only devices.