@@ -83,6 +83,8 @@ void TwoWire::begin(uint8_t address, bool generalCall)
8383
8484 _i2c.generalCall = (generalCall == true ) ? 1 : 0 ;
8585
86+ recoverBus (); // in case I2C bus (device) is stuck after a reset for example
87+
8688 i2c_custom_init (&_i2c, 100000 , I2C_ADDRESSINGMODE_7BIT, ownAddress);
8789
8890 if (_i2c.isMaster == 0 ) {
@@ -501,6 +503,28 @@ inline void TwoWire::resetTxBuffer(void)
501503 }
502504}
503505
506+ // Send clear bus (clock pulse) sequence to recover bus.
507+ // Useful in case of bus stuck after a reset for example
508+ // a mix implementation of Clear Bus from
509+ // https://www.nxp.com/docs/en/user-guide/UM10204.pdf
510+ // https://bits4device.wordpress.com/2017/07/28/i2c-bus-recovery/
511+ void TwoWire::recoverBus (void )
512+ {
513+ pinMode (pinNametoDigitalPin (_i2c.sda ), INPUT);
514+
515+ if (digitalReadFast (_i2c.sda ) == LOW) {
516+ pinMode (pinNametoDigitalPin (_i2c.scl ), OUTPUT);
517+
518+ for (int i = 0 ; i < 18 ; i++) {
519+ digitalWriteFast (_i2c.scl , LOW);
520+ delayMicroseconds (5 );
521+ digitalWriteFast (_i2c.scl , HIGH);
522+ delayMicroseconds (5 );
523+ }
524+ pinMode (pinNametoDigitalPin (_i2c.scl ), INPUT);
525+ }
526+ }
527+
504528// Preinstantiate Objects //////////////////////////////////////////////////////
505529
506530TwoWire Wire = TwoWire(); // D14-D15
0 commit comments