AnsweredAssumed Answered

LPI2C Bug?

Question asked by Mark Butcher on Dec 3, 2017
Latest reply on Mar 21, 2018 by Mark Butcher

Hi All


I have started some tests with the new LPI2C in the KL28 but may have already found a bug which is not mentioned in its errata.


Take a look at a read of the accelerometer on the FRDM-KL28Z that follows:




The accelerometer is addressed for a write and the value 9 is subsequently written to select the internal register to be read from, then a repeated start is send to address it for the subsequent read. Only the start of the subsequent read is shown but all works fine.


I repeat, but this time set a break point after the first address byte has been sent – with the DBGEN set to '1' (meaning that the LPI2C will stop when debug mode is entered).


As can be seen, the start condition is sent, followed by the address - and the bus remains busy.
When the debugger continues, the second byte is sent, followed a stop condition.



Now I repeat again but this time with the DBGEN set to '0', meaning that the LPI2C continues to run in debug mode.:



Now it is seen that a STOP condition has been sent by the LPI2C.

When the code continues, it tries to send the data byte but can't because the bus is now idle – it can only continue if it sends a new start bit.


It turns out that the LPI2C sends a STOP condition if there is nothing in the Tx FIFO, meaning that if the FIFO can't be filled before this takes place the transfer will be terminated. Firmware must thus keep up otherwise any Tx FIFO underflow will terminate a cycle and hence cause failure.


This is exactly what is explained in the AUTOSTOP feature in the LPI2C_MCFGR1 register:


However, whether this is set to '1' or set to '0' doesn't change the behavior – it always reacts as if it were set.


This is what looks like an errata, whereby the workaround is to ensure that the firmware keeps up with the transmission by making use of its Tx FIFO depth, or by using just slow I2C clock speeds, or using DMA.


Also, working with DBGEN set to '0' more or less means that all I2C activity will fail, so BDGEN is required to have any chance (one can also take the NXP examples and try stepping them to see that they then fail). In comparison, doing such things on other Kinetis devices with the old fashioned I2C (non-buffered) controller never had issues with debugging – one could step the code and the I2C bus would pause/continue normally, although the I2C continues to run in debug mode.