diff --git a/os/hal/include/can.h b/os/hal/include/can.h
index 9fd9a09ca..fe4386089 100644
--- a/os/hal/include/can.h
+++ b/os/hal/include/can.h
@@ -38,23 +38,23 @@
/**
* @brief Errors rate warning.
*/
-#define CAN_LIMIT_WARNING 1
+#define CAN_LIMIT_WARNING 1U
/**
* @brief Errors rate error.
*/
-#define CAN_LIMIT_ERROR 2
+#define CAN_LIMIT_ERROR 2U
/**
* @brief Bus off condition reached.
*/
-#define CAN_BUS_OFF_ERROR 4
+#define CAN_BUS_OFF_ERROR 4U
/**
* @brief Framing error of some kind on the CAN bus.
*/
-#define CAN_FRAMING_ERROR 8
+#define CAN_FRAMING_ERROR 8U
/**
* @brief Overflow in receive queue.
*/
-#define CAN_OVERFLOW_ERROR 16
+#define CAN_OVERFLOW_ERROR 16U
/** @} */
/**
@@ -113,7 +113,7 @@ typedef enum {
/**
* @brief Converts a mailbox index to a bit mask.
*/
-#define CAN_MAILBOX_TO_MASK(mbx) (1 << ((mbx) - 1))
+#define CAN_MAILBOX_TO_MASK(mbx) (1U << ((mbx) - 1U))
/** @} */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/LLD/CANv1/can_lld.c b/os/hal/ports/STM32/LLD/CANv1/can_lld.c
index 7bca76d8e..485a08c79 100644
--- a/os/hal/ports/STM32/LLD/CANv1/can_lld.c
+++ b/os/hal/ports/STM32/LLD/CANv1/can_lld.c
@@ -142,12 +142,50 @@ static void can_lld_set_filters(uint32_t can2sb,
* @notapi
*/
static void can_lld_tx_handler(CANDriver *canp) {
+ uint32_t tsr;
+ eventflags_t flags;
- /* No more events until a message is transmitted.*/
- canp->can->TSR = CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2;
+ /* Clearing IRQ sources.*/
+ tsr = canp->can->TSR;
+ canp->can->TSR = tsr;
+
+ /* Flags to be signaled through the TX event source.*/
+ flags = 0U;
+
+ /* Checking mailbox 0.*/
+ if ((tsr & CAN_TSR_RQCP0) != 0U) {
+ if ((tsr & (CAN_TSR_ALST0 | CAN_TSR_TERR0)) != 0U) {
+ flags |= CAN_MAILBOX_TO_MASK(1U) << 16U;
+ }
+ else {
+ flags |= CAN_MAILBOX_TO_MASK(1U);
+ }
+ }
+
+ /* Checking mailbox 1.*/
+ if ((tsr & CAN_TSR_RQCP1) != 0U) {
+ if ((tsr & (CAN_TSR_ALST1 | CAN_TSR_TERR1)) != 0U) {
+ flags |= CAN_MAILBOX_TO_MASK(2U) << 16U;
+ }
+ else {
+ flags |= CAN_MAILBOX_TO_MASK(2U);
+ }
+ }
+
+ /* Checking mailbox 2.*/
+ if ((tsr & CAN_TSR_RQCP2) != 0U) {
+ if ((tsr & (CAN_TSR_ALST2 | CAN_TSR_TERR2)) != 0U) {
+ flags |= CAN_MAILBOX_TO_MASK(3U) << 16U;
+ }
+ else {
+ flags |= CAN_MAILBOX_TO_MASK(3U);
+ }
+ }
+
+ /* Signaling flags and waking up threads waiting for a transmission slot.*/
osalSysLockFromISR();
osalThreadDequeueAllI(&canp->txqueue, MSG_OK);
- osalEventBroadcastFlagsI(&canp->txempty_event, CAN_MAILBOX_TO_MASK(1));
+ osalEventBroadcastFlagsI(&canp->txempty_event, flags);
osalSysUnlockFromISR();
}
@@ -167,7 +205,7 @@ static void can_lld_rx0_handler(CANDriver *canp) {
canp->can->IER &= ~CAN_IER_FMPIE0;
osalSysLockFromISR();
osalThreadDequeueAllI(&canp->rxqueue, MSG_OK);
- osalEventBroadcastFlagsI(&canp->rxfull_event, CAN_MAILBOX_TO_MASK(1));
+ osalEventBroadcastFlagsI(&canp->rxfull_event, CAN_MAILBOX_TO_MASK(1U));
osalSysUnlockFromISR();
}
if ((rf0r & CAN_RF0R_FOVR0) > 0) {
@@ -195,7 +233,7 @@ static void can_lld_rx1_handler(CANDriver *canp) {
canp->can->IER &= ~CAN_IER_FMPIE1;
osalSysLockFromISR();
osalThreadDequeueAllI(&canp->rxqueue, MSG_OK);
- osalEventBroadcastFlagsI(&canp->rxfull_event, CAN_MAILBOX_TO_MASK(2));
+ osalEventBroadcastFlagsI(&canp->rxfull_event, CAN_MAILBOX_TO_MASK(2U));
osalSysUnlockFromISR();
}
if ((rf1r & CAN_RF1R_FOVR1) > 0) {
diff --git a/os/hal/ports/STM32/LLD/CANv1/can_lld.h b/os/hal/ports/STM32/LLD/CANv1/can_lld.h
index 6297449c6..4a288cf3e 100644
--- a/os/hal/ports/STM32/LLD/CANv1/can_lld.h
+++ b/os/hal/ports/STM32/LLD/CANv1/can_lld.h
@@ -282,7 +282,7 @@ typedef struct {
* until the received frames queue has been completely emptied. It
* is not broadcasted for each received frame. It is
* responsibility of the application to empty the queue by
- * repeatedly invoking @p chReceive() when listening to this event.
+ * repeatedly invoking @p canReceive() when listening to this event.
* This behavior minimizes the interrupt served by the system
* because CAN traffic.
* @note The flags associated to the listeners will indicate which
@@ -293,13 +293,17 @@ typedef struct {
* @brief One or more transmission mailbox become available.
* @note The flags associated to the listeners will indicate which
* transmit mailboxes become empty.
+ * @note The upper 16 bits are transmission error flags associated
+ * to the transmit mailboxes.
*
*/
event_source_t txempty_event;
/**
* @brief A CAN bus error happened.
- * @note The flags associated to the listeners will indicate the
- * error(s) that have occurred.
+ * @note The flags associated to the listeners will indicate that
+ * receive error(s) have occurred.
+ * @note In this implementation the upper 16 bits are filled with the
+ * unprocessed content of the ESR register.
*/
event_source_t error_event;
#if CAN_USE_SLEEP_MODE || defined (__DOXYGEN__)
diff --git a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
index 4c684760d..95bb46a10 100644
--- a/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
+++ b/os/hal/ports/STM32/STM32L4xx/stm32_registry.h
@@ -61,6 +61,14 @@
#define STM32_HAS_CAN1 TRUE
#define STM32_HAS_CAN2 FALSE
#define STM32_CAN_MAX_FILTERS 14
+#define STM32_CAN1_TX_HANDLER Vector8C
+#define STM32_CAN1_RX0_HANDLER Vector90
+#define STM32_CAN1_RX1_HANDLER Vector94
+#define STM32_CAN1_SCE_HANDLER Vector98
+#define STM32_CAN1_TX_NUMBER 19
+#define STM32_CAN1_RX0_NUMBER 20
+#define STM32_CAN1_RX1_NUMBER 21
+#define STM32_CAN1_SCE_NUMBER 22
/* DAC attributes.*/
#define STM32_HAS_DAC1_CH1 TRUE
diff --git a/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch b/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch
index 30b653f3f..f3fc038e1 100644
--- a/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch
+++ b/testhal/STM32/STM32L4xx/CAN/debug/STM32L4xx-CAN (OpenOCD, Flash and Run).launch
@@ -33,7 +33,7 @@
-
+