Function name:FLEXCAN_IRQHandler
I modified the code in picture to avoid hardfault reset(because CAN2 don't have pretendnetwork function), and the value of ECR register(which is used to count error) is 0, thus Error_IRQHandler can not be executed.
I don't know the reason, help me!Thank you!
I found some discriptions in datasheet(red line).
The busoff interrupt is issued, and ERRCNT is setted to 0. If you check the ErrorCounters, the result may be 0, so that
if (ecr != 0U) will not be established.
I'm not sure it is the reason of that.
Hi@liyun
This should be the reason, but you still need to test it.
BR!
Jim,
Hi Senlent
I have passed the test.
Thank you for all the time.
BR!
Hi@liyun
Similar to the previous question.
usually we don't allow customers to modify the driver file.
RTM_3.0
void FLEXCAN_IRQHandler(uint8_t instance)
{
DEV_ASSERT(instance < CAN_INSTANCE_COUNT);
uint32_t flag_reg = 0;
CAN_Type * base = g_flexcanBase[instance];
flexcan_state_t * state = g_flexcanStatePtr[instance];
/* Get the interrupts that are enabled and ready */
uint32_t mb_idx = 0;
flag_reg = FLEXCAN_GetMsgBuffIntStatusFlag(base, mb_idx);
while ((flag_reg & 1U) == 0U)
{
mb_idx++;
flag_reg = FLEXCAN_GetMsgBuffIntStatusFlag(base, mb_idx);
if (mb_idx >= FEATURE_CAN_MAX_MB_NUM)
{
break;
}
}
/* Check Tx/Rx interrupt flag and clear the interrupt */
if(flag_reg != 0U)
{
if (FLEXCAN_IsRxFifoEnabled(base) && (mb_idx <= FEATURE_CAN_RXFIFO_OVERFLOW))
{
FLEXCAN_IRQHandlerRxFIFO(instance, mb_idx);
}
else
{
/* Check mailbox completed reception */
if (state->mbs[mb_idx].state == FLEXCAN_MB_RX_BUSY)
{
FLEXCAN_IRQHandlerRxMB(instance, mb_idx);
}
}
/* Check mailbox completed transmission */
if (state->mbs[mb_idx].state == FLEXCAN_MB_TX_BUSY)
{
if (state->mbs[mb_idx].isRemote)
{
/* If the frame was a remote frame, clear the flag only if the response was
* not received yet. If the response was received, leave the flag set in order
* to be handled when the user calls FLEXCAN_DRV_RxMessageBuffer. */
flexcan_msgbuff_t mb;
FLEXCAN_LockRxMsgBuff(base, mb_idx);
FLEXCAN_GetMsgBuff(base, mb_idx, &mb);
FLEXCAN_UnlockRxMsgBuff(base);
if (((mb.cs & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT) == (uint32_t)FLEXCAN_RX_EMPTY)
{
FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
}
}
else
{
FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
}
state->mbs[mb_idx].state = FLEXCAN_MB_IDLE;
/* Invoke callback */
if (state->callback != NULL)
{
state->callback(instance, FLEXCAN_EVENT_TX_COMPLETE, mb_idx, state);
}
if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
{
/* Complete transmit data */
FLEXCAN_CompleteTransfer(instance, mb_idx);
}
}
if (FLEXCAN_GetMsgBuffIntStatusFlag(base, mb_idx) != 0U)
{
if (FLEXCAN_IsRxFifoEnabled(base) && (mb_idx <= FEATURE_CAN_RXFIFO_OVERFLOW))
{
if (state->mbs[FLEXCAN_MB_HANDLE_RXFIFO].state == FLEXCAN_MB_IDLE)
{
/* In case of desynchronized status of the MB to avoid trapping in ISR
* clear the MB flag */
FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
}
}
else
{
if (state->mbs[mb_idx].state == FLEXCAN_MB_IDLE)
{
/* In case of desynchronized status of the MB to avoid trapping in ISR
* clear the MB flag */
FLEXCAN_ClearMsgBuffIntStatusFlag(base, mb_idx);
}
}
}
}
#if (defined(CPU_S32K116) || defined(CPU_S32K118))
else
{
#if FEATURE_CAN_HAS_PRETENDED_NETWORKING
/* The pretending Network Feature is present on all CPUs
* only on FLEXCAN Instance 0 */
if (instance == 0U)
{
uint8_t wtof = FLEXCAN_GetWTOF(base);
uint8_t wumf = FLEXCAN_GetWUMF(base);
/* Check if wake-up event occurred */
if ((wtof != 0U) || (wumf != 0U))
{
FLEXCAN_WakeUpHandler(instance);
}
}
#endif /* FEATURE_CAN_HAS_PRETENDED_NETWORKING */
uint32_t ecr = FLEXCAN_GetErrorCounters(base);
/* Check if any error occurred */
if (ecr != 0U)
{
FLEXCAN_Error_IRQHandler(instance);
}
}
#endif /* (defined(CPU_S32K116) || defined(CPU_S32K118)) */
return;
}
Here is the same problem, it may be a long time ago, but it should be very helpful for you complete the Bus-off function.
https://community.nxp.com/t5/S32K/s32K144-can-bus-off/td-p/762743
BR!
Jim,
Hi Senlent,
Thank you very much and give me 2 examples for learning.
And I knew the differences between RTM_3.0 and RTM_2.0.
I have one more question, connect CAN_H & CAN_L(CAN2), ESR->BOFFINT setted by 1, it means busoff interrupt happened, but because of ECR = 0(TEC>255, the bus will be busoff state), FLEXCAN_Error_IRQHandler can not be excused, the interrupt flag can not be cleared.
We do not use busoff automatically recovery.
What reasons can led to this status?Thank you.
uint32_t ecr = FLEXCAN_GetErrorCounters(base);
/* Check if any error occurred */
if (ecr != 0U)
{
FLEXCAN_Error_IRQHandler(instance);
}