-
Notifications
You must be signed in to change notification settings - Fork 8k
Description
Describe the bug
The DW I2C controller can implement a reception FIFO as deep as 256 bytes.
However, the computation made by the driver code to determine how many bytes can be asked is stored in a signed 8-bit variable called rx_empty.
If the reception FIFO depth is greater or equal to 128 bytes and the FIFO is currently empty, the rx_empty value will be 128 (or more), which stands for a negative value as the variable is signed.
Thus, the later code checking if the FIFO is full will run while it should not and exit from the i2c_dw_data_ask() function too early.
This hangs the controller in an infinite loop of interrupt storm because the interrupt flags are never cleared.
To Reproduce
Steps to reproduce the behavior:
- Get a board having a DW I2C controller with FIFO depth greater or equal to 128.
- Read I2C data over the bus and add a breakpoint to the i2c_dw_data_ask() function, when the rx_empty value is computed (https://github.com/zephyrproject-rtos/zephyr/blob/a6eef0ba3755f2530c5ce93524e5ac4f5be30194/drivers/i2c/i2c_dw.c#L220C3-L220C3).
- You will see that the computed rx_empty value is negative, so the function immediately returns and does not service the interrupts.
Expected behavior
The I2C controller should correctly receive the data.
Impact
This is a showstopper because it triggers an i2C interrupt storm because I2C interrupts are never handled.
Logs and console output
None available.
Environment (please complete the following information):
- OS: Linux
- Toolchain: Zephyr SDK
- Commit SHA or Version used: v3.5.0 (commit a6eef0b)
Additional context
This bug has already been fixed on mainline (see #66685).
I was asked by the Zephyr maintainers to file a bug for this issue.