I have built a system with 2 MCUs communicating through I2C.
The NRF52 is I2C slave and the other MCU is master.
I have implemented a command style interface which sends commands to the NRF52 (I2C writes, TWIS RX) followed by a I2C read (TWIS TX). The NRF52 uses address 0x51.
The buffer for TWIS TX is prepared in the "NRFX_TWIS_EVT_WRITE_DONE" event function.
The first byte in the response indicates the length / status of the response. Now I have implemented a function in the I2C master MCU to first read only a single byte.
After reading this first byte the I2C bus is stopped. Then the I2C is directly started again and the full length message is read again. To be able to read the same buffer contents again, I implemented the TX prepare function also in the "TWIS_EVT_READ_DONE" event.
For most of the times, this implementation works. However, if the nRF52 CPU gets busy with SoftDevice interrupts (BLE connections / flash writing), the "TWIS_EVT_READ_DONE" event is not always triggered by the TWIS driver on the first read. In this situation the I2C hangs as TWIS peripheral hangs streching the clock waiting for the TX prepare function which never gets triggered. The "NRFX_TWIS_EVT_READ_REQ" event does get triggered, but since I do not know if the previous I2C transter was a read or a write, I cannot call the TX prepare function.
I am wondering whether this behavior is expected?
Attached is the TWIS register status, is it true there is no way for me to get the TWIS peripheral status/state? I can only see the events from the registers.
Also attached is a I2C transfer showing the second I2C read hanging up due to the missing "tx prepare" function.
Chip I am using is nRF52832 and I use nRF5_SDK_17.1.0_ddde560.
For the short term I will probably rewrite the I2C driver of the host MCU to allow for variable length reads without stopping and starting again. I think this will solve my problems.
But I am still interested if the missing "NRFX_TWIS_EVT_READ_DONE" events can be explained.
I2C Transfer:
TWIS register view: