Description
Bug description
Steps to reproduce
Given the following minimum code example:
#include "Wire.h"
void setup() {
Wire.begin(21,22);
Serial.begin(115200);
Serial.println("Start i2c-test");
}
void loop() {
byte error;
// 0x20 is the address of a pcf8574 GPIO expander
Serial.println("Try to contact 0x20");
Wire.beginTransmission(0x20);
error = Wire.endTransmission();
Serial.print("Error code is:");
Serial.println(error);
delay(1000);
}
We've run this on a Nano32, WROOM32 and on a custom board. Run it:
- on a proper (10k) pulled up I2C-bus with no devices on it
- on a bus that has PCF8574 on it
- on a bus that is only a wire with no pullups in place
- on a bus where SCL is pulled up and SDA is pulled down
also try to change the condition of the test during the runtime of the code (e.g. remove a pullup or a cable on a breadboard).
Observed behavior
-
Initially we see error code
0
(no error, i.e. device ACKed) or2
(NACK on address). After removing a wire or pull up we see error code3
(NACK on data (⚠️ we have not even sent data here⚠️ )). When we then put in the missing component again the outputted error code will stay3
until we reset the ESP32. -
If we pull down SDA the code execution will stop / there will be no more stuff printed to the console.
-
Observing what happens on an oscilloscope we see in the first case (removed pullup) that after the faulty code (
3
) has occured the first time the I2C bus stays dark (high) on SCL and SDA.
In the second case (SDA pulled down) we observed a steady oscillation at 100kHz on SCL until we reset the device and remove the pulldown on SDA. Removing the pulldown alone does not work. -
We have observed an error condition as in (1.) on a known good board after several days of polling a value from a PCF8754 every 20ms. It looks like if the request fails once it will fail over and over again until we reboot.
Expected behavior
- When we have a faulty connection or device on the I2C bus the Wire commands MUST return a meaningful error code and MUST NOT freeze the ESP32/code execution (maybe timeout or throw an exception if inevitable?).
- Also when we have removed the faulty hardware condition and retry the command it MUST return a
0
(if we have an i2c device) or2
(if no device is present) error code. I.e. it MUST be resilient against faulty conditions without a reboot.