From ebc31f623538fbcf90041a7da87fa36ebac197a9 Mon Sep 17 00:00:00 2001 From: Alexander Wachter Date: Wed, 23 May 2018 10:54:56 +0200 Subject: [PATCH] drivers: can: Prepare STM32 driver for other series than STM32F0 This commit splits the common interrupt into rx and tx parts because only STM32F0 series has a common interrupt. Moved clock source definition to device-tree. Signed-off-by: Alexander Wachter --- drivers/can/stm32_can.c | 153 ++++++++++++++++++++--------- dts/arm/st/stm32f072.dtsi | 1 + dts/bindings/can/st,stm32-can.yaml | 6 ++ 3 files changed, 115 insertions(+), 45 deletions(-) diff --git a/drivers/can/stm32_can.c b/drivers/can/stm32_can.c index 55f875a1085..6fd79b1ef7c 100644 --- a/drivers/can/stm32_can.c +++ b/drivers/can/stm32_can.c @@ -43,18 +43,47 @@ static inline void can_stm32_get_msg_fifo(CAN_FIFOMailBox_TypeDef *mbox, msg->data_32[1] = mbox->RDHR; } -static void can_stm32_isr(void *arg) +static inline +void can_stm32_rx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data) { - struct device *dev; - struct can_stm32_data *data; - const struct can_stm32_config *cfg; - CAN_TypeDef *can; - u32_t bus_off; + CAN_FIFOMailBox_TypeDef *mbox; + int filter_match_index; + struct can_msg msg; - dev = (struct device *)arg; - data = DEV_DATA(dev); - cfg = DEV_CFG(dev); - can = cfg->can; + while (can->RF0R & CAN_RF0R_FMP0) { + mbox = &can->sFIFOMailBox[0]; + filter_match_index = ((mbox->RDTR & CAN_RDT0R_FMI) + >> CAN_RDT0R_FMI_Pos); + + if (filter_match_index >= CONFIG_CAN_MAX_FILTER) { + break; + } + + SYS_LOG_DBG("Message on filter index %d", filter_match_index); + can_stm32_get_msg_fifo(mbox, &msg); + + if (data->rx_response[filter_match_index]) { + if (data->response_type & (1ULL << filter_match_index)) { + struct k_msgq *msg_q = + data->rx_response[filter_match_index]; + + k_msgq_put(msg_q, &msg, K_NO_WAIT); + } else { + can_rx_callback_t callback = + data->rx_response[filter_match_index]; + callback(&msg); + } + } + + /* Release message */ + can->RF0R |= CAN_RF0R_RFOM0; + } +} + +static inline +void can_stm32_tx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data) +{ + u32_t bus_off; bus_off = can->ESR & CAN_ESR_BOFF; @@ -97,41 +126,61 @@ static void can_stm32_isr(void *arg) if (can->TSR & CAN_TSR_TME) { k_sem_give(&data->tx_int_sem); } - - while (can->RF0R & CAN_RF0R_FMP0) { - CAN_FIFOMailBox_TypeDef *mbox; - int filter_match_index; - struct can_msg msg; - - mbox = &can->sFIFOMailBox[0]; - filter_match_index = ((mbox->RDTR & CAN_RDT0R_FMI) - >> CAN_RDT0R_FMI_Pos); - - if (filter_match_index >= CONFIG_CAN_MAX_FILTER) { - break; - } - - SYS_LOG_DBG("Message on filter index %d", filter_match_index); - can_stm32_get_msg_fifo(mbox, &msg); - - if (data->rx_response[filter_match_index]) { - if (data->response_type & (1ULL << filter_match_index)) { - struct k_msgq *msg_q = - data->rx_response[filter_match_index]; - - k_msgq_put(msg_q, &msg, K_NO_WAIT); - } else { - can_rx_callback_t callback = - data->rx_response[filter_match_index]; - callback(&msg); - } - } - - /* Release message */ - can->RF0R |= CAN_RF0R_RFOM0; - } } +#ifdef CONFIG_SOC_SERIES_STM32F0X + +static void can_stm32_isr(void *arg) +{ + struct device *dev; + struct can_stm32_data *data; + const struct can_stm32_config *cfg; + CAN_TypeDef *can; + + dev = (struct device *)arg; + data = DEV_DATA(dev); + cfg = DEV_CFG(dev); + can = cfg->can; + + can_stm32_tx_isr_handler(can, data); + can_stm32_rx_isr_handler(can, data); + +} + +#else + +static void can_stm32_rx_isr(void *arg) +{ + struct device *dev; + struct can_stm32_data *data; + const struct can_stm32_config *cfg; + CAN_TypeDef *can; + + dev = (struct device *)arg; + data = DEV_DATA(dev); + cfg = DEV_CFG(dev); + can = cfg->can; + + can_stm32_rx_isr_handler(can, data); +} + +static void can_stm32_tx_isr(void *arg) +{ + struct device *dev; + struct can_stm32_data *data; + const struct can_stm32_config *cfg; + CAN_TypeDef *can; + + dev = (struct device *)arg; + data = DEV_DATA(dev); + cfg = DEV_CFG(dev); + can = cfg->can; + + can_stm32_tx_isr_handler(can, data); +} + +#endif + void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan) { ARG_UNUSED(hcan); @@ -798,8 +847,8 @@ static const struct can_stm32_config can_stm32_cfg_1 = { .prop_bs1 = CONFIG_CAN_1_PROP_SEG_PHASE_SEG1, .bs2 = CONFIG_CAN_1_PHASE_SEG2, .pclken = { - .enr = RCC_APB1ENR_CANEN, - .bus = STM32_CLOCK_BUS_APB1, + .enr = CONFIG_CAN_1_CLOCK_BITS, + .bus = CONFIG_CAN_1_CLOCK_BUS, }, .config_irq = config_can_1_irq }; @@ -814,9 +863,23 @@ DEVICE_AND_API_INIT(can_stm32_1, CONFIG_CAN_1_NAME, &can_stm32_init, static void config_can_1_irq(CAN_TypeDef *can) { SYS_LOG_DBG("Enable CAN1 IRQ"); +#ifdef CONFIG_SOC_SERIES_STM32F0X IRQ_CONNECT(CONFIG_CAN_1_IRQ, CONFIG_CAN_1_IRQ_PRIORITY, can_stm32_isr, DEVICE_GET(can_stm32_1), 0); irq_enable(CONFIG_CAN_1_IRQ); +#else + IRQ_CONNECT(CONFIG_CAN_1_IRQ_RX0, CONFIG_CAN_1_IRQ_PRIORITY, + can_stm32_rx_isr, DEVICE_GET(can_stm32_1), 0); + irq_enable(CONFIG_CAN_1_IRQ_RX0); + + IRQ_CONNECT(CONFIG_CAN_1_IRQ_TX, CONFIG_CAN_1_IRQ_PRIORITY, + can_stm32_tx_isr, DEVICE_GET(can_stm32_1), 0); + irq_enable(CONFIG_CAN_1_IRQ_TX); + + IRQ_CONNECT(CONFIG_CAN_1_IRQ_SCE, CONFIG_CAN_1_IRQ_PRIORITY, + can_stm32_tx_isr, DEVICE_GET(can_stm32_1), 0); + irq_enable(CONFIG_CAN_1_IRQ_SCE); +#endif can->IER |= CAN_IT_TME | CAN_IT_ERR | CAN_IT_FMP0 | CAN_IT_FMP1; } diff --git a/dts/arm/st/stm32f072.dtsi b/dts/arm/st/stm32f072.dtsi index fedf0e5c801..73551f9d33b 100644 --- a/dts/arm/st/stm32f072.dtsi +++ b/dts/arm/st/stm32f072.dtsi @@ -64,6 +64,7 @@ #size-cells = <0>; reg = <0x40006400 0x400>; interrupts = <30 0>; + clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>; status = "disabled"; label = "CAN_1"; bus-speed = <250000>; diff --git a/dts/bindings/can/st,stm32-can.yaml b/dts/bindings/can/st,stm32-can.yaml index 714b108cb6e..1f9797c104d 100644 --- a/dts/bindings/can/st,stm32-can.yaml +++ b/dts/bindings/can/st,stm32-can.yaml @@ -45,4 +45,10 @@ properties: category: required description: tx pin name generation: define + + clocks: + type: array + category: required + description: Clock gate control information + generation: define ...