LPI2C not releasing bus, STOP not sent

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

LPI2C not releasing bus, STOP not sent

1,685 Views
dmarples
Contributor IV

There appears to be a race bug in fsl_lpi2c.c in LPI2C_MasterStop / LPI2C_MasterCheckAndClearError whereby after the STOP command is added to the FIFO, if a NAK arrives then the STOP may be lost, resulting in the bus not being released. I think this patch addresses the issue;

diff --git a/devices/MIMXRT1021/drivers/fsl_lpi2c.c b/devices/MIMXRT1021/drivers/fsl_lpi2c.c
index 1ff3078..1267fff 100644
--- a/devices/MIMXRT1021/drivers/fsl_lpi2c.c
+++ b/devices/MIMXRT1021/drivers/fsl_lpi2c.c
@@ -248,8 +248,12 @@ status_t LPI2C_MasterCheckAndClearError(LPI2C_Type *base, uint32_t status)
         /* Clear the flags. */
         LPI2C_MasterClearStatusFlags(base, status);
 
-        /* Reset fifos. These flags clear automatically. */
-        base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
+        /* Reset fifos (Except for NAK, which doesn't generate a STOP automatically). */
+        /* These flags clear automatically. */
+        if (kStatus_LPI2C_Nak != result)
+          {
+            base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
+          }
     }
     else
     {
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Regards

DAVE

Labels (1)
0 Kudos
10 Replies

857 Views
p_shep
Contributor IV

Bump.

I'm finding this now with LPI2C version 2.3.0

The driver locks up in the ISR, continually running the state machine, and never setting *done or exiting with an error.

 

LPI2C_MasterGetFifoCounts() returns 4 in txCount, so ends up being 0 after the room is computed.

This means that the if (0U == txCount--) is true (as we wrap to -1), state_complete is set, the interrupt is not disabled, and we immediately re-enter it.

 

0 Kudos

850 Views
p_shep
Contributor IV

Alas, the above suggestion does not fix the issue I'm seeing.

Tags (1)
0 Kudos

848 Views
p_shep
Contributor IV

...However, I have got it to work by remove the NAK check in LPI2C_RunTransferStateMachine()

With the above code and also removing:

#if 0 /* NOTE: Removed this to fix NAK lockup */
    /* For the last byte, nack flag is expected.
       Do not check and clear kLPI2C_MasterNackDetectFlag for the last byte,
       in case FIFO is emptied when stop command has not been sent. */
    if (handle->remainingBytes == 0U)
    {
        status &= ~(uint32_t)kLPI2C_MasterNackDetectFlag;
    }
#endif

The bus seems to be behaving itself.

0 Kudos

1,517 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Dave, 

Thanks for the feedback! I was wondering if you could share an example code that I can use to reproduce the behavior you mentioned on my RT1020-EVK? 

Regards, 

Victor 

0 Kudos

1,517 Views
18362881285
Contributor II

Hi,I also found the question,when i debug LPI2C,to read a byte data from chip register,excute MCU_IO_I2C_Master_Tx(&buffer[0],1);
MCU_IO_I2C_Master_Rx(&buffer[1],1);when MCU_IO_I2C_Master_Tx(&buffer[0],1) excuted finished,the bus will not being released,the SCL will always keeping low,and always return busying.so MCU_IO_I2C_Master_Rx(&buffer[1],1)can't excute,and i can't read data.buffer[0] is device address,buffer[1] is received buffer.Using it wrong?

0 Kudos

1,517 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi, 

I'm not sure I understood you correctly so please correct me if I'm wrong. When the function MCU_IO_I2C_Master_Tx finishes the bus is not being released? Are you able to reproduce this behavior with an example of our SDK? 

Best Regards, 

Victor 

1,517 Views
dmarples
Contributor IV

Just try and write a zero-content-length message to a device that's not present. You'll see clock stay low and data return high.

Regards

DAVE

0 Kudos

1,517 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hello Dave,

 

By zero-content-length message, do you mean sending a message with only zeros and where the length doesn’t matter?

 

Regards,

Victor

0 Kudos

1,517 Views
dmarples
Contributor IV

Just send a read or write with no bytes following to a device that isn't present. The common way to trigger the problem is by querying for all devices on the bus and seeing which ones ack you.

Regards

DAVE

0 Kudos

1,517 Views
victorjimenez
NXP TechSupport
NXP TechSupport

Hi Dave, 

Thanks for clarifying,  I will provide the feedback to the SDK team. 

Regards, 

Victor 

0 Kudos