I2C_MasterTransferBlocking hangs waiting on kI2C_TransferCompleteFlag

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

I2C_MasterTransferBlocking hangs waiting on kI2C_TransferCompleteFlag

ソリューションへジャンプ
2,908件の閲覧回数
steve32768
Contributor II

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):

  • Why is I2C_MasterTransferBlocking() waiting for the TCF flag before performing a transfer when the reference manual advises that TCF is only valid after a transfer?
  • Does my workaround (waiting for kI2C_BusBusyFlag==0) look reasonable?
  • Is this a bug in the fsl_i2c.c that should be addressed by NXP?
0 件の賞賛
返信
1 解決策
2,896件の閲覧回数
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @steve32768,

  • Why is I2C_MasterTransferBlocking() waiting for the TCF flag before performing a transfer when the reference manual advises that TCF is only valid after a transfer?

Since you're using the blocking function, the API will wait until the transfer ends to continue in the code. The TCF 

  • Does my workaround (waiting for kI2C_BusBusyFlag==0) look reasonable?

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.

  • Is this a bug in the fsl_i2c.c that should be addressed by NXP?
The SDK only provides the typical use cases for the module. A multi-master I2C bus is a custom application and therefore not implemented. I do appreciate you taking the time to bring this to our attention, I will forward this to the development team so they can analyze this improvement opportunity.
 

Best Regards,

Alexis Andalon

元の投稿で解決策を見る

0 件の賞賛
返信
5 返答(返信)
954件の閲覧回数
thomas_92
Contributor I

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

0 件の賞賛
返信
2,792件の閲覧回数
KATE_WANG
NXP Employee
NXP Employee

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

BR
KATE
0 件の賞賛
返信
2,778件の閲覧回数
steve32768
Contributor II

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.

0 件の賞賛
返信
2,897件の閲覧回数
Alexis_A
NXP TechSupport
NXP TechSupport

Hello @steve32768,

  • Why is I2C_MasterTransferBlocking() waiting for the TCF flag before performing a transfer when the reference manual advises that TCF is only valid after a transfer?

Since you're using the blocking function, the API will wait until the transfer ends to continue in the code. The TCF 

  • Does my workaround (waiting for kI2C_BusBusyFlag==0) look reasonable?

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.

  • Is this a bug in the fsl_i2c.c that should be addressed by NXP?
The SDK only provides the typical use cases for the module. A multi-master I2C bus is a custom application and therefore not implemented. I do appreciate you taking the time to bring this to our attention, I will forward this to the development team so they can analyze this improvement opportunity.
 

Best Regards,

Alexis Andalon

0 件の賞賛
返信
2,867件の閲覧回数
steve32768
Contributor II

Thanks for the response. I'll go ahead with my workaround as described.

0 件の賞賛
返信