# I2C: clock stretch timeout on SCL line, slave holding clock low

- **ID:** `embedded/i2c-clock-stretch-timeout`
- **Domain:** embedded
- **Category:** protocol_error
- **Verification:** ai_generated
- **Fix Rate:** 79%

## Root Cause

I2C slave device stretches the clock (holds SCL low) beyond the master's timeout period, often due to slow internal processing or bus lock.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| STM32Cube_FW_L4_V1.18.0 | active | — | — |
| IAR EWARM 9.40.1 | active | — | — |
| ARM GCC 10.3.1 | active | — | — |
| FreeRTOSv202212.01 | active | — | — |

## Workarounds

1. **Increase I2C timeout in HAL_I2C_Master_Transmit(): set hi2c1.Init.Timing = 0x20C0E0FF; (for 100 kHz) and use HAL_I2C_Master_Transmit() with a timeout of 10000 ms instead of default 1000 ms.** (82% success)
   ```
   Increase I2C timeout in HAL_I2C_Master_Transmit(): set hi2c1.Init.Timing = 0x20C0E0FF; (for 100 kHz) and use HAL_I2C_Master_Transmit() with a timeout of 10000 ms instead of default 1000 ms.
   ```
2. **Implement software reset of I2C peripheral after timeout: call HAL_I2C_DeInit(&hi2c1); HAL_I2C_Init(&hi2c1); then retry the transaction up to 3 times.** (78% success)
   ```
   Implement software reset of I2C peripheral after timeout: call HAL_I2C_DeInit(&hi2c1); HAL_I2C_Init(&hi2c1); then retry the transaction up to 3 times.
   ```
3. **Use I2C recovery sequence: toggle SCL 9 times while SDA is high to release the slave: for(int i=0;i<9;i++) { HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET); delay_us(5); HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); delay_us(5); }** (85% success)
   ```
   Use I2C recovery sequence: toggle SCL 9 times while SDA is high to release the slave: for(int i=0;i<9;i++) { HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET); delay_us(5); HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); delay_us(5); }
   ```

## Dead Ends

- **Reducing I2C bus speed from 400 kHz to 100 kHz** — Slower speed may increase stretch duration, making timeout more likely. (80% fail)
- **Disabling clock stretching in the slave device configuration** — Many I2C slaves require clock stretching for proper operation; disabling it may cause data corruption. (90% fail)
- **Adding a hardware pull-up resistor on SCL line** — Pull-up resistors are already present; this does not address the slave holding the line low. (85% fail)
