/*!
* brief MCAN IRQ handle function.
*
* This function handles the MCAN Error, the Buffer, and the Rx FIFO IRQ request.
*
* param base MCAN peripheral base address.
* param handle MCAN handle pointer.
*/
void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle)
{
/* Assertion. */
assert(NULL != handle);
status_t status = kStatus_MCAN_UnHandled;
uint32_t valueIR;
uint32_t result;
/* Store Current MCAN Module Error and Status. */
valueIR = base->IR;
do
{
if (0U != (valueIR & ((uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |
(uint32_t)kMCAN_BusOffIntFlag)))
{
/* Solve error. */
result = (uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |
(uint32_t)kMCAN_BusOffIntFlag;
status = kStatus_MCAN_ErrorStatus;
}
else if (0U != (valueIR & (uint32_t)kMCAN_TxTransmitCompleteFlag))
{
/* Solve Tx interrupt. */
result = (uint32_t)kMCAN_TxTransmitCompleteFlag;
status = kStatus_MCAN_TxIdle;
MCAN_TransferAbortSend(base, handle, handle->txbufferIdx);
}
else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo0NewFlag))
{
(void)MCAN_ReadRxFifo(base, 0U, handle->rxFifoFrameBuf);
result = (uint32_t)kMCAN_RxFifo0NewFlag;
status = kStatus_MCAN_RxFifo0Idle;
MCAN_TransferAbortReceiveFifo(base, 0U, handle);
}
else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo0LostFlag))
{
result = (uint32_t)kMCAN_RxFifo0LostFlag;
status = kStatus_MCAN_RxFifo0Lost;
}
else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo1NewFlag))
{
(void)MCAN_ReadRxFifo(base, 1U, handle->rxFifoFrameBuf);
result = (uint32_t)kMCAN_RxFifo1NewFlag;
status = kStatus_MCAN_RxFifo1Idle;
MCAN_TransferAbortReceiveFifo(base, 1U, handle);
}
else if (0U != (valueIR & (uint32_t)kMCAN_RxFifo1LostFlag))
{
result = (uint32_t)kMCAN_RxFifo1LostFlag;
status = kStatus_MCAN_RxFifo0Lost;
}
else
{
/* Handle the interrupt flag unsupported in current version of MCAN driver.
* User can get these unsupported interrupt flags by callback function,
* we can clear directly in the handler to prevent endless loop.
*/
result = valueIR;
result &= ~((uint32_t)kMCAN_ErrorWarningIntFlag | (uint32_t)kMCAN_ErrorPassiveIntFlag |
(uint32_t)kMCAN_BusOffIntFlag | (uint32_t)kMCAN_TxTransmitCompleteFlag |
(uint32_t)kMCAN_RxFifo0NewFlag | (uint32_t)kMCAN_RxFifo0LostFlag |
(uint32_t)kMCAN_RxFifo1NewFlag | (uint32_t)kMCAN_RxFifo1LostFlag);
}
/* Clear Error interrupt, resolved Rx FIFO, Tx Buffer IRQ and other unsupported interrupt flags. */
MCAN_ClearStatusFlag(base, result);
/* Calling Callback Function if has one. */
if (handle->callback != NULL)
{
handle->callback(base, handle, status, result, handle->userData);
}
/* Reset return status */
status = kStatus_MCAN_UnHandled;
/* Store Current MCAN Module Error and Status. */
valueIR = base->IR;
} while (0U != valueIR);
}