@@ -83,6 +83,8 @@ void TwoWire::begin(uint8_t address, bool generalCall)
83
83
84
84
_i2c.generalCall = (generalCall == true ) ? 1 : 0 ;
85
85
86
+ recoverBus (); // in case I2C bus (device) is stuck after a reset for example
87
+
86
88
i2c_custom_init (&_i2c, 100000 , I2C_ADDRESSINGMODE_7BIT, ownAddress);
87
89
88
90
if (_i2c.isMaster == 0 ) {
@@ -501,6 +503,28 @@ inline void TwoWire::resetTxBuffer(void)
501
503
}
502
504
}
503
505
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 < 20 ; i++) {
519
+ digitalWriteFast (_i2c.scl , LOW);
520
+ delayMicroseconds (10 );
521
+ digitalWriteFast (_i2c.scl , HIGH);
522
+ delayMicroseconds (10 );
523
+ }
524
+ pinMode (pinNametoDigitalPin (_i2c.scl ), INPUT);
525
+ }
526
+ }
527
+
504
528
// Preinstantiate Objects //////////////////////////////////////////////////////
505
529
506
530
TwoWire Wire = TwoWire(); // D14-D15
0 commit comments