From 00a3a0f184ef5fcf98dacf910dfd8364ddfebfd9 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Fri, 25 Feb 2022 11:10:38 +0100 Subject: [PATCH] drivers: can: stm32: add statistics support Add CAN controller statistics support to the STM32 bxCAN driver. Signed-off-by: Henrik Brix Andersen --- drivers/can/can_stm32.c | 60 ++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/drivers/can/can_stm32.c b/drivers/can/can_stm32.c index 7e01b7e6c5c..ae6e0adc9ee 100644 --- a/drivers/can/can_stm32.c +++ b/drivers/can/can_stm32.c @@ -118,13 +118,43 @@ void can_stm32_rx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data) } } -static inline void can_stm32_bus_state_change_isr(CAN_TypeDef *can, - struct can_stm32_data *data) +static inline void can_stm32_bus_state_change_isr(const struct device *dev) { + const struct can_stm32_config *cfg = dev->config; + struct can_stm32_data *data = dev->data; struct can_bus_err_cnt err_cnt; enum can_state state; const can_state_change_callback_t cb = data->state_change_cb; void *state_change_cb_data = data->state_change_cb_data; + CAN_TypeDef *can = cfg->can; + +#ifdef CONFIG_CAN_STATS + switch (can->ESR & CAN_ESR_LEC) { + case (CAN_ESR_LEC_0): + CAN_STATS_STUFF_ERROR_INC(dev); + break; + case (CAN_ESR_LEC_1): + CAN_STATS_FORM_ERROR_INC(dev); + break; + case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0): + CAN_STATS_ACK_ERROR_INC(dev); + break; + case (CAN_ESR_LEC_2): + CAN_STATS_BIT1_ERROR_INC(dev); + break; + case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0): + CAN_STATS_BIT0_ERROR_INC(dev); + break; + case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1): + CAN_STATS_CRC_ERROR_INC(dev); + break; + default: + break; + } + + /* Clear last error code flag */ + can->ESR |= CAN_ESR_LEC; +#endif /* CONFIG_CAN_STATS */ if (!(can->ESR & CAN_ESR_EPVF) && !(can->ESR & CAN_ESR_BOFF) && !(can->ESR & CAN_ESR_EWGF)) { @@ -212,7 +242,7 @@ static void can_stm32_isr(const struct device *dev) can_stm32_tx_isr_handler(can, data); can_stm32_rx_isr_handler(can, data); if (can->MSR & CAN_MSR_ERRI) { - can_stm32_bus_state_change_isr(can, data); + can_stm32_bus_state_change_isr(dev); can->MSR |= CAN_MSR_ERRI; } } @@ -259,7 +289,7 @@ static void can_stm32_state_change_isr(const struct device *dev) /*Signal bus-off to waiting tx*/ if (can->MSR & CAN_MSR_ERRI) { can_stm32_tx_isr_handler(can, data); - can_stm32_bus_state_change_isr(can, data); + can_stm32_bus_state_change_isr(dev); can->MSR |= CAN_MSR_ERRI; } } @@ -1167,10 +1197,10 @@ static const struct can_stm32_config can_stm32_cfg_1 = { static struct can_stm32_data can_stm32_dev_data_1; -DEVICE_DT_DEFINE(DT_NODELABEL(can1), &can_stm32_init, NULL, - &can_stm32_dev_data_1, &can_stm32_cfg_1, - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, - &can_api_funcs); +CAN_DEVICE_DT_DEFINE(DT_NODELABEL(can1), can_stm32_init, NULL, + &can_stm32_dev_data_1, &can_stm32_cfg_1, + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, + &can_api_funcs); static void config_can_1_irq(CAN_TypeDef *can) { @@ -1199,6 +1229,9 @@ static void config_can_1_irq(CAN_TypeDef *can) #endif can->IER |= CAN_IER_TMEIE | CAN_IER_ERRIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_BOFIE; +#ifdef CONFIG_CAN_STATS + can->IER |= CAN_IER_LECIE; +#endif /* CONFIG_CAN_STATS */ } #if defined(CONFIG_NET_SOCKETS_CAN) @@ -1265,10 +1298,10 @@ static const struct can_stm32_config can_stm32_cfg_2 = { static struct can_stm32_data can_stm32_dev_data_2; -DEVICE_DT_DEFINE(DT_NODELABEL(can2), &can_stm32_init, NULL, - &can_stm32_dev_data_2, &can_stm32_cfg_2, - POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, - &can_api_funcs); +CAN_DEVICE_DT_DEFINE(DT_NODELABEL(can2), can_stm32_init, NULL, + &can_stm32_dev_data_2, &can_stm32_cfg_2, + POST_KERNEL, CONFIG_CAN_INIT_PRIORITY, + &can_api_funcs); static void config_can_2_irq(CAN_TypeDef *can) { @@ -1290,6 +1323,9 @@ static void config_can_2_irq(CAN_TypeDef *can) irq_enable(DT_IRQ_BY_NAME(DT_NODELABEL(can2), sce, irq)); can->IER |= CAN_IER_TMEIE | CAN_IER_ERRIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_BOFIE; +#ifdef CONFIG_CAN_STATS + can->IER |= CAN_IER_LECIE; +#endif /* CONFIG_CAN_STATS */ } #if defined(CONFIG_NET_SOCKETS_CAN)