LPI2C bus stuck if NACK received

cancel
Showing results for 
Search instead for 
Did you mean: 

LPI2C bus stuck if NACK received

859 Views
nxf47370
NXP Employee
NXP Employee

Hi, everyone,

I am supporting customer CA on LPI2C, and  found LPI2C will be stuck( SDA and SCL are hold low) with baudrate 100KHz when a NACK is received after writing an incorrect address to slave node. And I use PD driver API LPI2C_DRV_MasterSendDataBlockingdata() to send data, and the phenomenon only occurs when set SDK optimization level -O1 which is default setting. I test the issue using our SDK RTM3.0.0 demo project named "lpi2c_master_s32k144", the IDE is S32DS.ARM.2018.R1 and the EVB is S32K144EVB-Q100 with part number 700-29248 Rev A.  I suspected it maybe a SDK bug, because i also test the phenomenon with baudrate of 400KHz with different optimization (-O0 and -O1), SDA and SCL are all release after NACK received. 

According to the section 3.1. 6 in I2C-bus specification and user manual, it will lead to generate a NACK when no receiver is present on the bus with the transmitted address, so there is no device to respond with an acknowledge. In order to generate NACK, i use one S32K144 EVB as master and another as slave, and master send incorrect address to slave node. The following two images are I2C bus timing sequence, respectively corresponding to different optimization image Optimization Level None(-O0) and Optimization Level Optimize(-O1) and baudrate is 100KHz. 

 tek00122.png

   image 1.  Optimization Level None(-O0)

tek00121.png

   image 1.  Optimization Level Optimize(-O1)

Could anybody help check whether it is a SDK bug? 

And the attach is test demo project.

Thanks,

Han Niu

Labels (1)
Tags (3)
0 Kudos
12 Replies

541 Views
__invited__ali3
NXP Employee
NXP Employee

Hello Han,

 

Sorry for my late response.

 

The problem seem to appear only when the internal pull ups are used. I recommend using external pull-up resistors of 4.7KOhm for each line, as the internal ones seems to be unfit for standard mode.

 

As you could see from the picture attached the SCL and SDA lines are high after NACK is received. Baud rate used was 100KHz and external pull-up resistors were used.

NACK_K146.png

 

Best regards,

Alina

0 Kudos

541 Views
nxf47370
NXP Employee
NXP Employee

Hi,  Alina,

Thanks for your response, and i referenced your recommendation and added external pull-up resistors of 4.7KOhm for each line, but it still be stuck after NACK received when Baud rate used was 100KHz. That is so strange, and do you use the optimization level of SDK for none or -O1?

Finally, could you check your SDK code i mentioned in last reply LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true), is it false or true for the third parameter which indicates sendstop generation?

Thanks, BR

Han

0 Kudos

541 Views
__invited__ali3
NXP Employee
NXP Employee

Hello Han,

 

Did you disabled the internal pull-ups of the SCL and SDA pins before using external ones?

 

I have checked the code. It's alright for the third parameter (sendStop) of LPI2C_DRV_MasterEndTransfer() to be 'false', because in case of NACK the hardware automatically generates stop.

 

We will run again the test, as it seems that the optimization level used was -O0, and I will come back with the results.

 

Best regards,

Alina

0 Kudos

541 Views
nxf47370
NXP Employee
NXP Employee

Hi,  Alina,

Yes, I disabled the internal pull-ups of the SCL and SDA pins before using external ones.

 

Thanks, BR

Han

0 Kudos

541 Views
__invited__ali3
NXP Employee
NXP Employee

Hello Han,

 

I think that it was indeed a problem in the RTM 3.0.0 release.

 

The issue is not reproducing with the latest driver code, which will be available in RTM 3.0.3 release. We have tested again, this time using -O1 optimization level, using gcc and ghs compliers,. The SCL and SDA lines were both high after receiving NACK.

 

Best regards,

Alina

0 Kudos

541 Views
__invited__ali3
NXP Employee
NXP Employee

Hello Han Niu,

 

Could you tell me more about the pin configuration you have? What kind of pull-ups are you using? I recommend using external pull-ups of 4.7KOhm for each line.

 

