-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[TW#13148] i2c timeout error #680
Comments
Maybe this could be related to espressif/arduino-esp32#349 . I've noticed similar things when I poll some I2C-GPIO-Expander every 20ms. At some point the request will either always fail or just lock up. |
debugging a bit more it seems something locks up the lines. I tried disconnecting the device but the lines remain in their locked state. This is really frustrating as the only solution seems to be to reset the device when this happens. But that means data loss since we use the esp32 to measure sensors continuously and report this data to the cloud. Edit: This time during debugging both SCL and SDA remain low... |
Also this kind of problem seams to be noticed in the forum:
I would guess this more widespread than one may think. |
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. |
+1. |
Weird, is there a soft reboot during reading the I2C slave? |
Nop, there is no soft reboot (until i force it) |
I have no problem with I2C and MPU6050, even i can polling every 20ms, but im having problem with mcp23017. |
The patch will be merged into master branch soon |
@costaud how did you fix it? Can we already see the fix on master?
Am 18.10.2017 04:34 schrieb "costaud" <notifications@github.com>:
… The patch will be merged into master branch recently
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#680 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AC_DS7uqY_KVwjNpkpc20taPWvw1ba9Mks5stWO7gaJpZM4Nz80L>
.
|
The state machine of I2C bus could be dead if the bus is influenced in some circumstance(for example, short the sda/scl to gnd for a while). The hardware would get stuck and be always sending clock on scl or only sending a single pulse on scl. We can only reset the I2C hardware to get the hardware back working. To reset the hardware, we can call periph_module_disable then periph_module_enable, but all the register settings will be lost. We will try to merge this patch ASAP. In the next version of chips, we will find some way to void this situation. |
Reported from different sources from github or bbs: #680 #922 We tested reading several sensor or other I2C slave devices, if the power and SDA/SCL wires are in proper condition, everything works find with reading the slave. If we remove the power supply for the slave during I2C is reading, or directly connect SDA or SCL to ground, this would cause the I2C FSM get stuck in wrong state, all we can do is the reset the I2C hardware in this case. After this commit, no matter whether the power supply of I2C slave is removed or SDA / SCL are shorted to ground, the driver can recover from wrong state. We are not sure whether this the save issue with the reported one yet, but to make the driver more robust. Further information: 1. For I2C master mode, we have tested different situations, e.g., to short the SDA/SCL directly to GND/VCC, to short the SDA to SCL, to un-plug the slave device, to power off the slave device. Under all of those situations, this version of driver can recover and keep working. 2. Some slave device will die by accident and keep the SDA in low level, in this case, master should send several clock to make the slave release the bus. 3. Slave mode of ESP32 might also get in wrong state that held the SDA low, in this case, master device could send a stop signal to make esp32 slave release the bus. Modifications: 1. Disable I2C_MASTER_TRAN_COMP interrupt to void extra interrupt. 2. Disable un-used timeout interrupt for slave. 3. Add bus reset if error detected for master mode. 4. Add bus clear if SDA level is low when error detected. 5. Modify the argument type of i2c_set_pin. 6. add API to set timeout value 7. add parameter check for timing APIs
I am facing the same issue with I2C example provided in idf.
The slave is an Arduino device. ESP-idf version: v3.1 init
read data from slave
|
I can confirm this error still exists...I Incorporated the one-line
fix/cludge into a local fork of the esp-idf repo and keep track of it that
way.
…On Mon, Apr 22, 2019, 8:28 AM Amruta ***@***.***> wrote:
I am facing the same issue with I2C example provided in idf.
ESP32 Arduino works as expected whereas esp-idf gives the following errors
- timeout : 0x107 (generated by I2C_STATUS_TIMEOUT)
- failed: -1 (generated by I2C_STATUS_ACK_ERROR)
The slave is an Arduino device.
ESP-idf version: v3.1
Code:
#include <stdio.h>
#include "driver/i2c.h"
#define I2C_EXAMPLE_MASTER_SDA_IO 22 /*!< gpio number for I2C master data */
#define I2C_EXAMPLE_MASTER_SCL_IO 23 /*!< gpio number for I2C master clock */
#define I2C_EXAMPLE_MASTER_NUM I2C_NUM_0 /*!< I2C port number for master dev */
#define I2C_EXAMPLE_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_EXAMPLE_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_EXAMPLE_MASTER_FREQ_HZ (10 * 1000) /*!< I2C master clock frequency */
#define DATA_LENGTH 1 //18 /*!<Data buffer length for test buffer*/
#define I2C_SLAVE_ADDR (8) /*!< ESP32 slave address, you can set any 7bit value */
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
static esp_err_t i2c_example_master_read_slave(i2c_port_t i2c_num, uint8_t *data_rd, size_t size)
{
esp_err_t err = ESP_OK;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (I2C_SLAVE_ADDR << 1) | READ_BIT, ACK_CHECK_EN);
if (size > 1)
{
i2c_master_read(cmd, data_rd, size - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
i2c_master_stop(cmd);
err = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return err;
}
static void i2c_example_master_init()
{
int i2c_master_port = I2C_EXAMPLE_MASTER_NUM;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_EXAMPLE_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = I2C_EXAMPLE_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_EXAMPLE_MASTER_FREQ_HZ;
esp_err_t err = i2c_param_config(i2c_master_port, &conf);
if (ESP_OK == err)
{
err = i2c_driver_install(i2c_master_port, conf.mode,
I2C_EXAMPLE_MASTER_RX_BUF_DISABLE,
I2C_EXAMPLE_MASTER_TX_BUF_DISABLE, 0);
printf("i2c_driver_install 0x%x \n", err);
}
else
{
printf("i2c_param_config fail 0x%x \n", err);
}
}
static void i2c_test_task(void *arg)
{
uint8_t data_rd[DATA_LENGTH] = {0};
int cnt = 0;
esp_err_t ret = 0;
while (1)
{
printf("cnt: %d\n", cnt++);
vTaskDelay(100 / portTICK_RATE_MS);
ret = i2c_example_master_read_slave(I2C_EXAMPLE_MASTER_NUM, data_rd, DATA_LENGTH);
if (ESP_OK == ret)
{
data_rd[DATA_LENGTH] = 0;
printf("Data: %s \n", data_rd);
}
else
{
printf("err: 0x%x %s \n", ret, esp_err_to_name(ret));
}
}
}
void app_main()
{
i2c_example_master_init();
xTaskCreate(i2c_test_task, "i2c_test_task_1", 1024 * 5, (void *)1, 10, NULL);
}
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#680 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABUPXOUKJFB6TDUTDA57XXLPRWVPBANCNFSM4DOPZUFQ>
.
|
@arsinio can you share the changes which are working for you? |
More details: On Arduino slave side, it gives |
@AmrutaCh In
You'll need to modify the
To
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: When first introduced I found that it did not resolve my issue, but I should really give it another try. |
Thanks @arsinio |
Hi I tried to read SHT20 registers with I2C tool with "i2cget" command, but it has error |
Hi |
I couldn't solve this problem, but with a program that I wrote myself based on the SHT20 datasheet, it worked easily. I also used a DS1307 module with the i2c tool, which worked properly as well. I was able to read and write to the registers perfectly. I think in some i2c devices, there's a need for a short response time for the device to respond and send data, which hasn't been considered in the i2c tool code. |
Also having the same issue in v5.2.2, having said that I'm using the legacy driver I think. I will git it a go with the new driver in i2c_master.c |
I defaulted to using v5.1.4, (legacy driver) hybrid approach. Port 0 on IDF and port 1 in Arduino wire function! |
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
communication code
The text was updated successfully, but these errors were encountered: