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.
image 1. Optimization Level None(-O0)
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
Hello Han,
With 100kbps baudrate and -O1 optimized flag, the Lpi2c could not handle fast enough to shift STOP bit out bus before FIFO is reset on error interrupt handler. So i think that STOP bit is stuck on the shifter. I tried with no resetting FIFO on the interrupt handler, and saw that STOP bit appeared on bus as expectation.
Thanks,
Manh
Hi, I am also facing the same NACK issue. Using S32K144_SDK v3.0.0 and lpi2c_master_s32k144 example code. Would like to know the conclusion/resolution for this issue. Slave device is not connected and optimization is -O1(default). Thanks,Gopal
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.
Best regards,
Alina
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
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
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
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
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.
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
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
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.
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.
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