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!

Related