Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 372 of 9365. Communication Protocols and Data TransferFree lesson

Managing Clock Stretching for Slower Peripheral Devices

Develop logic to detect and respond to slave-held clock lines, allowing slow peripherals to pause data transfer during processing.

In this lesson, you will learn how to implement logic that allows a slow I2C slave device to pause data transmission by holding the clock line low.

The Mechanics of Clock Stretching

In an I2C transaction, the master is responsible for generating the clock signal on the SCL line. However, because I2C uses an open-drain configuration, any device on the bus—including the slave—can pull the SCL line to logic low. When a slave device needs more time to process data (such as finishing an internal ADC conversion or writing a byte to non-volatile memory), it holds the SCL line low even after the master releases it.

If the master were to blindly continue toggling SCL, it would violate the timing requirements of the slave, leading to data corruption. To manage this, the master must perform a "wait-and-check" operation during every clock cycle.

Implementing the Wait Logic

Before the master releases SCL and proceeds to the next bit, it must verify that the line actually transitioned to a high state. If the master releases SCL but reads a logic low, it knows the slave is "stretching" the clock. The master must then enter a wait loop until the line is released.

// Simplified logic for a master bit-banging I2C
void send_clock_pulse() {
    // Release SCL to go high
    set_scl_high();

    // Check if the slave is holding the clock low (Clock Stretching)
    while (read_scl_pin() == 0) {
        // Master waits here until the slave releases the SCL line
        // We could also implement a timeout mechanism here to prevent infinite loops
    }

    // Now that SCL is confirmed high, proceed with timing
    delay_half_period();
    set_scl_low();
}

Strategic Considerations

When implementing this, always include a timeout mechanism. If a slave device malfunctions or hangs, an infinite while loop will lock up your entire firmware. By checking a counter or a hardware timer inside the loop, you can exit the transaction, send a Stop condition, and signal an error to your application layer, ensuring the system remains responsive even when hardware encounters issues.

Key Takeaway: Clock stretching allows slow peripherals to safely pause communication by holding SCL low; the master must verify the line state before proceeding to ensure synchronization.