I was trying to develop a I2C driver function for reading data from a proximity sensor(Cypress CY8CMBR3102) and initially the function worked very well and successfully. But while continuously reading data from the device, the slave is holding the SDA line low and the bus arbitration flag is set in the MCU(NXP MKE04Z64). This is blocking all further communication.
I tried the following fix in my code but it didn't work out.
Every time I want to read from the device, I keep the I2C pins as GPIOs and check the level in the data bus.
The I2C module will be enabled only if the data bus is in high state.
If the Bus is held low, the SCL pin is clocked as a GPIO untill SDA is released by the slave.
When I tested the above fix in the device, the code is stuck in the loop where I clock the SCL pin until SDA turns high again. Which means clocking SCL is not helping in releasing the bus from the slave.
However if I unplug the slave or do a power reset, the bus is released since the slave is being reset.
I'm still unable to find the cause of this issue. I monitored the lines using a DSO and didn't find any significant noise in the lines.
1. What could be the possible reason for this bus lock-up?
2. How to detect and recover once the bus is locked up?
The details of our setup are as follows:
-> Single Master - Single Slave
-> Master - NXP MKE04Z64 Arm Cortex M0+
-> Slave - Cypress CY8CMBR3102 Capsense Proximity Controller
-> 400KHz I2C clock
-> MCU pins are open-drain with 4.7K external pull-ups.
-> Master and Slave are in separate boards interconnected with a 6cm long wire.