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 <alexander.wachter@student.tugraz.at>
This commit is contained in:
parent
13a96574cd
commit
ebc31f6235
3 changed files with 115 additions and 45 deletions
|
@ -43,18 +43,47 @@ static inline void can_stm32_get_msg_fifo(CAN_FIFOMailBox_TypeDef *mbox,
|
||||||
msg->data_32[1] = mbox->RDHR;
|
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;
|
CAN_FIFOMailBox_TypeDef *mbox;
|
||||||
struct can_stm32_data *data;
|
int filter_match_index;
|
||||||
const struct can_stm32_config *cfg;
|
struct can_msg msg;
|
||||||
CAN_TypeDef *can;
|
|
||||||
u32_t bus_off;
|
|
||||||
|
|
||||||
dev = (struct device *)arg;
|
while (can->RF0R & CAN_RF0R_FMP0) {
|
||||||
data = DEV_DATA(dev);
|
mbox = &can->sFIFOMailBox[0];
|
||||||
cfg = DEV_CFG(dev);
|
filter_match_index = ((mbox->RDTR & CAN_RDT0R_FMI)
|
||||||
can = cfg->can;
|
>> 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;
|
bus_off = can->ESR & CAN_ESR_BOFF;
|
||||||
|
|
||||||
|
@ -97,41 +126,61 @@ static void can_stm32_isr(void *arg)
|
||||||
if (can->TSR & CAN_TSR_TME) {
|
if (can->TSR & CAN_TSR_TME) {
|
||||||
k_sem_give(&data->tx_int_sem);
|
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)
|
void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(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,
|
.prop_bs1 = CONFIG_CAN_1_PROP_SEG_PHASE_SEG1,
|
||||||
.bs2 = CONFIG_CAN_1_PHASE_SEG2,
|
.bs2 = CONFIG_CAN_1_PHASE_SEG2,
|
||||||
.pclken = {
|
.pclken = {
|
||||||
.enr = RCC_APB1ENR_CANEN,
|
.enr = CONFIG_CAN_1_CLOCK_BITS,
|
||||||
.bus = STM32_CLOCK_BUS_APB1,
|
.bus = CONFIG_CAN_1_CLOCK_BUS,
|
||||||
},
|
},
|
||||||
.config_irq = config_can_1_irq
|
.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)
|
static void config_can_1_irq(CAN_TypeDef *can)
|
||||||
{
|
{
|
||||||
SYS_LOG_DBG("Enable CAN1 IRQ");
|
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,
|
IRQ_CONNECT(CONFIG_CAN_1_IRQ, CONFIG_CAN_1_IRQ_PRIORITY, can_stm32_isr,
|
||||||
DEVICE_GET(can_stm32_1), 0);
|
DEVICE_GET(can_stm32_1), 0);
|
||||||
irq_enable(CONFIG_CAN_1_IRQ);
|
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;
|
can->IER |= CAN_IT_TME | CAN_IT_ERR | CAN_IT_FMP0 | CAN_IT_FMP1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
reg = <0x40006400 0x400>;
|
reg = <0x40006400 0x400>;
|
||||||
interrupts = <30 0>;
|
interrupts = <30 0>;
|
||||||
|
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
label = "CAN_1";
|
label = "CAN_1";
|
||||||
bus-speed = <250000>;
|
bus-speed = <250000>;
|
||||||
|
|
|
@ -45,4 +45,10 @@ properties:
|
||||||
category: required
|
category: required
|
||||||
description: tx pin name
|
description: tx pin name
|
||||||
generation: define
|
generation: define
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
type: array
|
||||||
|
category: required
|
||||||
|
description: Clock gate control information
|
||||||
|
generation: define
|
||||||
...
|
...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue