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.
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.
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.
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.
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?
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.
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.
/* Received NACK */
/* Ignore NACK in Ultra Fast mode */
if (master->operatingMode != LPI2C_ULTRAFAST_MODE)
/* Signal transfer end for blocking transfers */
if (master->blocking == true)
/* High-speed transfers end at STOP condition */
master->highSpeedInProgress = false;
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)
/* Clear NACK flag */
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.
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.
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.
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.