Description
Hardware:
Board: WeMos Bluetooth& Battery, (Using ESP32 Dev Module in Arduino)
Core Installation/update date: 05/OCT/2017?
IDE name: Arduino IDE 1.8.5
Flash Frequency: 80Mhz
Upload Speed: 921600
Description:
I am getting different results from the I2C subsystem depending on how often(fast) calls are made.
I am accessing 24LCxx EEPROMS, after a data write sequence, the chip can take up to 5ms to preform the write. While this internal cycle is completing the EEPROM will not ACK its address. So after a write command, I can either delay for 5ms (worst case) or poll the EEPROM until it ACK's.
first Sketch
This sketch is producing unexpected I2C error codes. (5) I2C_ERROR_BUSY
uint32_t notReady=0;
bool i2cReady(uint8_t adr){
uint32_t timeout=millis();
bool ready=false;
while((millis()-timeout<100)&&(!ready)){
Wire.beginTransmission(adr);
int err=Wire.endTransmission();
ready=(err==0);
if(!ready){
notReady++; // howmany times this loop executed
if(err!=2) Serial.printf("{%d}",err); // 2 is NAK, I am only expecting 0:ok or 2:NAK
}
}
return ready;
}
Debug output
I have ERROR level debugging enabled.
[E][esp32-hal-i2c.c:160] i2cWrite(): Busy Timeout! Addr: 50
{5}[E][esp32-hal-i2c.c:160] i2cWrite(): Busy Timeout! Addr: 50
{5}0x50: 0 0 2 0 4k Bytes 2
each of the {5} are unexpected errors. The [esp32-hal-i2c.c:160] should not have occurred.
Second Sketch that functions as expected:
uint32_t notReady=0;
bool i2cReady(uint8_t adr){
uint32_t timeout=millis();
bool ready=false;
while((millis()-timeout<100)&&(!ready)){
Wire.beginTransmission(adr);
int err=Wire.endTransmission();
ready=(err==0);
if(!ready){
notReady++;
// if(err!=2)
Serial.printf("{%d}",err);
}
}
return ready;
}
Second Debug Output
ERROR level debugging is still enabled
{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}{2}0x50: 0 0 16 0 4k Bytes 14
The only difference between these two examples is that the second one sends a three character Serial output each time Wire.endTransmission() returns an error(which slows down the rate of I2C calls). The first one only sends these three characters if (err!=2) ( much faster I2C calls).
What I think is happening is that the I2C bus is still returning to IDLE from the STOP bit. The subsystem is correctly reporting the 'bus' is busy because the pullup on the SDA line only supplies a finite current.
I will see if I can create a test circuit and use my scope to capture events. I'll modify i2cWrite() to generate a trigger pulse and compare it to SDA and SCL.
Chuck.