Commit ebc31f62 authored by Alexander Wachter's avatar Alexander Wachter Committed by Anas Nashif
Browse files

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: default avatarAlexander Wachter <alexander.wachter@student.tugraz.at>
parent 13a96574
Loading
Loading
Loading
Loading
+101 −38
Original line number Diff line number Diff line
@@ -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;
#ifdef CONFIG_SOC_SERIES_STM32F0X

		mbox = &can->sFIFOMailBox[0];
		filter_match_index = ((mbox->RDTR & CAN_RDT0R_FMI)
					   >> CAN_RDT0R_FMI_Pos);
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);

		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);
#else

		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];
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;

				k_msgq_put(msg_q, &msg, K_NO_WAIT);
			} else {
				can_rx_callback_t callback =
					data->rx_response[filter_match_index];
				callback(&msg);
			}
		}
	dev = (struct device *)arg;
	data = DEV_DATA(dev);
	cfg = DEV_CFG(dev);
	can = cfg->can;

		/* Release message */
		can->RF0R |= CAN_RF0R_RFOM0;
	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;
}

+1 −0
Original line number Diff line number Diff line
@@ -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>;
+6 −0
Original line number Diff line number Diff line
@@ -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
...