Embedded Systems · Embedded Buses
Open-Drain Signalling and Arbitration on a Shared Two-Wire Bus
How pull-up resistors and open-drain drivers turn two wires into a wired-AND, and why that makes simultaneous transmission by two masters harmless rather than destructive.
A bus with two wires and no chip-select line has to answer an electrical question before it can answer any protocol question: several devices drive the same copper, so what happens when two of them drive it differently at the same instant? Push-pull outputs would answer that question with a short circuit. One driver would source current into another driver sinking it, the current would be limited only by the transistors, and the resulting voltage would be undefined. The bus would also lose any information about which device drove it.
I2C avoids the fight by removing the ability to drive a line high at all. Every device output on the bus is open-drain: it can pull the line to ground through a transistor, or it can stop pulling. A resistor to the supply rail restores the high level when nobody pulls. The bus state is therefore the logical AND of every device’s intent, where low is the asserted value. This single decision produces addressing, acknowledgement, clock synchronisation, and multi-master arbitration from the same mechanism, which is why the bus survives with two wires.
One resistor, many drivers, and the meaning of a low level
The pull-up is not a detail of the schematic; it is part of the protocol. When a line is released, the voltage rises toward the supply along an exponential curve set by the resistance and the total capacitance of the wire, the connectors, and every device pin attached to it. Nothing accelerates that rise except a smaller resistor, and a smaller resistor costs current whenever any device holds the line low. The specification fixes the receiver thresholds at 0.3 times the supply for a guaranteed low and 0.7 times the supply for a guaranteed high, which means the rise must complete between those two levels within the allowed time. That budget is the real speed limit of the bus, and it is the subject of sizing pull-ups against bus capacitance.
Because a device can only pull low, it can also read the line while it drives it. A device that releases the line and observes a low level learns that somebody else is asserting it. That read-back is the foundation of every multi-master feature, and it costs nothing extra in hardware: the same pin that drives the transistor is the input to the receiver.
The idle state of both lines is high. Both lines high for long enough is the only condition under which a start condition may be generated, which is why a bus with a permanently stuck line never becomes usable again without intervention.
Start, stop, and the acknowledge slot as electrical events
I2C has no chip-select and no frame delimiter, so the boundaries of a transaction are encoded as transitions that are illegal during data transfer. Data may change only while the clock is low; the receiver samples while the clock is high. A start condition is a high-to-low transition on the data line while the clock is high. A stop condition is a low-to-high transition on the data line while the clock is high. A repeated start is another start condition issued without an intervening stop, which is how a master changes direction or changes target without releasing the bus.
Every byte on the wire is eight bits followed by a ninth clock pulse reserved for the acknowledge. The transmitter releases the data line for that ninth pulse. The receiver either pulls it low, which is an acknowledge, or leaves it high, which is a not-acknowledge. The master generating the clocks reads the line at that moment and knows whether a device answered its address. A not-acknowledge during an address phase usually means no device has that address; a not-acknowledge during a read is the master telling the slave that it wants no more bytes.
This is a weak form of error detection. The acknowledge says a device is present and functioning well enough to respond, not that the byte arrived intact. There is no checksum in the base protocol, and no length field: the master decides when to stop by issuing a stop or repeated start, so a slave that keeps sending bytes after the master has stopped reading simply holds the line while the master ignores it. Higher layers that need integrity add their own check byte, and SMBus, a stricter derivative of the same electrical bus, defines a packet error code for exactly that reason.
Arbitration: two masters, one winner, no lost bits
The interesting property appears when two masters begin a transaction in the same bit time. Both check the bus is idle, both see it idle, both drive a start condition. From that moment both are transmitting, and the protocol requires each to read the data line on every bit it transmits.
Each master compares what it intended to put on the line with what it actually observes. If it released the line for a high bit and reads a low level, another master is transmitting a low bit at the same position, and this master has lost arbitration. It stops driving immediately and switches to receiving. Crucially, the winner never notices. The loser’s contribution at that bit position was a released line, which is exactly what the winner’s low bit needed in order to be low. At every earlier bit the two masters transmitted identical values, otherwise one of them would have lost there. So the winner’s stream is bit-for-bit what it would have been alone.
The consequence is that arbitration compares addresses numerically, with the lowest address winning, because a low bit beats a high bit at the first position where they differ. A master that loses does not retry with a backoff delay; it becomes a receiver of the transaction it lost and may retry at the next bus-idle moment. Two masters sending the same address and the same data at the same time both continue to the end, and both believe they sent it, which is harmless because the bus carried exactly one copy.
Clock arbitration works by the same read-back, with a different rule. Each master has its own low period and its own high period. During the low period, the master that holds the clock low longest determines the low phase, because the line stays low until the last holder releases it. During the high period, the master with the shortest high period determines when the line rises, because the first master to release lets the line rise and every master sees it rise. The resulting clock is the slowest low phase combined with the shortest high phase, so the combined clock is never faster than the slowest participant can tolerate. A master must also check that the clock has actually gone high before starting its high-period timer, which is where clock stretching and arbitration meet.
A simplified bit-banged transmitter shows the read-back requirement:
/* Bus lines are open-drain: drive 0 to assert, 1 to release. */
static bool write_byte(uint8_t b)
{
for (int i = 7; i >= 0; i--) {
sda_drive((b >> i) & 1u); /* release for a 1, pull low for a 0 */
scl_release();
wait_while_scl_low(); /* another master or a slave may hold it */
delay_high();
scl_pull_low();
delay_low();
}
sda_release(); /* hand the line to the receiver for ACK */
scl_release();
wait_while_scl_low();
bool acked = !sda_read(); /* low during the ninth clock is an ACK */
scl_pull_low();
return acked;
}
The loop contains no arbitration check because this fragment is written for a single master. A multi-master implementation adds one comparison per bit: after releasing the data line for a high bit, read it back, and abort if it reads low. The abort path must release the clock as well, and must not generate a stop condition, because the bus is still in use.
What the address space looks like from the wire
A standard transaction begins with seven address bits and a direction bit. The address space is therefore 128 values, of which 16 are reserved: the all-zero pattern is the general call address, one pattern is a start byte a master may send to synchronise on a slow bus, several are master codes used to switch the bus into high-speed mode, and two eight-value blocks are prefixes for ten-bit addressing and for patterns the specification keeps for future use. That leaves 112 usable addresses for ordinary devices, which is why address conflicts are a recurring problem on buses with many identical sensors. Ten-bit addressing extends the space, at the cost of an extra byte per transaction and a prefix that must be recognised by every device on the bus.
Reserved patterns are also the reason a bus scan can be misleading. Probing every address in sequence will report devices at addresses that are not devices, because a reserved pattern can elicit an acknowledge from a device that implements the corresponding feature. A scan that reports a device at the general-call address has found a device that responds to general call, not a device sitting at address zero.
Where the design stops working
The wired-AND is what makes arbitration possible and what makes the bus fragile. A single device that holds the data line low, whether because it lost power in the middle of a byte, because it was reset while driving, or because its state machine is confused, makes the bus permanently busy: no master can generate a start condition, because that requires the data line to be high while the clock is high. The protocol has no timeout in its original form, so the failure is silent and indefinite. Recovering from it requires clocking the stuck device until it releases the line, which is described in clock stretching and stuck-bus recovery.
The second limit is distance. The rise time grows with capacitance, so a bus of a few metres at 100 kbit/s is comfortable, while the same bus at 400 kbit/s or 1 Mbit/s is not, unless the capacitance stays small and the pull-ups shrink accordingly. The specification bounds the total capacitance at 400 pF for standard and fast modes, which is roughly a few metres of cable plus a handful of devices. Beyond that, a differential bus with terminated transmission lines is the correct answer, and differential signalling and termination explains why.
Within those limits the two-wire bus is unusually economical. Two wires carry addressing, data, acknowledgement, clock synchronisation, and collision resolution, with no chip-select per device, and the only shared resource that must be sized is a resistor.
References
- UM10204: I2C-bus specification and user manual — NXP Semiconductors
- The I2C-bus specification, version 2.1 — Philips Semiconductors, 2000
- Linux kernel documentation: I2C and SMBus — Linux kernel project