0
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ Also, the datasheet makes a point of "No bus-stalling or clock-stretching during transactions" feature, meaning the sensor should work smooth... if master follows the rules, of course. It has extensive info on timing requirements. Did you follow all the guidelines? Especially "bus free time" and a possibility for device to reply NACK when in transition between states. \$\endgroup\$ – Maple Nov 29 '19 at 10:45
  • \$\begingroup\$ Yes, I made the firmware according to the directions given in the datasheet. I guess the slave will not even ACK once if there is a timing issue with the system. The Slave is responding very well for some time after powering up. The time when bus gets locked up is totally random. That may happen after one minute,1 hour or it may even run without any issues for indefinite time. I still don't know the cause. \$\endgroup\$ – KKSjunior Nov 29 '19 at 11:52
  • \$\begingroup\$ You'll either need to have a path to do a hardware reset of the peripheral (if such is even possible) or else need to identify the set of conditions causing this and avoid them. Some sort of automated fuzzing combined with a test for this stuck condition might be worthwhile to see if you can come up with a repeatable cause. Also check for known errata and get in touch with the vendor applications engineers. If at all possible, chose non-blocking modes where you trigger a reading and come back later to poll the results, rather than any that stall until done. \$\endgroup\$ – Chris Stratton Nov 29 '19 at 14:45
  • \$\begingroup\$ How does "continuously reading data" work? You cannot read data indefinitely. At some point you have to send stop condition and reset data pointer. And most important, each operation must begin with address and repeat start condition until slave ACKs. Most of the MCU firmware libraries I've seen do not support this behavior out of the box. Finally, you should use HI feature to read sensor only when necessary, not polling the same data over and over again. \$\endgroup\$ – Maple Nov 29 '19 at 16:20
  • \$\begingroup\$ @Maple By "Continuously reading data" I meant that I'm executing the read sequence multiple times with proper START & STOP conditions and timings. Let me check about the HI feature you're telling. \$\endgroup\$ – KKSjunior Nov 30 '19 at 5:12
1
\$\begingroup\$

Looks like this was something to do with my master MCU (NXP MKE04Z64). I dug a bit deeper into the old NXP forums and found out that a lot of people had the same problem of I2C bus lock-up from the Kinetis E Series MCUs and NXP hasn't responded to it yet. Maybe something's wrong with the chip design. I tried GPIO bit-banging the same slave instead of using the I2C module and the issue was solved. Also I tried driving the same slave from another MCU where it worked very well.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.