LPI2C occasional missing clock pulse on address ACK bit when using LPI2C_RTOS_Transfer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPI2C occasional missing clock pulse on address ACK bit when using LPI2C_RTOS_Transfer

1,006 Views
transistor32
Contributor III

I'm using FreeRTOS on MIMXRT117F on a complex design with multiple tasks.

I'm having a problem with I2C. Occasionally, the I2C bus will lock up and it is necessary to power cycle the device to restore operation. It could take several hours or it could take half an hour to happen after turning it on, it varies. The SDA line is stuck low when the problem happens.

I have connected a logic analyzer and this shows that the final SCL pulse on the ACK bit is missing, so the slave device is continuously driving the ACK bit expecting another clock pulse. Manually pulling the SCL line to GND with a jumper wire releases the SDA line.

transistor32_0-1689338119104.png

The LPI2C_CheckForBusyBus function reports error code 900 (kStatus_LPI2C_Busy) once the problem appears and using the method described above to release the SDA line doesn't clear it, nor does setting the Software Reset bit in the Master Control register using a debugger, which seems odd, but that means that at present the only way to recover is to reset the MCU.

The signal integrity of the I2C signals is very good so I am confident that it is not a pull-up resistor issue.

What can cause this issue and how can I debug it to find the cause?

Labels (1)
0 Kudos
6 Replies

936 Views
EdwinHz
NXP TechSupport
NXP TechSupport

Hi @transistor32,

It is very likely that the complexity of the tasks you are executing are causing the faulty behavior you are seeing on the I2C Bus. Have you tried using the I2C without any other tasks? This to ensure that the issue is software related, rather than HW. If the HW is OK, then the next thing to check would be the priorities. Finally, a work around could be to use a GPIO pin as SCL instead of the native one, to ensure the missing clock pulse for the ACK and force the bus to a non-busy state.

BR,
Edwin.

0 Kudos

867 Views
transistor32
Contributor III

Hi @EdwinHz,

I have disabled the other tasks that use the same I2C bus and there was no improvement.

I have tried the solution of changing the IO mux of the SCL pin to a GPIO, toggling it to free up the bus, then switching it back to the I2C peripheral. Whilst this does free up the bus, this is very dangerous, as if the master stopped transmitting the clock at certain times, pulsing the SCL pin without controlling the SDA pin will result in an unexpected I2C write to a slave device, resulting in data being overwritten.

0 Kudos

849 Views
EdwinHz
NXP TechSupport
NXP TechSupport

Hi @transistor32,

The work around I mentioned about using a GPIO instead of the SCL would have to be permanent (i.e. no switching between GPIO and SCL) precisely because it could cause unwanted transmissions and therefore corrupt the data. That said, I am not able to replicate your issue with the freertos_lp2ic_cm7 example project we provide on the SDK. I highly suggest you to base your i2c implementation on the one seen on this example project.

BR,
Edwin.

0 Kudos

758 Views
transistor32
Contributor III

Hi @EdwinHz,

After spending some time adding resistors to the SDA lines going to each device from the I2C bus, I found that one of the devices on the bus is holding it down low and therefore this does not appear to be an LPI2C issue. I added a DIP switch to the bus on the SCL and SDA lines to the offending IC and if I disconnect it once it is configured, the problem does not occur.

The offending chip is a SN65DSI83 which converts the MIPI output from the iMX to LVDS. When running the demos, this chip would not be configured or processing any video, and the problem didn't happen. It looks like this is not an NXP problem (unless the iMX clocks/PLL are interfering somehow) but since I have a spare LPI2C peripheral that is unused on the iMX, I can put the SN65DSI83 on its own dedicated LPI2C bus which should work around the problem.

0 Kudos

787 Views
transistor32
Contributor III

Hi @EdwinHz,

Thank you for your continued support. I have been running the freertos_lpi2c_cm7 example on my board, modified to run in a continuous loop, and it has not failed after running for over 24 hours.

I have also been running the lpi2c_polling_b2b_master_cm7 example, modified to read from the most problematic slave device on the bus, and that has also not failed after running for over 24 hours.

I am still unable to understand how, on my own project, the LPI2C peripheral can just stop transmitting halfway through a transmission via a software bug, so my next idea is that there could be a different fault with my board and that the I2C transmission stopping is merely a symptom. My project uses more features of the chip than those examples, in particular the video output and the SDRAM, so any problems with those will affect my project but not the example projects.

My problem also happens a lot more frequently on some of my boards than others, which again suggests it could be a hardware issue. (The board I'm using for my testing is one where it happens frequently)

Could the cause be SDRAM related? Is there a good SDRAM test example available? My board has the same SDRAM as the evaluation board but the pair of SDRAM chips is rotated 90 degrees compared to the evaluation board so one is about 30mm further away from the iMXRT1170 than the other, whereas on the evaluation board both the chips are the same distance away from the NXP chip. The signal integrity of my board's routing may therefore not be as good as the evaluation board.

Can insufficient or incorrect decoupling capacitors cause it?

0 Kudos

925 Views
transistor32
Contributor III

Hi @EdwinHz,

Thanks for you reply.

I have implemented the SCL line toggle workaround, however I found that this would cause unexpected slave register addresses to be written to. This is because the the transmission doesn't always fail at a byte boundary; sometimes it will fail halfway through a byte as shown in this screenshot, and if the 'i2c rescue' function changes the SCL pin to a GPIO and toggles it to free up the bus, a write to an unexpected address will be completed.

transistor32_0-1689946179912.png

I will see if I can disable some tasks and if that makes the problem go away.

I am using the LPI2C RTOS functions, so I would have thought that the mutex and semaphore would have prevented multiple tasks becoming an issue. A cursory glance at the analyzer record suggests that the fault does not occur due to a clash between different tasks which each communicate with their own device on the I2C bus at different intervals.

0 Kudos