2222#include " twi.h"
2323#include " pins_arduino.h"
2424#include " wiring_private.h"
25+ #include " PolledTimeout.h"
2526
2627
2728
@@ -122,9 +123,12 @@ class Twi
122123 // Handle the case where a slave needs to stretch the clock with a time-limited busy wait
123124 inline void WAIT_CLOCK_STRETCH ()
124125 {
125- for (unsigned int t = 0 ; !SCL_READ () && (t < twi_clockStretchLimit); t++)
126- {
127- /* noop */
126+ esp8266::polledTimeout::oneShotFastUs timeout (twi_clockStretchLimit);
127+ esp8266::polledTimeout::periodicFastUs yieldTimeout (5000 );
128+ while (!timeout && !SCL_READ ()) // outer loop is stretch duration up to stretch limit
129+ {
130+ if (yieldTimeout) // inner loop yields every 5ms
131+ yield ();
128132 }
129133 }
130134
@@ -245,7 +249,7 @@ void Twi::init(unsigned char sda, unsigned char scl)
245249 pinMode (twi_sda, INPUT_PULLUP);
246250 pinMode (twi_scl, INPUT_PULLUP);
247251 twi_setClock (preferred_si2c_clock);
248- twi_setClockStretchLimit (230 ); // default value is 230 uS
252+ twi_setClockStretchLimit (150000L ); // default value is 150 mS
249253}
250254
251255void Twi::setAddress (uint8_t address)
@@ -444,6 +448,7 @@ unsigned char Twi::readFrom(unsigned char address, unsigned char* buf, unsigned
444448
445449uint8_t Twi::status ()
446450{
451+ WAIT_CLOCK_STRETCH (); // wait for a slow slave to finish
447452 if (!SCL_READ ())
448453 {
449454 return I2C_SCL_HELD_LOW; // SCL held low by another device, no procedure available to recover
@@ -463,11 +468,6 @@ uint8_t Twi::status()
463468 return I2C_SDA_HELD_LOW; // I2C bus error. SDA line held low by slave/another_master after n bits.
464469 }
465470
466- if (!write_start ())
467- {
468- return I2C_SDA_HELD_LOW_AFTER_INIT; // line busy. SDA again held low by another device. 2nd master?
469- }
470-
471471 return I2C_OK;
472472}
473473
0 commit comments