I2C clock is not generate reliably after clock stretch
Posted: Mon May 15, 2023 4:01 pm
Hello,
After my slave device stretches the clock before a 'master read' operation, SCK is not generated reliably.
The issue is intermittent, and only seems to occur once is ~100 transactions. I have only spotted the issue after a clock stretch.
It looks like the master is not generating the clock. Other times it does generate the clock in this period.
Each time this occurs, the I2C driver returns the error: ESP_ERR_TIMEOUT
Below are some screenshots from a scope on the clock and data lines.
Does this look like an issue with what I have done, or is this an issue with the I2C hardware on the master? Is this a bug, or an issue with what I am doing?
Detailed information:
I am using an ESP32-wrover and communicating with an RRC1120 battery pack.
Clock speed: 100kHz
IDF version: 4.4 (f31b5c3bd2)
Bus voltage: 3.3V
Pull up resistors: 4k7
The code that calls a read looks like this (small excerpt - can provide more if needed):
After my slave device stretches the clock before a 'master read' operation, SCK is not generated reliably.
The issue is intermittent, and only seems to occur once is ~100 transactions. I have only spotted the issue after a clock stretch.
It looks like the master is not generating the clock. Other times it does generate the clock in this period.
Each time this occurs, the I2C driver returns the error: ESP_ERR_TIMEOUT
Below are some screenshots from a scope on the clock and data lines.
Does this look like an issue with what I have done, or is this an issue with the I2C hardware on the master? Is this a bug, or an issue with what I am doing?
Detailed information:
I am using an ESP32-wrover and communicating with an RRC1120 battery pack.
Clock speed: 100kHz
IDF version: 4.4 (f31b5c3bd2)
Bus voltage: 3.3V
Pull up resistors: 4k7
The code that calls a read looks like this (small excerpt - can provide more if needed):
Code: Select all
i2c_master_start(cmd.ch);
i2c_master_write_byte(cmd.ch, (RRC1120_ADDR << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd.ch, start_addr, true);
i2c_master_start(cmd.ch);
i2c_master_write_byte(cmd.ch, (RRC1120_ADDR << 1) | I2C_MASTER_READ, true);
i2c_master_read(cmd.ch, cmd.rx_buf, len - 1, I2C_MASTER_ACK);
i2c_master_read_byte(cmd.ch, cmd.rx_buf + (len - 1), I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd.ch);
i2c_master_cmd_begin(WLM_I2C_PORT, cmd.ch, 500 / portTICK_PERIOD_MS);