Skip to content
Chuck Todd edited this page Feb 9, 2019 · 7 revisions

Feb 8, 2019 I finally have a I2C slave device that uses SCL stretching for sampling synchronization. The Sensirion SHT25 Temperature/Humidity sensor has two operation modes:

  • Hold Master
  • No Hold Master

The "Hold Master" commands are the SCL stretching commands. These commands are a two part operation, first the sample command is given with a Write command then a Read operation is started. The slave ACK's its ID then holds SCL low until the sample is acquired, It then starts outputting the first bit of the sampled value, then releases the SCL. This a valid I2C protocol sequence.

But, this sequence can cause a communication failure on the ESP32. If the configured timeout period expires before the sensor releases SCL the i2c peripheral issues a timeout interrupt, this event seems to lockup the peripheral. This timeout interrupt will be reissued every timeout period from that point forward(Why would the peripheral continue to re-issue this timeout interrupt after the stretch event has ended? Shouldn't there be a method to recover after the stretching event ends?). I have not been able to recover from a timeout without Aborting the in-progress transaction by RESETTING the peripheral.

The ESP32 has a hardwired timeout that cannot be disabled in the I2C peripheral. This timeout is configured as a divider to the APB clock. The APB clock is related to the system clock, it ranges from 80MHz down to 10MHz. The divider is a twenty bit value, the maximum value results in a 13.1ms timeout when APB is 80MHz to 104.8ms when APB is 10MHz. So, if the SCL stretch event exceed this timeout period the transaction fail in an unrecoverable method.

Clone this wiki locally