@@ -13,19 +13,31 @@ HAL_StatusTypeDef can_init(can_t *can, FDCAN_HandleTypeDef *hcan)
1313 can -> extended_filter_index = 0 ;
1414 can -> hcan = hcan ;
1515
16- /* Config interrupts */
16+ /* Config incoming message interrupt. */
1717 HAL_StatusTypeDef status = HAL_FDCAN_ConfigInterruptLines (can -> hcan , FDCAN_IT_RX_FIFO0_NEW_MESSAGE , FDCAN_INTERRUPT_LINE0 );
1818 if (status != HAL_OK )
1919 {
20- printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() (Status: %d).\n" , status );
20+ printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines(can->hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, FDCAN_INTERRUPT_LINE0); (Status: %d).\n" , status );
2121 return status ;
2222 }
23-
24- /* Activate interrupt notifications */
2523 status = HAL_FDCAN_ActivateNotification (can -> hcan , FDCAN_IT_RX_FIFO0_NEW_MESSAGE , 0 );
2624 if (status != HAL_OK )
2725 {
28- printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ActivateNotification() (Status: %d).\n" , status );
26+ printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); (Status: %d).\n" , status );
27+ return status ;
28+ }
29+
30+ /* Config BusOff interrupt. */
31+ status = HAL_FDCAN_ConfigInterruptLines (can -> hcan , FDCAN_IT_BUS_OFF , FDCAN_INTERRUPT_LINE1 );
32+ if (status != HAL_OK )
33+ {
34+ printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines(can->hcan, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); (Status: %d).\n" , status );
35+ return status ;
36+ }
37+ status = HAL_FDCAN_ActivateNotification (can -> hcan , FDCAN_IT_BUS_OFF , 1 );
38+ if (status != HAL_OK )
39+ {
40+ printf ("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, 1); (Status: %d).\n" , status );
2941 return status ;
3042 }
3143
@@ -101,6 +113,36 @@ HAL_StatusTypeDef can_add_filter_extended(can_t *can, uint32_t can_ids[2])
101113 return status ;
102114}
103115
116+ /* Returns true if the CAN node is in bus-off state. */
117+ bool can_is_bus_off (can_t * can ) {
118+ FDCAN_ProtocolStatusTypeDef status ;
119+ HAL_FDCAN_GetProtocolStatus (can -> hcan , & status );
120+ return (bool )status .BusOff ;
121+ }
122+
123+ /* Recovers from bus-off by stopping and restarting the FDCAN peripheral.
124+ Filters survive Stop/Start but notifications do not, so RX FIFO interrupt is re-enabled. */
125+ HAL_StatusTypeDef can_recover_bus_off (can_t * can ) {
126+ HAL_StatusTypeDef status = HAL_FDCAN_Stop (can -> hcan );
127+ if (status != HAL_OK ) {
128+ printf ("[fdcan.c/can_recover_bus_off()] ERROR: HAL_FDCAN_Stop() failed (Status: %d).\n" , status );
129+ return status ;
130+ }
131+
132+ status = HAL_FDCAN_Start (can -> hcan );
133+ if (status != HAL_OK ) {
134+ printf ("[fdcan.c/can_recover_bus_off()] ERROR: HAL_FDCAN_Start() failed (Status: %d).\n" , status );
135+ return status ;
136+ }
137+
138+ status = HAL_FDCAN_ActivateNotification (can -> hcan , FDCAN_IT_RX_FIFO0_NEW_MESSAGE , 0 );
139+ if (status != HAL_OK ) {
140+ printf ("[fdcan.c/can_recover_bus_off()] ERROR: HAL_FDCAN_ActivateNotification() failed (Status: %d).\n" , status );
141+ }
142+
143+ return status ;
144+ }
145+
104146/* Sends a CAN message. */
105147HAL_StatusTypeDef can_send_msg (can_t * can , can_msg_t * msg )
106148{
0 commit comments