Page 1 of 1

I2C: protection against connection (lines) problems

Posted: Sun Mar 19, 2017 11:07 am
by KanyeKanye
Each time, when I2C's lines SCL or SDL stops connect (eg. I am unplugging it), i2c_master_cmd_begin returns ESP_FAIL or ESP_ERR_TIMEOUT.
If ESP_ERR_TIMEOUT is returned, I2C wont work anymore - after replugging disconnected pins, result is still ESP_ERR_TIMEOUT. How to protect it to recover after disconnecting pins?
My attempts showed that executing i2c_driver_delete, i2c_param_config, i2c_driver_install result in panic a core.

EDIT:
Sometimes disconnecting SCL line result in ESP_FAIL and a core panic in strange place: backtrack show a core panic on xSemaphoreTake

Re: I2C: protection against connection (lines) problems

Posted: Thu Mar 23, 2017 11:57 am
by KanyeKanye
[Up]

Re: I2C: protection against connection (lines) problems

Posted: Thu Mar 23, 2017 2:51 pm
by kolban
You bring up an interesting concept/question. I'm wondering (out loud) if the concept of "pulling" an I2C device is has any kind of valid semantics. I am going to stick my neck out and say that I2C is not like USB or a UART which were designed from the outset to be able to be connected/disconnected dynamically. Rather I2C is a communication protocol at the "PCB" trace level (i.e. the copper wires etched into the circuits) with the I2C devices permanently fixed.

By analogy ... if the processor is reading or writing to a flash memory device and we decided we want to disconnect the flash memory chip for a few moments and then plug it back in again, we wouldn't expect our solution to recover. I think the same is associated with I2C devices. The semantics of I2C doesn't include the notion that they can be connected or disconnected dynamically.

Re: I2C: protection against connection (lines) problems

Posted: Thu Mar 23, 2017 5:01 pm
by Lurcher
If you want to hot-swap I2C devices, you may need something like the PCA9511A chip.
Still, deleting the driver shouldn't crash a core - or at least there should be an easier approach.

Re: I2C: protection against connection (lines) problems

Posted: Thu Mar 23, 2017 6:49 pm
by Hans Dorn
I2C isn't very fault tolerant on the electrical level. It only takes a power supply glitch or something similar to take a device offline for an instant. The I2C master must be able to handle this without hanging.

Deliberatly interrupting the connection is a good test for eventual troubles lying in your future. If your system can't handle a temporarily broken connection, you don't want to ship it...


Cheers

Re: I2C: protection against connection (lines) problems

Posted: Thu Mar 23, 2017 8:42 pm
by KanyeKanye
Exactly. Dynamic replugging is not a point, but any EM deviation on a line mustn't cause a core panic

Re: I2C: protection against connection (lines) problems

Posted: Thu Mar 23, 2017 9:23 pm
by Hans Dorn
I can confirm that unplugging an I2C line a couple of times will break I2C, and make my little test system grind to a standstill.
(Cycle time increases from 14 to 320ms).

I'm using unmodified arduino libs for I2C and a PCF8574 at the moment, will try to look into it.

Cheers

Re: I2C: protection against connection (lines) problems

Posted: Fri Mar 24, 2017 1:07 am
by Hans Dorn
Didn't have much luck trying to resolve this in software.

"i2cResetFiFo" or "i2cInit" from esp32-hal-i2c won't fix the problem,

and "i2cInitFix" will hang, because it contains a while loop without timeout.

Is there a software way to bring the I2C peripheral into the same state it has after resetting the ESP32?


P.S:

For the moment I'm pulling down the ESP32 reset pin via software when I see I2C_ERROR_TIMEOUT or I2C_ERROR_BUS,
but I'd rather do this more elegantly :P

Re: I2C: protection against connection (lines) problems

Posted: Fri Mar 24, 2017 7:33 pm
by Hans Dorn
I found a way to reset and restart the I2C periphal in case of I2C errors.
Well... most of the time, actually. See below

Code: Select all

	// Disable clock for I2C peripheral #0
	CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT0_CLK_EN);
	//reset peripheral
	SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT0_RST);
	i2c = i2cInit(0, 0, false);
	i2cSetFrequency(i2c, 100000); 
The PERI_REG writes do the inverse of what i2cinit does to bring up the i2c peripheral


Problems:
If I pull and reconnect the I2C wires often enough, the above will fail to work and the ESP32 hangs

The same thing actually happens when I pull down the ESP32 reset pin via software instead.
After the ESP gets stuck, it takes more than one push on the RESET button to bring it up again.

I'll add an arduino to my project to babysit the ESP and bring it back up in case it gets stuck...

Re: I2C: protection against connection (lines) problems

Posted: Fri Mar 31, 2017 9:24 pm
by KanyeKanye
[Up]