drivers: can: stm32: add statistics support

Add CAN controller statistics support to the STM32 bxCAN driver.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
Henrik Brix Andersen 2022-02-25 11:10:38 +01:00 committed by Marti Bolivar
commit 00a3a0f184

View file

@ -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)