void LPI2C_SlaveTransferHandleIRQ(uint32_t instance, void *lpi2cSlaveHandle)
{
assert(instance < ARRAY_SIZE(kLpi2cBases));
uint32_t flags;
lpi2c_slave_transfer_t *xfer;
LPI2C_Type *base = kLpi2cBases[instance];
lpi2c_slave_handle_t *handle = (lpi2c_slave_handle_t *)lpi2cSlaveHandle;
/* Check for a valid handle in case of a spurious interrupt. */
if (NULL != handle)
{
xfer = &handle->transfer;
/* Get status flags. */
flags = LPI2C_SlaveGetStatusFlags(base);
if (0U != (flags & ((uint32_t)kLPI2C_SlaveBitErrFlag | (uint32_t)kLPI2C_SlaveFifoErrFlag)))
{
xfer->event = kLPI2C_SlaveCompletionEvent;
xfer->completionStatus = LPI2C_SlaveCheckAndClearError(base, flags);
if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveCompletionEvent)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
}
else
{
if (0U !=
(flags & (((uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag) | ((uint32_t)kLPI2C_SlaveStopDetectFlag))))
{
xfer->event = (0U != (flags & (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag)) ?
kLPI2C_SlaveRepeatedStartEvent :
kLPI2C_SlaveCompletionEvent;
xfer->receivedAddress = 0U;
xfer->completionStatus = kStatus_Success;
xfer->transferredCount = handle->transferredCount;
if (xfer->event == kLPI2C_SlaveCompletionEvent)
{
handle->isBusy = false;
}
if (handle->wasTransmit)
{
/* Subtract one from the transmit count to offset the fact that LPI2C asserts the */
/* tx flag before it sees the nack from the master-receiver, thus causing one more */
/* count that the master actually receives. */
--xfer->transferredCount;
handle->wasTransmit = false;
}
/* Clear the flag. */
LPI2C_SlaveClearStatusFlags(base, flags & ((uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag |
(uint32_t)kLPI2C_SlaveStopDetectFlag));
/* Revert to sending an Ack by default, in case we sent a Nack for receive. */
base->STAR = 0U;
if ((0U != (handle->eventMask & (uint32_t)xfer->event)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
if (0U != (flags & (uint32_t)kLPI2C_SlaveStopDetectFlag))
{
/* Clean up transfer info on completion, after the callback has been invoked. */
(void)memset(&handle->transfer, 0, sizeof(handle->transfer));
}
}
if (0U != (flags & (uint32_t)kLPI2C_SlaveAddressValidFlag))
{
xfer->event = kLPI2C_SlaveAddressMatchEvent;
xfer->receivedAddress = (uint8_t)(base->SASR & LPI2C_SASR_RADDR_MASK);
/* Update handle status to busy because slave is addressed. */
handle->isBusy = true;
if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveAddressMatchEvent)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
}
if (0U != (flags & (uint32_t)kLPI2C_SlaveTransmitAckFlag))
{
xfer->event = kLPI2C_SlaveTransmitAckEvent;
if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveTransmitAckEvent)) && (NULL != handle->callback))
{
handle->callback(base, xfer, handle->userData);
}
else
{
LPI2C_SlaveTransmitAck(base, true);
}
}
/* Handle transmit and receive. */
if (0U != (flags & (uint32_t)kLPI2C_SlaveTxReadyFlag))
{
handle->wasTransmit = true;
/* If we're out of data, invoke callback to get more. */
if ((NULL == xfer->data) || (0U == xfer->dataSize))
{
xfer->event = kLPI2C_SlaveTransmitEvent;
if (NULL != handle->callback)
{
handle->callback(base, xfer, handle->userData);
}
/* Clear the transferred count now that we have a new buffer. */
handle->transferredCount = 0U;
}
/* Transmit a byte. */
if ((NULL != xfer->data) && (0U != xfer->dataSize))
{
base->STDR = *xfer->data++;
--xfer->dataSize;
++handle->transferredCount;
}
}
if (0U != (flags & (uint32_t)kLPI2C_SlaveRxReadyFlag))
{
/* If we're out of room in the buffer, invoke callback to get another. */
if ((NULL == xfer->data) || (0U == xfer->dataSize))
{
xfer->event = kLPI2C_SlaveReceiveEvent;
if (NULL != handle->callback)
{
handle->callback(base, xfer, handle->userData);
}
/* Clear the transferred count now that we have a new buffer. */
handle->transferredCount = 0U;
}
/* Receive a byte. */
if ((NULL != xfer->data) && (0U != xfer->dataSize))
{
*xfer->data++ = (uint8_t)base->SRDR;
--xfer->dataSize;
++handle->transferredCount;
if (0U != (base->SCFGR1 & LPI2C_SCFGR1_ACKSTALL_MASK))
{
if (((0U == (handle->eventMask & (uint32_t)kLPI2C_SlaveTransmitAckEvent)) ||
(NULL == handle->callback)))
{
LPI2C_SlaveTransmitAck(base, true);
}
}
}
else
{
/* We don't have any room to receive more data, so send a nack. */
if (0U != (base->SCFGR1 & LPI2C_SCFGR1_ACKSTALL_MASK))
{
if (((0U == (handle->eventMask & (uint32_t)kLPI2C_SlaveTransmitAckEvent)) ||
(NULL == handle->callback)))
{
LPI2C_SlaveTransmitAck(base, false);
}
}
}
}
}
}
}
Hope it can help you
BR
XiangJun Rong