1 /*
2 * Copyright (c) 2006-2022, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2022-08-04 tangzz98 first version
9 *
10 */
11
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 #include "driver/uart.h"
15 #include "hal/uart_hal.h"
16 #include "sdkconfig.h"
17
18 #ifdef RT_USING_SERIAL_V1
19
20 #ifdef CONFIG_UART_ISR_IN_IRAM
21 #define UART_ISR_ATTR IRAM_ATTR
22 #else
23 #define UART_ISR_ATTR
24 #endif
25
26 uart_hal_context_t hal[] = {
27 {
28 .dev = &UART0,
29 },
30 {
31 .dev = &UART1,
32 },
33 };
34
35 static struct rt_serial_device _serial;
36
mcu_uart_rx_intr_handler(void * param)37 static void mcu_uart_rx_intr_handler(void *param)
38 {
39 uint32_t uart_intr_status;
40 struct rt_serial_device *serial;
41 uart_port_t port;
42 rt_interrupt_enter();
43 serial = (struct rt_serial_device *)param;
44 port = (uart_port_t)serial->parent.user_data;
45 uart_intr_status = uart_hal_get_intsts_mask(&hal[port]);
46 if (uart_intr_status != 0)
47 {
48 if (uart_intr_status & UART_INTR_RXFIFO_FULL)
49 {
50 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
51 }
52 uart_hal_clr_intsts_mask(&hal[port], uart_intr_status);
53 }
54 rt_interrupt_leave();
55 }
56
mcu_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)57 static rt_err_t mcu_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
58 {
59 return RT_EOK;
60 }
61
mcu_uart_control(struct rt_serial_device * serial,int cmd,void * arg)62 static rt_err_t mcu_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
63 {
64 return RT_EOK;
65 }
66
mcu_uart_putc(struct rt_serial_device * serial,char c)67 static int mcu_uart_putc(struct rt_serial_device *serial, char c)
68 {
69 uart_port_t port = (uart_port_t)serial->parent.user_data;
70 uint32_t write_size = 0;
71 do
72 {
73 uart_hal_write_txfifo(&hal[port], (const uint8_t *)&c, 1, &write_size);
74 } while (write_size == 0);
75
76 return 1;
77 }
78
mcu_uart_getc(struct rt_serial_device * serial)79 static int mcu_uart_getc(struct rt_serial_device *serial)
80 {
81 uart_port_t port = (uart_port_t)serial->parent.user_data;
82 uint8_t c;
83 int len = uart_hal_get_rxfifo_len(&hal[port]);
84 if (len == 0)
85 {
86 return -1;
87 }
88 else
89 {
90 len = 1;
91 uart_hal_read_rxfifo(&hal[port], &c, &len);
92 return (int)c;
93 }
94 }
95
96 static const struct rt_uart_ops _uart_ops =
97 {
98 mcu_uart_configure,
99 mcu_uart_control,
100 mcu_uart_putc,
101 mcu_uart_getc,
102 RT_NULL,
103 };
104
rt_hw_uart_init(void)105 int rt_hw_uart_init(void)
106 {
107 uart_intr_config_t uart_intr = {
108 .intr_enable_mask = UART_INTR_RXFIFO_FULL,
109 .rxfifo_full_thresh = 1,
110 };
111 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
112 uart_config_t uart_config = {
113 .baud_rate = BAUD_RATE_115200,
114 .data_bits = UART_DATA_8_BITS,
115 .parity = UART_PARITY_DISABLE,
116 .stop_bits = UART_STOP_BITS_1,
117 .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
118 .source_clk = UART_SCLK_APB,
119 };
120 int intr_alloc_flags = 0;
121
122 #if CONFIG_UART_ISR_IN_IRAM
123 intr_alloc_flags = ESP_INTR_FLAG_IRAM;
124 #endif
125
126 ESP_ERROR_CHECK(uart_param_config(RT_BSP_UART_PORT, &uart_config));
127 ESP_ERROR_CHECK(uart_set_pin(RT_BSP_UART_PORT, RT_BSP_UART_TX_PIN, RT_BSP_UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
128 ESP_ERROR_CHECK(esp_intr_alloc(uart_periph_signal[RT_BSP_UART_PORT].irq, intr_alloc_flags, mcu_uart_rx_intr_handler, (void *)&_serial, NULL));
129 ESP_ERROR_CHECK(uart_intr_config(RT_BSP_UART_PORT, &uart_intr));
130 _serial.ops = &_uart_ops;
131 _serial.config = config;
132
133 return rt_hw_serial_register(&_serial, "uart", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, (void *)RT_BSP_UART_PORT);
134 }
135 INIT_BOARD_EXPORT(rt_hw_uart_init);
136
137 #endif /* RT_USING_SERIAL_V1 */
138