Embedded Systems · Embedded Buses
Clock Stretching and Recovering a Bus Held Low by a Stuck Slave
Why a slave is allowed to hold the clock line down, how that interacts with arbitration and timeouts, and the pulse sequence that frees a device stuck mid-byte.
A bus that allows a slave to delay the master is making an unusual concession. Most buses put all timing authority in one place: the master issues clocks and the slave must respond within them. The two-wire bus inverts that, because the clock line is open-drain and any device on it can hold it low. A slave that needs more time to produce a byte simply keeps the clock low until it is ready, and the master is required to wait. This is clock stretching, and it is simultaneously one of the protocol’s most useful features and the source of its most common lockups.
How stretching works electrically and what it costs
Because the clock line is pulled up by a resistor and driven low by open-drain transistors, a device that holds it low wins against every device that has released it. The master releases the clock to let it rise, sees that it has not risen, and must not proceed. The rule is that the master may only continue once it has observed the clock actually high for the required minimum high period.
The cost is paid in throughput and in worst-case timing. A master’s transaction time is no longer a function of its own clock; it is a function of the slowest slave in the transaction. The specification does not bound how long a slave may stretch, so a master that waits forever can wait forever. Every practical master therefore imposes a timeout, and the timeout has to be long enough for the slowest legitimate stretch and short enough that a stuck bus is detected before the system’s own watchdog expires.
Stretching is bounded by mode in one respect: during a stretched low period the bus is still in the same transaction, so the bus-idle timeout does not apply. A master that treats “clock low for longer than the bus timeout” as a fault will abort legitimate transactions with a slow slave such as an analogue-to-digital converter that stretches for the duration of a conversion. Distinguishing a slow slave from a stuck slave is the entire difficulty.
Stretching interacts with arbitration in a way that is easy to get wrong. During the low phase of a bit, several masters may be driving the clock low at once. The line stays low until the last of them releases, so the low phase is the union of all masters’ low periods. During the high phase, the first master to release lets the line rise, so the high phase is the intersection. A master must therefore not assume that the clock has risen just because it released the line; it must read the line, and it must also handle the case where a slave is stretching during a bit that the master won.
The consequence for a multi-master system is that a master which has lost arbitration must stop driving the data line but must continue to track the clock until the current byte boundary, because the winning master is still producing clocks and the loser has to know when it may retry.
Where stretching is actually used
A slave stretches the clock in three situations. The first is after it acknowledges its address and before it delivers the first data byte, while it fetches the value from a conversion or a slow memory. The second is between a write of a register address and the subsequent read, which is why a read of a register in a device with a slow internal bus commonly shows a stretch at exactly that point. The third is during a byte that the device cannot yet supply, which a well-behaved device avoids by stretching before the acknowledge rather than after.
Some devices stretch on the acknowledge bit itself, holding the clock low after the eighth bit until they have decided whether to acknowledge. This is legal and it is the reason a master must sample the data line only after the clock has been observed high, not at the moment it releases the clock.
A number of controllers do not implement stretching at all on the master side. They generate clocks from a fixed divider and sample on a fixed schedule, so a slave that stretches produces a corrupted read rather than a delayed one. This is a documented limitation in some microcontroller peripherals and it is worth checking before choosing a slave that relies on stretching. The workaround is to reduce the bus rate far enough that the slave never needs to stretch, which converts a protocol feature into a timing margin.
Detecting the stuck bus
The failure looks like this: a transaction is interrupted, typically by a reset of the master in the middle of a byte, by a power glitch on a slave, or by a slave that was addressed while its internal state machine was in an unexpected place. The slave is left holding the data line low, sometimes holding the clock low as well. The master comes back, sees the data line low, and concludes the bus is busy. It waits for a stop condition that never comes.
The signal is the idle check. A start condition requires both lines high. If the data line stays low while the master releases it, the bus can never be idle, and every transaction attempt fails at the first step. A driver that reports “bus busy” or a timeout on the very first transfer after a reset is describing this condition.
There is a second, subtler variant: the clock line is free but the data line is stuck, and the slave is holding the data line low waiting for clocks so it can finish the byte it was in the middle of. This one is recoverable by clocking, because the slave’s own state machine advances on the clock. That is what the recovery sequence exploits.
The recovery sequence
The idea is to give the stuck slave the clocks it is waiting for, without a start condition, until it releases the data line. Nine clock pulses are the conventional number: the slave may be anywhere within a byte, so up to eight clocks complete the byte and a ninth covers the acknowledge slot. Many implementations use nine and some use sixteen, since a device that has drifted further can need more.
/* Recover a bus whose data line is held low by a confused slave.
Both lines are open-drain; nothing here generates a start condition. */
static bool i2c_bus_recover(void)
{
if (sda_read() && scl_read())
return true; /* already idle, nothing to do */
scl_release();
for (int i = 0; i < 9; i++) {
if (sda_read())
break; /* slave has let go */
scl_pull_low();
delay_half_period();
scl_release();
delay_half_period();
if (!wait_while_scl_low(I2C_STRETCH_LIMIT))
return false; /* clock itself is stuck */
}
/* Manufacture a stop condition: SDA low-to-high while SCL is high. */
scl_pull_low();
delay_half_period();
sda_pull_low();
delay_half_period();
scl_release();
delay_half_period();
sda_release();
delay_half_period();
return sda_read() && scl_read();
}
The stop condition at the end is not decoration. A slave that has just been clocked out of a partial byte is still in a transaction from its own point of view; the stop condition tells it that the transaction is over and returns its state machine to idle. Without it, the next start condition may be interpreted as a repeated start in the middle of the previous transfer.
Two details make the difference between a recovery that works and one that appears to work. The clock must be driven at a rate within the slave’s specification, not as fast as the pins allow, because a slave that is already confused will not tolerate an out-of-spec clock. And the data line must be released during the pulses, not driven high, since the only way to know the slave has let go is to read the line.
If nine clocks do not free the data line, the cause is not a slave waiting for clocks. It is either a slave that is holding the line actively — which no amount of clocking will fix — or a hardware fault such as a short to ground or a failed transceiver. At that point the only remaining remedy is to power-cycle the offending device, which means the board design needs a way to do that, typically a load switch on the device’s supply or a dedicated reset line. A bus without that provision is unrecoverable in the field.
Timeouts and the policy question
A recovery routine is only reached if something decides the bus is broken. That decision is a timeout, and timeouts on this bus are a policy problem rather than a technical one, because the protocol does not define any.
A per-transaction timeout bounds the total time a single transfer may take, including legitimate stretching. A per-byte timeout bounds the time between clock edges. A bus-idle timeout detects the case where no transaction has completed for a long period. Each catches a different failure: the first catches a slave that stretches far too long, the second catches a slave that has stopped responding mid-byte, the third catches a master that died while holding the bus.
SMBus, the derivative of this bus used for system management, defines timeouts where the original does not: a maximum clock low period and a maximum cumulative low period, with the explicit intent that a stuck device eventually releases the bus or is detected. Devices built to SMBus rules will therefore not stretch indefinitely, and a controller that implements the SMBus timeout will abort a transfer that a plain device might have completed. Mixing the two on one bus is a common source of intermittent failures with slow devices.
The practical arrangement is a timeout per transaction set well above the slowest documented stretch of any device on the bus, a recovery sequence on timeout, and a bounded number of recovery attempts before the bus is declared failed. The bound matters because a bus with a permanently shorted line will otherwise spend every subsequent transaction in the recovery path, and the failure will present itself as a system-wide slowdown rather than as a clear error.
What the failure teaches about the design
The reason a stuck bus is possible at all is the same property that makes arbitration possible: any device can assert a line. That property cannot be removed without removing multi-master operation and slave flow control. What can be removed is the case where a master resets in the middle of a byte, by having the master complete or abort its transaction before resetting, and what can be added is the ability to power-cycle a device that will not let go.
The clock-rate budget interacts with all of this. A slower bus gives a slave more time and reduces the chance that stretching is needed, and it also gives the recovery sequence more room before a watchdog expires. The rise-time limit that sets the maximum rate is described in sizing pull-ups against bus capacitance, and the electrical reason the line cannot simply be driven high is in open-drain signalling and arbitration.
References
- UM10204: I2C-bus specification and user manual — NXP Semiconductors
- System Management Bus (SMBus) Specification, Version 3.0 — SBS Implementers Forum
- Linux kernel documentation: I2C and SMBus — Linux kernel project