From b47199f8d7bba5c376242905fb072431850eb09a Mon Sep 17 00:00:00 2001 From: bjackson312006 Date: Sat, 18 Apr 2026 19:39:14 -0400 Subject: [PATCH 1/4] fd can updates --- platforms/stm32h563/include/fdcan.h | 2 ++ platforms/stm32h563/src/fdcan.c | 47 ++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/platforms/stm32h563/include/fdcan.h b/platforms/stm32h563/include/fdcan.h index d59c37bc..c619f82c 100644 --- a/platforms/stm32h563/include/fdcan.h +++ b/platforms/stm32h563/include/fdcan.h @@ -28,6 +28,8 @@ HAL_StatusTypeDef can_init(can_t *can, FDCAN_HandleTypeDef *hcan); HAL_StatusTypeDef can_send_msg(can_t *can, can_msg_t *msg); HAL_StatusTypeDef can_add_filter_standard(can_t *can, uint16_t can_ids[2]); HAL_StatusTypeDef can_add_filter_extended(can_t *can, uint32_t can_ids[2]); +bool can_is_bus_off(can_t *can); +HAL_StatusTypeDef can_recover_bus_off(can_t *can); // clang-format on #endif // FDCAN_H \ No newline at end of file diff --git a/platforms/stm32h563/src/fdcan.c b/platforms/stm32h563/src/fdcan.c index 2191455e..6f1f59af 100644 --- a/platforms/stm32h563/src/fdcan.c +++ b/platforms/stm32h563/src/fdcan.c @@ -17,17 +17,18 @@ HAL_StatusTypeDef can_init(can_t *can, FDCAN_HandleTypeDef *hcan) HAL_StatusTypeDef status = HAL_FDCAN_ConfigInterruptLines(can->hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, FDCAN_INTERRUPT_LINE0); if (status != HAL_OK) { - printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() (Status: %d).\n", status); + printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() FDCAN_IT_RX_FIFO0_NEW_MESSAGE (Status: %d).\n", status); return status; } - - /* Activate interrupt notifications */ - status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); - if (status != HAL_OK) - { - printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ActivateNotification() (Status: %d).\n", status); - return status; + status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); + if(status != HAL_OK) { + printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() for FDCAN_IT_BUS_OFF (Status: %d).\n", status); } + // status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, 0); + // if(status != HAL_OK) { + // printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() for FDCAN_IT_BUS_OFF (Status: %d).\n", status); + // } + // this is the direct code from the st guy /* Set up the global filter to reject all messages by default. You must explicitly add messages to your filters in the app layer to receive them. */ status = HAL_FDCAN_ConfigGlobalFilter(hcan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE); @@ -101,6 +102,36 @@ HAL_StatusTypeDef can_add_filter_extended(can_t *can, uint32_t can_ids[2]) return status; } +/* Returns true if the CAN node is in bus-off state. */ +bool can_is_bus_off(can_t *can) { + FDCAN_ProtocolStatusTypeDef status; + HAL_FDCAN_GetProtocolStatus(can->hcan, &status); + return (bool)status.BusOff; +} + +/* Recovers from bus-off by stopping and restarting the FDCAN peripheral. + Filters survive Stop/Start but notifications do not, so RX FIFO interrupt is re-enabled. */ +HAL_StatusTypeDef can_recover_bus_off(can_t *can) { + HAL_StatusTypeDef status = HAL_FDCAN_Stop(can->hcan); + if (status != HAL_OK) { + printf("[fdcan.c/can_recover_bus_off()] ERROR: HAL_FDCAN_Stop() failed (Status: %d).\n", status); + return status; + } + + status = HAL_FDCAN_Start(can->hcan); + if (status != HAL_OK) { + printf("[fdcan.c/can_recover_bus_off()] ERROR: HAL_FDCAN_Start() failed (Status: %d).\n", status); + return status; + } + + status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + if (status != HAL_OK) { + printf("[fdcan.c/can_recover_bus_off()] ERROR: HAL_FDCAN_ActivateNotification() failed (Status: %d).\n", status); + } + + return status; +} + /* Sends a CAN message. */ HAL_StatusTypeDef can_send_msg(can_t *can, can_msg_t *msg) { From f069d49227c9c3be4316b97fdadd3308c80c8548 Mon Sep 17 00:00:00 2001 From: bjackson312006 Date: Sun, 19 Apr 2026 14:41:07 -0400 Subject: [PATCH 2/4] fixed can_init() for interrupts --- platforms/stm32h563/src/fdcan.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/platforms/stm32h563/src/fdcan.c b/platforms/stm32h563/src/fdcan.c index 6f1f59af..1a501762 100644 --- a/platforms/stm32h563/src/fdcan.c +++ b/platforms/stm32h563/src/fdcan.c @@ -13,16 +13,32 @@ HAL_StatusTypeDef can_init(can_t *can, FDCAN_HandleTypeDef *hcan) can->extended_filter_index = 0; can->hcan = hcan; - /* Config interrupts */ + /* Config incoming message interrupt. */ HAL_StatusTypeDef status = HAL_FDCAN_ConfigInterruptLines(can->hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, FDCAN_INTERRUPT_LINE0); if (status != HAL_OK) { - printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() FDCAN_IT_RX_FIFO0_NEW_MESSAGE (Status: %d).\n", status); + 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); return status; } - status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); - if(status != HAL_OK) { - printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() for FDCAN_IT_BUS_OFF (Status: %d).\n", status); + status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + if (status != HAL_OK) + { + 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); + return status; + } + + /* Config BusOff interrupt. */ + HAL_StatusTypeDef status = HAL_FDCAN_ConfigInterruptLines(can->hcan, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); + if (status != HAL_OK) + { + 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); + return status; + } + status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, 1); + if (status != HAL_OK) + { + printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, 1); (Status: %d).\n", status); + return status; } // status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, 0); // if(status != HAL_OK) { From 8d4b1113c3df7914dab3899fe697f0dfe85e0604 Mon Sep 17 00:00:00 2001 From: bjackson312006 Date: Sun, 19 Apr 2026 14:42:04 -0400 Subject: [PATCH 3/4] whoops --- platforms/stm32h563/src/fdcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/stm32h563/src/fdcan.c b/platforms/stm32h563/src/fdcan.c index 1a501762..7c6f9a34 100644 --- a/platforms/stm32h563/src/fdcan.c +++ b/platforms/stm32h563/src/fdcan.c @@ -28,7 +28,7 @@ HAL_StatusTypeDef can_init(can_t *can, FDCAN_HandleTypeDef *hcan) } /* Config BusOff interrupt. */ - HAL_StatusTypeDef status = HAL_FDCAN_ConfigInterruptLines(can->hcan, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); + status = HAL_FDCAN_ConfigInterruptLines(can->hcan, FDCAN_IT_BUS_OFF, FDCAN_INTERRUPT_LINE1); if (status != HAL_OK) { 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); From 38575e1675ae9ce0df8cacde9c368045b21a01fe Mon Sep 17 00:00:00 2001 From: Caio DaSilva Date: Sun, 19 Apr 2026 20:12:43 -0400 Subject: [PATCH 4/4] cleanup --- platforms/stm32h563/src/fdcan.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/platforms/stm32h563/src/fdcan.c b/platforms/stm32h563/src/fdcan.c index 7c6f9a34..082528e3 100644 --- a/platforms/stm32h563/src/fdcan.c +++ b/platforms/stm32h563/src/fdcan.c @@ -40,11 +40,6 @@ HAL_StatusTypeDef can_init(can_t *can, FDCAN_HandleTypeDef *hcan) printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, 1); (Status: %d).\n", status); return status; } - // status = HAL_FDCAN_ActivateNotification(can->hcan, FDCAN_IT_BUS_OFF, 0); - // if(status != HAL_OK) { - // printf("[fdcan.c/can_init()] ERROR: Failed to run HAL_FDCAN_ConfigInterruptLines() for FDCAN_IT_BUS_OFF (Status: %d).\n", status); - // } - // this is the direct code from the st guy /* Set up the global filter to reject all messages by default. You must explicitly add messages to your filters in the app layer to receive them. */ status = HAL_FDCAN_ConfigGlobalFilter(hcan, FDCAN_REJECT, FDCAN_REJECT, FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE);