Hi Freescale community,
I use Kinetis Design studio 2.0.0, MQX KSDK 1.0.0 with Processor expert, (uc MK64F),
I realized I2C communication using I2C1 as Master. It seems that the I2C driver MQX KSDK 1.0.0 is not stable, so I adapt the 1.2.0 I2C driver for working with all of the rest of MQX KSDK 1.0.0.
I talk with a PSU in a Task every 400ms, it works fine during a variable time (about 30 sec or 15 min) but after the I2C crash and only a software reset allow to restart the communication.
I take a screenshot when it works fine :
And a screenshot when the bus crash :
Why after the repeated start, only one clock was sent ? Whats the problem ?
An another screenshot when the bus crash :
Can you help me ?
thanks,
Solved! Go to Solution.
Hello Pierre,
It fails with (2) and (3), but works OK in case (1). This implies that you should be looking at hardware issues with the I2C buffer instead of the software issue.
I am not familiar with using this kind of buffer in an I2C bus, but let me ask around and if I get some idea I will let you know.
Regards!
Jorge Gonzalez
Hello PE TAPIE:
In your pictures I notice that the low level in SDA and SCL lines does not go all the way to '0' volts (or close), except for the acknowledge bit. Have you enabled the Open Drain configuration for both pins in the K64? If open drain is not enabled this could cause transmission issues.
Also, from your last 2 screenshots I think the slave holds down the clock line. This leads me to think that the problem is in the slave side. Maybe the frames are sent too fast or the slave requires warm times between transmission, or getting stuck because of an internal error, etc, there could be several reasons. Give a check to the slave specifications and try reducing the I2C frequency and/or adding delays between transfers.
I also highly recommend you to upgrade to the latest versions of the tools: KSDK v1.2 and KDS v3.0.0.
Regards!
Jorge Gonzalez
Hi Jorge,
Thanks for your answer,
Open drain is enable for SDA and SCL pins, but there is an explanation for the low level. I use two P82B96TD for increase I2C level to 12V during the transmission for reduce noise impact. When I take the screenshots, I placed sensors on the side of the PSU (exactly there is 6 PSU on the I2C Bus). But the P82B96TD can provide a minimum low level of 0.8V. So on the screenshot, the low level provide by the slave is 0V (because it is not yet passed through the two P82B96TD) whereas the low level provide by the K64 is 0.8V.
I tried to reduce I2C frequency or add delays between transfert, but the problem still occurs.
You said : maybe the slave holds down the clock line, but if it's really the slave, we would see on the screenshot a low level to 0V (not 0.8V) no ?
I have an another screenshot when the I2C bus Crash :
zoom on the second 8 bits :
I don't understand the behavior of the uc, the slave give an acquittement one clock too early, ok, it's not really a problem, but why the I2C bus crash ?
Thank you for your help,
Regards
Hello PE TAPIE,
The early ACK could explain the problem. In your pictures when the ACK is sent on the 8th bit, the 9th bit is '1' (NACK). The KSDK I2C driver interprets any NACK as a failed transmission and immediately sends the STOP signal. I suppose that's what you mean with "the bus crash".
So, I still believe the issue is on the sensor side, maybe due to the I2C buffer (P82B96TD). If possible try connecting the sensors directly to the MCU, to discard a problem with the buffer.
Regards!
Jorge Gonzalez
HI Jorge,
Thanks for your answer,
On the last screenshot, the 9th bit is '1' NACK, the I2C driver interprets any NACK as a failed transmission, ok I agree with this. But on screenshot I don't see the stop signal, so I said "the bus crash" because after this frame, when I want to send another frames , the driver return "bus busy" and only a "deinit" and "init" of the I2C module can relaunch the communication.
Why the stop signal is not send ?
Could you explain the behavior after the 9th bit ? (indicate in the red circle on the following screenshot)
In addition, if we return on the second screenshot I posted :
On this screenshot there is no problem with "ack" but the bus crash and after this frame, the bus state is "bus busy" and I can't communicate.
Why the I2C module stop after send only one clock ?
Why during the clock stretching, the sda line go down and up ? (the 0.8V low level indicate that was the master at origin of this spike)
Thank you for your help,
Regards,
Pierre-Etienne TAPIE
Hello PE TAPIE:
The behavior is very hard to explain. It needs more debugging to see under what specific conditions the bus fails, e.g. MQX holding interrupts, master-slave synchronization/clock stretching issues, interrupt handling race conditions, etc.
If you can replicate this in a baremetal project then that would at least discard MQX has something to do. Another test is to comment out any extra code for other peripherals and just leave the I2C part. This should help tracking down the root cause.
Regards!
Jorge Gonzalez
Hi Jorge,
I tried three new methods to communicate with the slave :
1 : I tried to communicate directly with the PSU without using P82B96 I2C buffers, It works fine, there is no I2C problem. (I just change the software for used I2C0 instead I2C1 ).
2 : I created a new MQX KSDK project with only one task, to discard the others components. Its the same issue, the I2C bus crash after less than one minute.
3 : I created a new bare metal project, with only functions for communicate with the PSU. The bus crash after less than one minute, I took a screenshot :
I hope you could help me to find the root cause.
Thanks,
Regards,
Pierre-Etienne TAPIE
Hello Pierre,
It fails with (2) and (3), but works OK in case (1). This implies that you should be looking at hardware issues with the I2C buffer instead of the software issue.
I am not familiar with using this kind of buffer in an I2C bus, but let me ask around and if I get some idea I will let you know.
Regards!
Jorge Gonzalez