I have a problem with K22 and I2C communication.
I am using K22 as master in a I2C bus with two sensors (both are slaves). I am using KSDK_MK22FA12 v2.3 and I2C blocking.
My problem is that, after some hours (or days) running propperly, the I2C fails, the watch dog is activated and the K22 reboots. The problem is that the SDA lines go LOW when K22 is trying to read data from the slave (you can see the image when the problem occurs, when the SDA line is LOW). This occurs in the execution of I2C_MasterTransferBlocking.
I have tried to delimit the problem removing one of the sensor from the bus, but the problem remains. The difference is that the K22 is more time runnning propperly, but, finally, the problem appears.
- K22 reads the data from the sensor each 30 ms.
- The sensor is si1153 (proximity and luminosity).
- I am not sure because this kind of test are very long, but I think that, if I compile without NDEBUG symbol, the problem disappears.
Does anyone know something?
I had a hardware problem, related to EMC (Electromagnetic Compatibility). Enablig the glitch filter in SDA and SCL, the problem is solved.
Hi Stephen, thank you so much for your reply.
Unfortunately I lost the capture, I only have that picture so I can't do zoom. Right now I am trying to get the fail again. The relation between INT and the I2C transaction is the following: when Si115x have new measurements it go LOW the INT pin to notify this fact to the K22. After that, the K22 read, using I2C, this new measurements. As we can see in the picture, the K22 has tried to read although the Si115x hasn't notify it using INT, and, after that, the I2C dies. I have modify my program to try to read a lot of measurements from the Si115x athough it hasn't notify anything and it isn't a problem, only, the measurements are not valid but the I2C doesn't die. I am thinking that maybe in the picture we have a wrong behaviour of the I2C module, it dies and in Saleae we only see noise while it is dying.
"can you check the power supply to the sensor (using an analogue channel / scope) to see if there is any relationship between power dips and bad behaviour". We can see in the picture that the power isn't a problem. The last channel ("3.3 sensores") is the analog measure of the sensor supply and we see that it is constant (there are some small downs and it occurs when the sensor go low the INT pin).
"You could consider increasing the poll rate from 30ms to something less, to try to reduce your testing time." Yes, that is a possibility but I think that it won't solve the problem, it only will decrease the possibility of fail. We have other micro (KL26) using this sensor in the same way and we haven't problems.
I am trying to catch the problem again, I will update with new pictures.
Than you again.
Hello Raul Arenaz
Another suggestion I have that may be useful is to use the i2c dead-lock recovery.
The master should send nine clock pulses. The device that held the bus low should release it sometime within those nine clocks.
What you need to do is to switch SCL and SDA lines to GPIO output and input respectively.
Then you generate clock cycles at the same frequency as is normally used.
Please check the below community thread, I believe it can be helpful for you.
Let me know if this is helpful.
Hi Omar Anguiano.
I have been studying your solution and it sounds really useful, maybe this method could recovery the I2C module properly.
If it fails again and I can to get the fail before I finish my test, I will try to solve it using your suggestion.
Thank you so much Omar.
I had occasional device lock-up because of I2C related problems. What helped in my case was a combination of watchdog and I2C recovery: That way my LPC and Kinetis parts are working now for months without issues.
If you are interested, I have the code on GitHub. It is the same code (example for K22 and LPC845), and check for I2CLIB_ReleaseBus():
I hope this helps,
Hi Erich Styger.
My problem is that the I2C dies and, when K22 try to read the next information from the Si115x using the I2C, as I2C module has died (the DCA line is LOW), it can't communicate and the watch dog is activated, rebooting the K22 is. I have tried to increase the watch dog time, but it doesn't fix the problem.
Thank you so much for your code, I have been seeing that and I have a question: you only use I2CLIB_ReleaseBus() at the init in I2CLIB_Init()? How can this recover I2C if I2CLIB_ReleaseBus() isn't used when the problem appears?.
A few ideas:
* Can you zoom in on the capture at +60ms (i.e. the previous transfer that worked) so that we can see the relationship between INT and the I2C transaction? Do all good transfers have this relationship?
* The data sheet for the sensor says "For proper operation, the Si115x is expected to fully complete its Initialization Mode prior to any activity on the I2C" - can you check the power supply to the sensor (using an analogue channel / scope) to see if there is any relationship between power dips and bad behaviour.
* You could consider increasing the poll rate from 30ms to something less, to try to reduce your testing time.