Electronics Design AU
Communications

How Does I2C Clock Stretching Work, and How Do You Debug a Timeout?

Last updated 15 July 2026 · 6 min read

Direct Answer

Clock stretching is a feature built into the I2C specification that allows a slave device to hold SCL low after the master releases it, pausing the bus until the slave is ready to continue — the master, seeing SCL still low, waits rather than proceeding with the next clock pulse. It's a legitimate, spec-defined flow-control mechanism, not a fault condition in itself, and it's commonly used by EEPROMs during an internal write cycle, sensors mid-conversion, and any slave whose internal processing occasionally can't keep up with the bus clock. It becomes a debugging problem only when the master's I2C peripheral or driver doesn't actually support waiting for a stretched clock (some bit-banged or DMA-driven implementations silently proceed as if SCL had gone high), or when a slave stretches for far longer than the master's timeout allows — in both cases the transfer corrupts silently or the bus appears to hang, and the fix depends on which of the two is actually happening.

Detailed Explanation

I2C's SCL and SDA lines are both open-drain: any device on the bus can pull either line low, but no device can actively drive either line high — that's what the external pull-up resistors are for. Clock stretching exploits this directly on the clock line. During a normal transaction, the master releases SCL after each clock pulse and the pull-up resistor returns it high; a compliant master then checks that SCL has actually gone high before starting the next clock pulse, rather than assuming it has. If a slave needs more time — to finish an internal operation, load the next byte into its shift register, or complete an ADC conversion — it can hold SCL low itself during that check. The master sees SCL still low, and per the I2C specification, waits. When the slave is ready, it releases SCL, the pull-up returns it high, and the master proceeds with the next clock pulse exactly as if no delay had occurred.

This is a deliberate, specification-defined flow-control mechanism (NXP UM10204, Section 3.1.9), not an error condition or a workaround for a slow device — it exists specifically so a slave with variable internal timing doesn't need external logic to buffer or pace the bus. The failure mode isn't clock stretching itself; it's a master that doesn't correctly wait for it, or a slave that stretches for longer than the master is prepared to tolerate.

Practical Examples

An I2C EEPROM write is the textbook case: the host writes a page of data, the EEPROM acknowledges the write command itself immediately, but the actual non-volatile write to the memory array takes on the order of milliseconds to complete internally — during which many EEPROM families either stretch the clock on the next access attempt or simply NACK it until the write finishes, depending on the specific part. Firmware that doesn't account for this and immediately issues the next transaction will see either a stalled bus (if the part stretches) or a failed transaction that needs a retry loop (if the part NACKs) — check the datasheet's write-cycle timing section to know which behaviour to expect and design the retry or wait strategy around it, rather than discovering it from an intermittent field failure.

A humidity or gas sensor that stretches the clock while a conversion completes is a second common case: the host issues a read immediately after triggering a measurement, and the sensor holds SCL low until the conversion result is actually ready, rather than returning a stale or partially-updated value. This is functionally convenient for the host firmware (no separate "is it ready yet" polling step is needed) but only works correctly if the master's I2C implementation genuinely honours the stretch — see the FAQ below for what happens when it doesn't.

Design Considerations

  • Confirm the master's I2C peripheral supports clock stretching before relying on a slave that uses it. A hardware I2C peripheral generally supports it correctly by design, but a bit-banged software implementation only does if it explicitly reads SCL back and waits for it to go high, rather than toggling the pin on a fixed timer. Check the specific implementation, not just the protocol, before assuming this works.
  • Set the master's I2C timeout generously enough for the slowest stretching operation in the design, not just the nominal transaction time — an EEPROM page-write cycle or a sensor's slowest conversion mode can be orders of magnitude longer than a normal byte transfer, and a timeout set for typical transaction speed will trip on the legitimate slow case. Read the specific part's datasheet for its maximum stretch or write-cycle duration and add margin.
  • Distinguish a genuinely stuck bus (a fault) from a long but legitimate stretch (normal operation) in firmware. Both look identical from the master's perspective — SCL held low — so the only way to tell them apart is the timeout value: too short and legitimate stretching trips a false fault-recovery sequence; too long and a genuinely stuck slave (see I2C bus-hung recovery) hangs the application far longer than necessary. Set the timeout from the slowest datasheet-specified stretch duration in the design, with margin, not from a generic default.
  • Capture the failure with a logic analyzer before assuming a firmware bug. A trace that shows SCL held low by the slave for a bounded, consistent duration after a specific command (e.g. always immediately following a page write) is legitimate stretching that needs a longer timeout or a wait loop; SCL held low indefinitely, or SDA also stuck low, indicates a genuinely wedged bus requiring the bus-clear recovery sequence instead. Don't guess — capture the actual waveform.
  • Firmware bring-up support: diagnosing an intermittent I2C corruption or hang that only appears with a specific stretching-capable device is exactly the kind of bus-level debugging Zeus Design's embedded firmware team handles as part of sensor and peripheral integration work.

Common Mistakes

  • Using a bit-banged I2C implementation with a stretching-capable slave without verifying the bit-bang code actually reads SCL back. A naive implementation that assumes SCL goes high immediately after being released will send the next clock pulse while the slave is still holding it low, corrupting the transfer silently — no error is raised, the data is simply wrong, which is often far harder to diagnose than an outright hang.
  • Setting the master's I2C timeout to a generic short value (copied from an unrelated project or a default HAL example) without checking the datasheet's actual maximum stretch duration for every slave on the bus, then treating the resulting spurious timeout as a hardware fault when it's actually a timeout configured too aggressively for legitimate device behaviour.
  • Assuming a device that appears to work at low transaction rates on the bench will behave the same in production, when the real failure only appears under back-to-back transactions that don't leave enough margin for the slave's occasional longer stretch — bench testing at a leisurely pace can mask a timing bug that only shows up under sustained bus load.
  • Treating every "bus appears hung" symptom as the same STM32 BUSY-flag lockup fault without first checking whether it's actually bounded, datasheet-consistent clock stretching that just needs a longer timeout — the fix for the two is different, and applying the wrong one (a full bus-clear recovery sequence for what was actually a normal, if slow, EEPROM write) adds unnecessary complexity and risk to the firmware.

Frequently Asked Questions

Which I2C devices commonly use clock stretching?
EEPROMs are the most frequently cited case — many I2C EEPROM families stretch the clock (or, more commonly, NACK a poll) during the internal write cycle that follows a page write, which can take several milliseconds. Some sensor ICs stretch the clock briefly while an internal ADC conversion or measurement completes if the host reads before the result is ready, rather than returning stale or invalid data. The exact behaviour — clock stretching versus a busy-poll NACK pattern — is device-specific and stated in the datasheet's timing or write-cycle section; do not assume one mechanism without checking, since firmware needs to handle whichever one the specific part actually implements.
Does every I2C master support clock stretching?
No, and this is the single most common cause of clock-stretching-related bugs. A hardware I2C peripheral built to the full specification supports it inherently, because SCL is open-drain on both sides and the master's own clock-generation logic naturally samples the line before continuing. A bit-banged software I2C implementation only supports it if the firmware explicitly reads SCL back after releasing it and waits for the line to actually go high before proceeding — a naive bit-bang implementation that just toggles a GPIO on a fixed delay without reading it back will not honour a stretched clock at all, and will send subsequent clock pulses while the slave is still holding SCL low, corrupting the transfer. Some MCU DMA-driven I2C peripherals have documented errata around clock-stretching interaction with a specific speed mode or repeated-start pattern — check the specific silicon's errata sheet if intermittent corruption appears only with a known-stretching slave.

References

Related Questions

Related Forum Discussions