Affected SDK: nRF Connect SDK v3.2.0 (Zephyr v4.2.99)
File: zephyr/drivers/i2c/i2c_nrfx_twi.c
Description
The I2C TWI driver always returns -EIO for every transfer, even when the transfer completes successfully. This is caused by a mismatch between the value set in the event handler and the value checked in the transfer function.
Root Cause
In the event handler (event_handler), on successful completion:
case NRFX_TWI_EVT_DONE:
dev_data->res = 0; // Sets res to 0
break;
In i2c_nrfx_twi_transfer(), the success check is:
if (data->res != NRFX_SUCCESS) {
ret = -EIO;
break;
}
However, NRFX_SUCCESS is defined in nrfx_errors.h as:
#define NRFX_ERROR_BASE_NUM 0x0BAD0000
NRFX_SUCCESS = (NRFX_ERROR_BASE_NUM + 0), // = 0x0BAD0000
So the comparison 0 != 0x0BAD0000 is always true, causing every I2C transfer to fail with -EIO.
Impact
- All I2C devices using the nordic,nrf-twi compatible driver fail to communicate
- This affects any board using TWI (not TWIM) for I2C
Proposed Fix
Change line 112 in i2c_nrfx_twi.c from:
dev_data->res = 0;
to:
dev_data->res = NRFX_SUCCESS;
Alternatively/Additionally, NRFX_SUCCESS should be defined as 0.
How to Reproduce
- Use nRF Connect SDK v3.2.0
- Configure I2C with compatible = "nordic,nrf-twi"
- Attempt any I2C transfer
- Observe that all transfers return -EIO (-5)
Environment
- nRF Connect SDK: v3.2.0
- Zephyr: v4.2.99
- Target: nRF52840