TWIM does not recover after pull‑up power domain is cycled with nRF54L15

Hi all,

I'm encountering an issue with the TWIM30 interface on the nRF54L15 (pins P0.03 - SDA, and P0.04 - SCL), using vanilla Zephyr v4.2.0-rc1.

The setup involves external I2C pull-ups powered through a separate power domain. Internal pull-ups are disabled. My intended flow is as follows:

  • Power up the domain to enable the pull-ups.

  • Perform the I2C transaction.

  • Power down the domain.

This works as expected under normal conditions. However, if I attempt an I2C operation while the pull-ups are unpowered (as expected, it fails), and then power the domain back on and retry the transaction, the I2C peripheral never recovers. All subsequent transfers fail unless I reboot the MCU.

Upon debugging, I found that the completion_sync semaphore is never released after this fault condition, and we always get a timeout

ret = k_sem_take(&dev_data->completion_sync, I2C_TRANSFER_TIMEOUT_MSEC);
if (ret != 0) {
/* Whatever the frequency, completion_sync should have
* been given by the event handler.
*
* If it hasn't, it's probably due to an hardware issue
* on the I2C line, for example a short between SDA and
* GND.
* This is issue has also been when trying to use the
* I2C bus during MCU internal flash erase.
*
* In many situation, a retry is sufficient.
* However, some time the I2C device get stuck and need
* help to recover.
* Therefore we always call i2c_nrfx_twim_recover_bus()
* to make sure everything has been done to restore the
* bus from this error.
*/
(void)i2c_nrfx_twim_recover_bus(dev);
ret = -EIO;
break;
}


It seems the TWIM driver enters a bad state after the failed attempt and does not properly recover even when the electrical conditions are restored and recover function is called.

Any help would be appreciated, thanks in advance!

Parents
  • Why do you turn off the power domain where the pull ups are connected? I2C idle state is high, so no current will flow when the I2C is not in use. 

    If the other power domain has a different voltage than the nRF54L15's supply voltage, this is not the way to do it, you need level shifters instead. 

  • Thanks for your reply! Good point regarding the power domain being connected to the pull-ups, it's indeed unnecessary Slight smile

    The same domain is also connected to the external sensors, so I need to drive it low/high to save power regardless. And of course in our use case we won't have a situation where firmware is attempting an i2c operation when the power domain is off.  Nevertheless, even if the power is always on, accidental shorting of SCL line can still happen (especially during cert tests), and I would expect the interface to recover without rebooting the firmware. 

  • van.petrosyan said:
    Nevertheless, even if the power is always on, accidental shorting of SCL line can still happen (especially during cert tests), and I would expect the interface to recover without rebooting the firmware. 

    True, but this is different from floating. In case the I2C lines are not clearly defined high or low, the interface can fail. Best to have the lines always defined high when not in use. Then you can safely remove power to the slaves on the interface. 

Reply
  • van.petrosyan said:
    Nevertheless, even if the power is always on, accidental shorting of SCL line can still happen (especially during cert tests), and I would expect the interface to recover without rebooting the firmware. 

    True, but this is different from floating. In case the I2C lines are not clearly defined high or low, the interface can fail. Best to have the lines always defined high when not in use. Then you can safely remove power to the slaves on the interface. 

Children
No Data
Related