I'm using MCUXpresso SDK version 2.8.0 with the MK64FX512VLL12. I'm working with 3 I2C buses (I2C0, I2C1, and I2C2).
I'm having an issue where I2C_MasterTransferBlocking() hangs in an infinite loop waiting on the kI2C_TransferCompleteFlag:
/* Wait until the data register is ready for transmit. */
while (0U == (base->S & (uint8_t)kI2C_TransferCompleteFlag))
{
}
The hang doesn't occur on I2C0 or I2C1. However, I2C2 is shared with another master. Transfers work on that bus until the other master performs a transfer. The next time I call I2C_MasterTransferBlocking(), this results in an infinite loop waiting on kI2C_TransferCompleteFlag near the very top of the function.
It appears the other master's transfer results in the I2C2_S:TCF flag being cleared, so I'm not surprised to see the loop above hang infinitely. In fact, the K64 reference manual says this about I2Cx_S:TCF:
"TCF - Transfer Complete Flag: Acknowledges a byte transfer; TCF is set on the completion of a byte transfer. This bit is valid only during or immediately following a transfer to or from the I2C module. TCF is cleared by reading the I2C data register in receive mode or by writing to the I2C data register in transmit mode."
I can work around the issue by replacing the existing loop with:
while (base->S & (uint8_t)kI2C_BusBusyFlag)
{
}
So to my question(s):
解決済! 解決策の投稿を見る。
Hello @steve32768,
Since you're using the blocking function, the API will wait until the transfer ends to continue in the code. The TCF
Yes, the SDK is not enabled to work as Multimaster so checking the busy flag before a transfer to see if there's any pending transfer in the bus is a good approach.
Best Regards,
Alexis Andalon
Hey @Alexis_A,
we are using a really similiar setup MCU K32L2B31 communicating with an IMX6 via I2C. We are using I2C0 and I2C1 bus. The I2C0 bus is more or less acting as a real onboard bus. All sensors, EEPROM, MCU are connected ot the IMX6 on this bus. The IMX6 is always master and the MCU is the slave here. Everything is fine on the bus. We also have some I2C switch in between MCU and IMX6 to isolate the IMX6 of the bus.
On the I2C1 bus the IMX6 is also connected to the MCU and also the "outside" of the board - a connector. There we are connecting another board (lets call it lamp electronic) with a LED driver. At the bootup sequence of our device the following procedure is happening - at this time the IMX6 is not supplied and the I2C switch is opened (IMX6 is not on the I2C bus).
We are suppling the second board (lamp electronic - connected via the connector) with 3.3V - supply voltage for the lamp electronic board and also the 3V3 signal for the I2C lines. Then we wait 50ms to be sure we are supplied. In the next step we want to write an I2C command to the LED driver. In case of success the MCU would now turn into slave mode, IMX6 would be supplied with power, module should boot and we close the I2C switch so that the IMX master could reach the MCU (now in slave mode). But we are sometimes (not always) hanging in the while loop written above (I marked it bold below):
status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
{
assert(NULL != xfer);i2c_direction_t direction = xfer->direction;
status_t result = kStatus_Success;/* Clear all status before transfer. */
I2C_MasterClearStatusFlags(base, (uint32_t)kClearFlags);#if I2C_RETRY_TIMES
uint32_t waitTimes = I2C_RETRY_TIMES;
/* Wait until the data register is ready for transmit. */
while ((0U == (base->S & kI2C_TransferCompleteFlag)) && (0U != --waitTimes))
{
}
if (0U == waitTimes)
{
return kStatus_I2C_Timeout;
}
#else
/* Wait until the data register is ready for transmit. */
while (0U == (base->S & (uint8_t)kI2C_TransferCompleteFlag))
{
}
#endif
I checked the I2C communication to see the I2C command to set the LED pattern, but I cannot see any I2C communication on the oscilloscope. Interesting is also, if the second board (lamp electronic) is disconnected (so the I2C slave is not there physically) I never see this stuck in the while loop - but the command would be send too.
Could you tell me, if this is an NXP driver issue?
BR,
Thomas
Hi @steve32768
I cannot reproduce the issue on my side using a multi-master system(3 k64 I2C instance, 2 as master and 1 as slave). The data transfered by other master did and should not affect the TCF bit since the TCF is set to indicate the byte transfer completion done by this module not other master on bus. May you please share more of the transfer sequence when this situation happens? And what kind of I2C master and slave module are sharing the bus?
Thanks
Kate,
Thanks for the response.
The two masters on the bus are 1) K64 MCU, and 2) i.MX8 running Linux. The only slave on the bus is a DS1340U RTC. The transfers from master #2 are early in the Linux bootup sequence, and happen after the master #1 calls I2C_MasterInit() and before master #1 calls I2C_MasterTransferBlocking() to read a register from the slave.
I'll need some time before I can recreate the test setup and reproduce the issue. I should be able to get you more information in a few days.
Hello @steve32768,
Since you're using the blocking function, the API will wait until the transfer ends to continue in the code. The TCF
Yes, the SDK is not enabled to work as Multimaster so checking the busy flag before a transfer to see if there's any pending transfer in the bus is a good approach.
Best Regards,
Alexis Andalon
Thanks for the response. I'll go ahead with my workaround as described.