Closed LaurentLouf closed 6 years ago
@LaurentLouf
[E][esp32-hal-i2c.c:988] i2cProcQueue(): I2C exitCode=0x112
This error message show an arbitration failure. The esp32 was using the i2c bus and another master collided with it. Do you have a multi-master configuration?
uint32_t i2cGetFrequency(i2c_t* i2c) will only return 0 under two conditions:
uint32_t i2cGetFrequency(i2c_t * i2c)
{
if(i2c == NULL) {
return 0;
}
uint32_t result = 0;
uint32_t old_count = (i2c->dev->scl_low_period.period+i2c->dev->scl_high_period.period);
if(old_count>0) {
result = APB_CLK_FREQ / old_count;
} else {
result = 0;
}
return result;
}
Either of these conditions are abnormal, never should be encountered during normal execution. Normally scl_low_period
and scl_high_period
are both 400, and APB_CLK_FREQ is 80,000,000 so the result is 100kHz(default i2c bus rate).
I don't have any idea how i2c
could be null, the call to i2cWrite() would fail with ERROR_DEV
is i2c
was null before it ever called i2cProcQueue()
So, the only way I can see this divide by zero occurring is that if APB_CLK_FREQ
is less than scl_low_period
+ scl+high_period
or scl_low_period
and scl_high_period
are both zero?
Chuck.
This error message show an arbitration failure. The esp32 was using the i2c bus and another master collided with it. Do you have a multi-master configuration?
That may be it. I recently inherited this code, so there are a few things that I still don't fully get about how it functions. This problems occur when connecting via Bluetooth and sending some data, so if I understand correctly, this happens on core 0 where the bluetooth code executes. On the other core, it's the application code, which uses i2c, so could it be a conflict between the two ? Is this doable/advisable to try to handle i2c communication on two different cores ? Should I configure i2c on the second core or just re-design the code to avoid such configurations ?
And a big thanks for your investigation of the problem !
@LaurentLouf describe you i2c circuit a multi-master system is abnormal. I haven't seen anyone actual use a esp32 in a multi-master environment.
You can add additional debug to i2cGetFrequency()
to verify the actual cause:
uint32_t i2cGetFrequency(i2c_t * i2c)
{
if(i2c == NULL) {
log_e( "i2c==NULL" );
return 0;
}
uint32_t result = 0;
uint32_t old_count = (i2c->dev->scl_low_period.period+i2c->dev->scl_high_period.period);
if(old_count>0) {
result = APB_CLK_FREQ / old_count;
} else {
log_e( "old_count==%ld",old_count );
result = 0;
}
if( result==0 ){
log_e("fail freq=0, APB_CLK_FREQ=%ld, Clock=%ld",APB_CLK_FREQ,old_count);
return result;
}
I think you have a problem with a memory overwrite issue. Your report describes a event that cannot happen through normal I2C transactions. There is something else happening.
Chuck.
@stickbreaker Thanks for your help. As expected, removing the i2c logic from the Bluetooth code fixed the problem, which seems to be that i2c devices were controlled by two different threads at the same time. Moving it to only one thread and no concurrent access is in all cases a better practice.
Well, my experience sharing a TwoWire among 4 separated tasks is that holding a xSemaphoreTakeRecursive() to the in use Wire (1 or 0) is enough. I did succefullly share the Wir0 & Wire1 with BMP180+BMP280 each plus a OLED display on Wire0 (driven by the
Hardware:
Board: ESP32 WROOM32 Core Installation/update date: last IDE name: ESP-IDF Flash Frequency: 140Mhz ? Upload Speed: 115200
Description:
I encounter random crashes using a DS3231 with I2C. While this may be on my end since I'm using it inside a BLE function, the error is pretty clear :
IntegerDivideByZero
with this line concerned https://github.com/espressif/arduino-esp32/blob/2fbe4908facddc91e299f56aa4afd0573b20dabb/cores/esp32/esp32-hal-i2c.c#L956 .portTICK_PERIOD_MS
should'nt be equal to zero, so my best guess is that i2cGetFrequency returns zero (which is possible, considering the code of the function), which isn't checked and so creates a possible error.Debug Messages:
Not sure that helps but anyway :