esp-idf: [TW#13148] i2c timeout error
I’m polling a i2c device every half second and after a while (sometimes 4 minutes, sometimes half an hour). The i2c_master_cmd_begin function returns ESP_ERR_TIMEOUT, and every next call to i2c_master_cmd_begin returns ESP_ERR_TIMEOUT.
I tried deleting the driver using i2c_driver_delete and then i2c_driver_install but it keeps giving the error.
At this time the SDA line remains low and the SCL line remains high. I also tried to delete the driver and then change the pins to output and change to no avail.
The device I am communicating with is a battery monitor (LC709203F). But I have the same problem with an accelerometer.
init code
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_DISABLE;
conf.scl_io_num = I2C_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_DISABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
i2c_param_config(I2C_MASTER_NUM, &conf);
i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
communication code
int ret = 0;
uint8_t crc = 0, crc_read, valh, vall;
i2c_cmd_handle_t cmd;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( FG_SLAVE_ADDR << 1 ) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, command, ACK_CHECK_EN);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, ( FG_SLAVE_ADDR << 1 ) | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &vall, ACK_VAL);
i2c_master_read_byte(cmd, &valh, ACK_VAL);
i2c_master_read_byte(cmd, &crc_read, NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 20 (4 by maintainers)
@AmrutaCh You’ll need to modify
components/driver/i2c.c
…I’m not up-to-date with the latest version so I’ll just walk you through the change:In
esp_err_t i2c_param_config(i2c_port_t i2c_num, const i2c_config_t* i2c_conf)
there is an if block…something like:You’ll need to modify the
else
clause changingTo
That number was picked because, to the best of my knowledge, it’s the largest supported by the hardware.
That being said there is a “newer” function that may help:
i2c_set_timeout
When first introduced I found that it did not resolve my issue, but I should really give it another try.
I think I have the same problem but with a DS3231 / DS1307. The interesting thing is, that I have exactly your behavior using the ESP-IDF. But if I use the ESP-Arduino SDK (as a component in IDF) it works without any problems.