From 56e47668d59b0947c9e969e415d6a797b0704b58 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 17 Dec 2015 12:46:10 +0000 Subject: Added CAN transmission errors handling. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8613 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/CANv1/can_lld.c | 48 ++++++++++++++++++++++++--- os/hal/ports/STM32/LLD/CANv1/can_lld.h | 10 ++++-- os/hal/ports/STM32/STM32L4xx/stm32_registry.h | 8 +++++ 3 files changed, 58 insertions(+), 8 deletions(-) (limited to 'os/hal/ports') 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 -- cgit v1.2.3