AnsweredAssumed Answered

I2C slave bug in fsl_i2c.c

Question asked by michals on Jul 5, 2018
Latest reply on Jul 9, 2018 by Daniel Chen

There appears to be a bug in fsl_i2c.c (latest SDK for MCUXpresso for KL17 as of 2018-07-05). I have implemented I2C slave on KL17 and the code works fine in blocking mode but does not work in interrupt driven (specifically, when slave is receiving incoming data. Slave transmit out data works fine). I traced this down to this snipped of code in:

 

void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)

 

#ifdef I2C_HAS_STOP_DETECT
/* Check stop flag. */
if (status & kI2C_StopDetectFlag)
{
I2C_MasterClearStatusFlags(base, kI2C_StopDetectFlag);

/* Clear the interrupt flag. */
base->S = kI2C_IntPendingFlag;

/* Call slave callback if this is the STOP of the transfer. */
if (handle->isBusy)
{
xfer->event = kI2C_SlaveCompletionEvent;
xfer->completionStatus = kStatus_Success;
handle->isBusy = false;

if ((handle->eventMask & xfer->event) && (handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
}
if (!(status & kI2C_AddressMatchFlag))
{
return;
}
}
#endif /* I2C_HAS_STOP_DETECT */

 

The problem is that when, IRQ is triggered on 'stop' detected, there is still a byte in the data register (data in I2C->D and TFC flag on). However, that byte is never processed because of the last 'if' statement above. I2C->S register does not show 'kI2C_AddressMatchFlag' (IAAS) so the IRQ handler exits and drops last byte. Commenting out that last 'if' statement gets slave receive working using fsl_i2c.c.

Outcomes