This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I2C gets stuck with -EBUSY if i2c_* function calls timeout on zephyr (NCS) for nRF52840

To reproduce this problemm Ive added a device to the I2C that does not respond to a read command.

The `i2c_read` call first returns `-EOI` (-5) and for every other i2c funcion calls it will return `-EBUSY` (-16).

Apparently it locks the i2c subsystem, a `sys_reboot` makes the i2c BUS available again.

I wonder if this is a known issue, and if there is a way of recovering the i2c subsystem? `i2c_recover_bus` is useless for this effect.



a similar issues were posted here:

https://devzone.nordicsemi.com/f/nordic-q-a/70481/what-means-errno--16-for-nrf52832/289628 
- https://devzone.nordicsemi.com/f/nordic-q-a/66928/zephyr-i2c-locked-into-ebusy

Parents Reply
  • I can confirm that the behaviour is the same for v1.4.0.

    For v1.3.0, it hangs forever on read. I guess this is due to some change/addition of a timeout code?

    The following is a short code to test (considering you have a device on the other end that doesn't write back):

     

    uint8_t r_buff;
    uint8_t w_buff = 0x02;
    
    const struct device *i2c1_dev;
    i2c1_dev = device_get_binding("I2C_1");
    
    while (true)
    {
    	r_buff = 0;
    	// Write something to device at 0x05
    	ret = i2c_write(i2c1_dev, &w_buff, 1, 0x05);
    	if(ret != 0) {
    		printk("error write: %d\n", ret);
    	}
    
    	// Read byte from device at 0x05, this is where it is problematic
    	// if the device doesnt write back
    	ret = i2c_read(i2c1_dev, &r_buff, 1, 0x05);
    	if(ret != 0) {
    		printk("error read: %d\n", ret);
    	}
    	printk("r_buff: %u\n", r_buff);
    	k_msleep(2000);
    }



    So far I've noticed that the bus gets stuck forever if:

    • i2c_read times out
    • i2c SDA and SCL are shorted for a short amount of time

    My main problem is not being able to recover the bus, If I was able to do that in runtime without resetting I could have that workaround. Is there any way I can do this in the meanwhile?

Children
Related