SLAAET4 April 2025 MSPM0G3506 , MSPM0G3507 , MSPM0G3518 , MSPM0G3519
The Bus Off state occurs when a CAN node is forcibly isolated due to severe bus errors. In this state, the node stops transmitting and receiving data, effectively disconnecting from the bus. This mechanism protects the bus from persistent errors and prevents fault propagation.
The primary trigger is when the TEC exceeds a threshold (typically 255). Common scenarios include:
For example, each transmission error increments the TEC by 1. If errors accumulate rapidly and TEC exceeds 255, then the node enters bus off state.
The device can recover from bus off state by performing one of the following actions:
An example is shown below of how to detect bus off status by on enabling Bus_Off Status interrupt in Sysconfig first. When there is a change in the Bus Off status, the MCAN triggers a Bus_Off Status interrupt to notify users of this situation. Users need to check if the bus off state is in the interrupt routine.
/**
* CAN protocol status
* Bus off
*/
DL_MCAN_ProtocolStatus gProtStatus;
volatile uint8_t CANBusOff = 0;
void MCAN0_INST_IRQHandler(void)
{
switch (DL_MCAN_getPendingInterrupt(MCAN0_INST)) {
case DL_MCAN_IIDX_LINE0:
break;
case DL_MCAN_IIDX_LINE1:
/* MCAN bus off status changed */
if(gInterruptLine1Status&DL_MCAN_INTERRUPT_BO) {
DL_MCAN_getProtocolStatus(MCAN0_INST, &gProtStatus);
if(gProtStatus.busOffStatus == 1) {
CANBusOff = true;
}
else {
CANBusOff = false;
}
}
/* Clear all MCAN interrupt status */
DL_MCAN_clearIntrStatus(MCAN0_INST, gInterruptLine1Status, DL_MCAN_INTR_SRC_MCAN_LINE_1);
break;
default:
break;
}
}
Then, check the CANBusOff flag in the main loop. When the bus off state is detected, restart the MCAN module.
main loop:
{
if(CANBusOff == 1) {
/* Re-start MCAN */
MCAN0_Restart();
CANBusOff = 0;
}
}
/*MCAN restart function*/
void MCAN0_Restart(void)
{
DL_MCAN_reset(CANFD0);
delay_cycles(16);
DL_MCAN_disablePower(CANFD0);
delay_cycles(32);
DL_MCAN_enablePower(CANFD0);
// MCAN RAM need at least 50us to finish init
// 1600 CPU cycles@CPU32MHz
// 4000 CPU cycles@CPU80MHz
delay_cycles(4000);
SYSCFG_DL_MCAN0_init();
}