Skip to content

Commit

Permalink
Wire: implement Clear Bus sequence to recover I2C bus.
Browse files Browse the repository at this point in the history
Source:
https://www.nxp.com/docs/en/user-guide/UM10204.pdf
https://bits4device.wordpress.com/2017/07/28/i2c-bus-recovery/

Useful in case of bus stuck after a reset for example
Fixes #1661

Signed-off-by: Alexandre Bourdiol <alexandre.bourdiol@st.com>
  • Loading branch information
ABOSTM committed Feb 25, 2022
1 parent 443b609 commit a150c2e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
24 changes: 24 additions & 0 deletions libraries/Wire/src/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ void TwoWire::begin(uint8_t address, bool generalCall)

_i2c.generalCall = (generalCall == true) ? 1 : 0;

recoverBus(); // in case I2C bus (device) is stuck after a reset for example

i2c_custom_init(&_i2c, 100000, I2C_ADDRESSINGMODE_7BIT, ownAddress);

if (_i2c.isMaster == 0) {
Expand Down Expand Up @@ -501,6 +503,28 @@ inline void TwoWire::resetTxBuffer(void)
}
}

// Send clear bus (clock pulse) sequence to recover bus.
// Useful in case of bus stuck after a reset for example
// a mix implementation of Clear Bus from
// https://www.nxp.com/docs/en/user-guide/UM10204.pdf
// https://bits4device.wordpress.com/2017/07/28/i2c-bus-recovery/
void TwoWire::recoverBus(void)
{
pinMode(pinNametoDigitalPin(_i2c.sda), INPUT);

if (digitalReadFast(_i2c.sda) == LOW) {
pinMode(pinNametoDigitalPin(_i2c.scl), OUTPUT);

for (int i = 0; i < 20; i++) {
digitalWriteFast(_i2c.scl, LOW);
delayMicroseconds(10);
digitalWriteFast(_i2c.scl, HIGH);
delayMicroseconds(10);
}
pinMode(pinNametoDigitalPin(_i2c.scl), INPUT);
}
}

// Preinstantiate Objects //////////////////////////////////////////////////////

TwoWire Wire = TwoWire(); //D14-D15
1 change: 1 addition & 0 deletions libraries/Wire/src/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class TwoWire : public Stream {

void resetRxBuffer(void);
void resetTxBuffer(void);
void recoverBus(void);

public:
TwoWire();
Expand Down

0 comments on commit a150c2e

Please sign in to comment.