Does LPI2C_DRV_MasterSendDataBlocking function returns STATUS_I2C_RECEIVED_NACK in every situation you mentioned? Also, calling  LPI2C_DRV_MasterDeinit and then LPI2C_DRV_MasterInit after this function, brings the signals back to HIGH?

 

Finally, could you try without a slave connected to it? Without a slave, does the signals are still stuck LOW?

 

Best regards,

Alina  

0 Kudos

541 Views
nxf47370
NXP Employee
NXP Employee

Hi, Alina,

I use PTA2 pin as SDA, PTA3  pin SCL, and enable internal pull-up for the two pins configured as following image. I have not used external pull-ups fro each line.

 

pastedImage_2.png

pastedImage_1.png

I test it again and find that it will return STATUS_I2C_RECEIVED_NACK  in every situation you mentioned after the LPI2C_DRV_MasterSendDataBlocking() function, and when that happens I call LPI2C_DRV_MasterDeinit() to find the SCL and SDA can be back to high.

 

Finally, there is the same between  without a slave connected and with a slave.

Note: When NACK signal is received, it will jump into LPI2C_DRV_MasterIRQHandler() function, and in this function there is  LPI2C_DRV_MasterEndTransfer() to end current transfer where I set parameter sendStop to be true to generate STOP condition it will be back to high, however the default setting value is false. I wonder why the parameter  will have different effect  on different baudrate and different optimization level because it is exactly OK for different optimization -O0 and -O1 with baudrate 400KHz.

if (LPI2C_Get_MasterNACKDetectEvent(baseAddr))
{
/* Received NACK */

#if(LPI2C_HAS_ULTRA_FAST_MODE)
/* Ignore NACK in Ultra Fast mode */
if (master->operatingMode != LPI2C_ULTRAFAST_MODE)
{
#endif
/* Signal transfer end for blocking transfers */
if (master->blocking == true)
{
(void)OSIF_SemaPost(&(master->idleSemaphore));
}

#if(LPI2C_HAS_HIGH_SPEED_MODE)
/* High-speed transfers end at STOP condition */
master->highSpeedInProgress = false;
#endif
master->status = STATUS_I2C_RECEIVED_NACK;

/* End transfer: no stop generation (the module will handle that by itself
if needed), reset FIFOs */
LPI2C_DRV_MasterEndTransfer(baseAddr, master, false, true);

if (master->masterCallback != NULL)
{
master->masterCallback(I2C_MASTER_EVENT_END_TRANSFER, master->callbackParam);
}

/* Clear NACK flag */
LPI2C_Clear_MasterNACKDetectEvent(baseAddr);
#if(LPI2C_HAS_ULTRA_FAST_MODE)
}
#endif
}

Thanks, BR

Han

0 Kudos

541 Views
__invited__ali3
NXP Employee
NXP Employee

Hello Han,

 

Thank you for the information provided.

 

I will make some investigations on my side (as the behavior described is pretty strange) and I will come back with my observations.

 

Best regards,

Alina

0 Kudos

541 Views
bobpaddock
Senior Contributor II

If changing the optimization level to something lower makes the code work,

this is almost universally a sign that there is a 'volatile' qualifier missing

in some interrupt routine where it is needed.

0 Kudos

541 Views
nxf47370
NXP Employee
NXP Employee

Hi, Bob,

Thanks for your reply, but if change the baudrate for 400KHz, it will not be effected by optimization level(-O0 or  -O1), and our SDK optimization level is -O1 which is default setting. So i suspected it maybe a bug of SDK.

0 Kudos

541 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi nxf47370,

I wonder which device is holding the bus low.

Is there any slave connected to the bus?

Is it the S32K144 LPI2C Master?

Thanks,

BR, Daniel

0 Kudos

541 Views
nxf47370
NXP Employee
NXP Employee

Hi, Daniel,

 In order to generate NACK, i use one S32K144-Q100 EVB LPI2C master and another S32K144-Q100 EVB LPI2C as slave(addressed by master as 0x01), and master send incorrect slave address ( 0x02) . I test two conditions master connected with slave node and master without connected slave node, and they all hold the bus low after NACK received when set baudrate 100khz with SDK optimization level -O1. 

Thanks,

Han

0 Kudos