2025-05-28 2:33 PM
When a CAN message is not ACKed by other nodes, if auto re-transmission is set, bxCAN will re-transmit the message infinitely. This floods the CAN bus, especially if the message is of high priority.
My solution is to enable the error passive interrupt (EPVIE), when EPVF is set, in HAL_CAN_ErrorCallback check which TX mail box has transmission error, and explicitly request abort, as follows:
if (hcan->ErrorCode & HAL_CAN_ERROR_EPV) {
uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
hcan->ErrorCode &= ~HAL_CAN_ERROR_EPV;
if ((tsrflags & CAN_TSR_TERR0) && !(tsrflags & CAN_TSR_TME0)) {
SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);
}
if ((tsrflags & CAN_TSR_TERR1) && !(tsrflags & CAN_TSR_TME1)) {
SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
}
if ((tsrflags & CAN_TSR_TERR2) && !(tsrflags & CAN_TSR_TME2)) {
SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
}
/* I noticed EPVF bit in the ESR register will not be cleared by aborting
* the TX message. I then explicitly stop and re-start the CAN peripheral.
* However, this has no effect. After the below API calls, EPVF is still set
* and another flooding TX message will not trigger the SCE interrupt.
*/
HAL_CAN_Stop(hcan);
HAL_CAN_Start(hcan);
HAL_CAN_ResetError(hcan);
}
This can only work just one time. If again another message is not ACKed, ERRI bit in the MSR register will not be set and the SCE interrupt will not be triggered. As a result, I can not abort the corrsponding flooding message.
I notice that after aborting the flooding TX message, EPVF flag in the ESR register will not be cleared. However, explicitly stop and re-start the peripheral will not fix the issue.
Below is the setting in the Init function. AutoRetransmission is enabled in case arbitration lost.
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 3;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_2TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_12TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_3TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = ENABLE;
Any suggestion would be appreciated.
Thanks,
Xiankun
2025-05-28 2:39 PM
Some follow up clarification:
HAL_CAN_ActivateNotification(hcan_, CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_RX_FIFO0_MSG_PENDING
|CAN_IT_RX_FIFO1_MSG_PENDING | CAN_IT_ERROR_PASSIVE | CAN_IT_BUSOFF | CAN_IT_ERROR);