Page 1 of 1

I2C Clock Flush

Posted: Wed Sep 06, 2023 6:01 am
by cnlohr
When using I2C, sometimes downstream devices are in the middle of a transaction when the ESP resets. This causes them to hold the SDA line low, while the SCL line is high, which apparently confuses the ESP I2C stack?

Is there a proper way to "flush" I2C transactions by toggling the clock line several times to get the bus back in a functional state?

Re: I2C Clock Flush

Posted: Wed Sep 06, 2023 6:24 am
by ESP_Sprite
I think that's because keeping SDA low means that another master possibly is attempting a transaction, and the I2C peripheral in the ESP32 should hold off. I don't think there's a way to fix this using the I2C peripheral, but you can simply configure the pins as (open-drain) GPIOs and give them a few clocks manually before you start.

Re: I2C Clock Flush

Posted: Wed Sep 06, 2023 6:38 am
by cnlohr
This is not an uncommon error state in a single-master system. If the host is reset at a bad time, i.e. when a slave was sending a 0 bit on the SDA.

Code: Select all

	int gpio_no = 41;
	// Shake any device off the bus.
	int i;
	for( i = 0; i < 16; i++ )
	{
		gpio_matrix_out( gpio_no, 256, 1, 0 );
		GPIO.out1_w1tc.val = (1<<(gpio_no-32));
		esp_rom_delay_us(3);
		gpio_matrix_out( gpio_no, 256, 1, 0 );
		GPIO.out1_w1ts.val = (1<<(gpio_no-32));
		esp_rom_delay_us(3);
	}
	gpio_matrix_out( gpio_no, 29, 0, 0 );
In case anyone wanted to lift some quick code "29" at the end is I2C0's SCL.

Re: I2C Clock Flush

Posted: Wed Sep 06, 2023 8:54 am
by MicroController
In fact, the I2C driver has that already (internally) implemented:
https://github.com/espressif/esp-idf/bl ... 44C1-L44C1

In some SoC's, the I2C peripheral can even do it in hardware (-> i2c_ll_master_clr_bus(...)).