i have my slave call back function.
void I2CManager::lpi2c_slave_callback(LPI2C_Type *base,
lpi2c_slave_transfer_t *xfer,
void *param) {
switch (xfer->event) {
case kLPI2C_SlaveAddressMatchEvent:
xfer->data = nullptr;
xfer->dataSize = 0;
break;
case kLPI2C_SlaveTransmitEvent:
xfer->data = m_slave_buff[1];
xfer->dataSize = sizeof(m_slave_buff);
break;
case kLPI2C_SlaveReceiveEvent:
xfer->data = m_slave_buff;
xfer->dataSize = sizeof(m_slave_buff);
break;
case kLPI2C_SlaveCompletionEvent:
m_SlaveCompletionFlag = true;
/* here how to know the exact receive complete and transfer complete how to know specific is there any flags to know whether it is receiver complete or transmit complete */
break;
default:
m_SlaveCompletionFlag = false;
break;
}
}
As mentioned in multiline comment
how to know the exact receive complete and transfer complete How to know specifically, are there any flags to know whether it is receiver complete or transmit complete?
could you please let me know which flag i need to add .Thanks in advance.
Hi,
Pls refer to the api function, the
:lpi2c_slave_callback(LPI2C_Type *base,
lpi2c_slave_transfer_t *xfer,
void *param) is the same as handle->callback, which is a function pointer.
I copy the function here:
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