Skip to content

I2C stability hypothesis  #745

Closed
Closed
@stickbreaker

Description

@stickbreaker

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions