1 /*
2  * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-07-01     lik          first version
9  */
10 
11 #include "drv_uart.h"
12 
13 #ifdef RT_USING_SERIAL
14 #ifdef BSP_USING_UART
15 
16 //#define DRV_DEBUG
17 #define LOG_TAG "drv.uart"
18 #include <drv_log.h>
19 
20 #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
21     !defined(BSP_USING_UART3)
22 #error "Please define at least one BSP_USING_UARTx"
23 /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
24 #endif
25 
26 #ifdef BSP_USING_UART0
27 #ifndef UART0_CFG
28 #define UART0_CFG                                   \
29     {                                               \
30         .name = "uart0",                            \
31         .UARTx = UART0,                             \
32         .irq = UART0_IRQn,                          \
33         .uart_initstruct.Baudrate = 115200,         \
34         .uart_initstruct.DataBits = UART_DATA_8BIT, \
35         .uart_initstruct.Parity = UART_PARITY_NONE, \
36         .uart_initstruct.StopBits = UART_STOP_1BIT, \
37         .uart_initstruct.RXThreshold = 0,           \
38         .uart_initstruct.RXThresholdIEn = 1,        \
39         .uart_initstruct.TXThresholdIEn = 0,        \
40         .uart_initstruct.TimeoutTime = 10,          \
41         .uart_initstruct.TimeoutIEn = 1,            \
42     }
43 #endif /* UART0_CFG */
44 #endif /* BSP_USING_UART0 */
45 
46 #ifdef BSP_USING_UART1
47 #ifndef UART1_CFG
48 #define UART1_CFG                                   \
49     {                                               \
50         .name = "uart1",                            \
51         .UARTx = UART1,                             \
52         .irq = UART1_IRQn,                          \
53         .uart_initstruct.Baudrate = 115200,         \
54         .uart_initstruct.DataBits = UART_DATA_8BIT, \
55         .uart_initstruct.Parity = UART_PARITY_NONE, \
56         .uart_initstruct.StopBits = UART_STOP_1BIT, \
57         .uart_initstruct.RXThreshold = 0,           \
58         .uart_initstruct.RXThresholdIEn = 1,        \
59         .uart_initstruct.TXThresholdIEn = 0,        \
60         .uart_initstruct.TimeoutTime = 10,          \
61         .uart_initstruct.TimeoutIEn = 1,            \
62     }
63 #endif /* UART1_CFG */
64 #endif /* BSP_USING_UART1 */
65 
66 #ifdef BSP_USING_UART2
67 #ifndef UART2_CFG
68 #define UART2_CFG                                   \
69     {                                               \
70         .name = "uart2",                            \
71         .UARTx = UART2,                             \
72         .irq = UART2_IRQn,                          \
73         .uart_initstruct.Baudrate = 115200,         \
74         .uart_initstruct.DataBits = UART_DATA_8BIT, \
75         .uart_initstruct.Parity = UART_PARITY_NONE, \
76         .uart_initstruct.StopBits = UART_STOP_1BIT, \
77         .uart_initstruct.RXThreshold = 0,           \
78         .uart_initstruct.RXThresholdIEn = 1,        \
79         .uart_initstruct.TXThresholdIEn = 0,        \
80         .uart_initstruct.TimeoutTime = 10,          \
81         .uart_initstruct.TimeoutIEn = 1,            \
82     }
83 #endif /* UART2_CFG */
84 #endif /* BSP_USING_UART2 */
85 
86 #ifdef BSP_USING_UART3
87 #ifndef UART3_CFG
88 #define UART3_CFG                                   \
89     {                                               \
90         .name = "uart3",                            \
91         .UARTx = UART3,                             \
92         .irq = UART3_IRQn,                          \
93         .uart_initstruct.Baudrate = 115200,         \
94         .uart_initstruct.DataBits = UART_DATA_8BIT, \
95         .uart_initstruct.Parity = UART_PARITY_NONE, \
96         .uart_initstruct.StopBits = UART_STOP_1BIT, \
97         .uart_initstruct.RXThreshold = 0,           \
98         .uart_initstruct.RXThresholdIEn = 1,        \
99         .uart_initstruct.TXThresholdIEn = 0,        \
100         .uart_initstruct.TimeoutTime = 10,          \
101         .uart_initstruct.TimeoutIEn = 1,            \
102     }
103 #endif /* UART3_CFG */
104 #endif /* BSP_USING_UART3 */
105 
106 /* swm config class */
107 struct swm_uart_cfg
108 {
109     const char *name;
110     UART_TypeDef *UARTx;
111     IRQn_Type irq;
112     UART_InitStructure uart_initstruct;
113 };
114 
115 /* swm uart dirver class */
116 struct swm_uart_device
117 {
118     struct swm_uart_cfg *uart_cfg;
119     struct rt_serial_device serial_device;
120 };
121 
122 enum
123 {
124 #ifdef BSP_USING_UART0
125     UART0_INDEX,
126 #endif
127 #ifdef BSP_USING_UART1
128     UART1_INDEX,
129 #endif
130 #ifdef BSP_USING_UART2
131     UART2_INDEX,
132 #endif
133 #ifdef BSP_USING_UART3
134     UART3_INDEX,
135 #endif
136 };
137 
138 static struct swm_uart_cfg swm_uart_cfg[] =
139     {
140 #ifdef BSP_USING_UART0
141         UART0_CFG,
142 #endif
143 #ifdef BSP_USING_UART1
144         UART1_CFG,
145 #endif
146 #ifdef BSP_USING_UART2
147         UART2_CFG,
148 #endif
149 #ifdef BSP_USING_UART3
150         UART3_CFG,
151 #endif
152 };
153 
154 static struct swm_uart_device uart_obj[sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0])] = {0};
155 
swm_uart_configure(struct rt_serial_device * serial_device,struct serial_configure * configure)156 static rt_err_t swm_uart_configure(struct rt_serial_device *serial_device, struct serial_configure *configure)
157 {
158     struct swm_uart_cfg *uart_cfg;
159     RT_ASSERT(serial_device != RT_NULL);
160     RT_ASSERT(configure != RT_NULL);
161     uart_cfg = serial_device->parent.user_data;
162 
163     uart_cfg->uart_initstruct.Baudrate = configure->baud_rate;
164     switch (configure->data_bits)
165     {
166     case DATA_BITS_8:
167         uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
168         break;
169     case DATA_BITS_9:
170         uart_cfg->uart_initstruct.DataBits = UART_DATA_9BIT;
171         break;
172     default:
173         uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
174         break;
175     }
176     switch (configure->stop_bits)
177     {
178     case STOP_BITS_1:
179         uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
180         break;
181     case STOP_BITS_2:
182         uart_cfg->uart_initstruct.StopBits = UART_STOP_2BIT;
183         break;
184     default:
185         uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
186         break;
187     }
188     switch (configure->parity)
189     {
190     case PARITY_NONE:
191         uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
192         break;
193     case PARITY_ODD:
194         uart_cfg->uart_initstruct.Parity = UART_PARITY_ODD;
195         break;
196     case PARITY_EVEN:
197         uart_cfg->uart_initstruct.Parity = UART_PARITY_EVEN;
198         break;
199     default:
200         uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
201         break;
202     }
203 
204     UART_Init(uart_cfg->UARTx, &(uart_cfg->uart_initstruct));
205     UART_Open(uart_cfg->UARTx);
206     return RT_EOK;
207 }
208 
swm_uart_control(struct rt_serial_device * serial_device,int cmd,void * arg)209 static rt_err_t swm_uart_control(struct rt_serial_device *serial_device, int cmd, void *arg)
210 {
211     struct swm_uart_cfg *uart_cfg;
212     RT_ASSERT(serial_device != RT_NULL);
213     uart_cfg = serial_device->parent.user_data;
214 
215     switch (cmd)
216     {
217     case RT_DEVICE_CTRL_CLR_INT:
218         /* disable rx irq */
219         NVIC_DisableIRQ(uart_cfg->irq);
220         break;
221     case RT_DEVICE_CTRL_SET_INT:
222         /* enable rx irq */
223         NVIC_EnableIRQ(uart_cfg->irq);
224         break;
225     }
226     return RT_EOK;
227 }
228 
swm_uart_putc(struct rt_serial_device * serial_device,char c)229 static int swm_uart_putc(struct rt_serial_device *serial_device, char c)
230 {
231     struct swm_uart_cfg *uart_cfg;
232     RT_ASSERT(serial_device != RT_NULL);
233     uart_cfg = serial_device->parent.user_data;
234 
235     UART_WriteByte(uart_cfg->UARTx, c);
236     while (UART_IsTXBusy(uart_cfg->UARTx))
237         ;
238     return 1;
239 }
240 
swm_uart_getc(struct rt_serial_device * serial_device)241 static int swm_uart_getc(struct rt_serial_device *serial_device)
242 {
243     int ch;
244     struct swm_uart_cfg *uart_cfg;
245     RT_ASSERT(serial_device != RT_NULL);
246     uart_cfg = serial_device->parent.user_data;
247 
248     ch = -1;
249     if (UART_IsRXFIFOEmpty(uart_cfg->UARTx) == 0)
250     {
251         UART_ReadByte(uart_cfg->UARTx, (uint32_t *)&ch);
252     }
253     return ch;
254 }
255 
256 static const struct rt_uart_ops swm_uart_ops =
257     {
258         .configure = swm_uart_configure,
259         .control = swm_uart_control,
260         .putc = swm_uart_putc,
261         .getc = swm_uart_getc,
262         .dma_transmit = RT_NULL};
263 
264 /**
265  * Uart common interrupt process. This need add to uart ISR.
266  *
267  * @param serial serial device
268  */
swm_uart_isr(struct rt_serial_device * serial_device)269 static void swm_uart_isr(struct rt_serial_device *serial_device)
270 {
271     struct swm_uart_cfg *uart_cfg;
272     RT_ASSERT(serial_device != RT_NULL);
273     uart_cfg = serial_device->parent.user_data;
274 
275     /* UART in mode Receiver -------------------------------------------------*/
276     if (UART_INTStat(uart_cfg->UARTx, UART_IT_RX_THR) || UART_INTStat(uart_cfg->UARTx, UART_IT_RX_TOUT))
277     {
278         if(!UART_IsRXFIFOEmpty(uart_cfg->UARTx))
279         {
280             rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_IND);
281         }
282 
283         if(UART_INTStat(uart_cfg->UARTx, UART_IT_RX_TOUT))
284         {
285             UART_INTClr(uart_cfg->UARTx, UART_IT_RX_TOUT);
286 
287             rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_TIMEOUT);
288         }
289     }
290 }
291 
292 #if defined(BSP_USING_UART0)
UART0_Handler(void)293 void UART0_Handler(void)
294 {
295     rt_interrupt_enter();
296     swm_uart_isr(&(uart_obj[UART0_INDEX].serial_device));
297     rt_interrupt_leave();
298 }
299 #endif /* BSP_USING_UART0 */
300 
301 #if defined(BSP_USING_UART1)
UART1_Handler(void)302 void UART1_Handler(void)
303 {
304     rt_interrupt_enter();
305     swm_uart_isr(&(uart_obj[UART1_INDEX].serial_device));
306     rt_interrupt_leave();
307 }
308 #endif /* BSP_USING_UART1 */
309 
310 #if defined(BSP_USING_UART2)
UART2_Handler(void)311 void UART2_Handler(void)
312 {
313     rt_interrupt_enter();
314     swm_uart_isr(&(uart_obj[UART2_INDEX].serial_device));
315     rt_interrupt_leave();
316 }
317 #endif /* BSP_USING_UART2 */
318 
319 #if defined(BSP_USING_UART3)
UART3_Handler(void)320 void UART3_Handler(void)
321 {
322     rt_interrupt_enter();
323     swm_uart_isr(&(uart_obj[UART3_INDEX].serial_device));
324     rt_interrupt_leave();
325 }
326 #endif /* BSP_USING_UART3 */
327 
swm_uart_init(void)328 int swm_uart_init(void)
329 {
330     struct serial_configure serial_cfg = RT_SERIAL_CONFIG_DEFAULT;
331     int i = 0;
332     rt_err_t result = RT_EOK;
333 
334 #ifdef BSP_USING_UART0
335     PORT_Init(PORTM, PIN0, PORTM_PIN0_UART0_RX, 1);
336     PORT_Init(PORTM, PIN1, PORTM_PIN1_UART0_TX, 0);
337 #endif
338 #ifdef BSP_USING_UART1
339     PORT_Init(PORTD, PIN4, PORTD_PIN4_UART1_RX, 1);
340     PORT_Init(PORTD, PIN3, PORTD_PIN3_UART1_TX, 0);
341 #endif
342 #ifdef BSP_USING_UART2
343     PORT_Init(PORTC, PIN1, PORTC_PIN1_UART2_RX, 1);
344     PORT_Init(PORTC, PIN0, PORTC_PIN0_UART2_TX, 0);
345 #endif
346 #ifdef BSP_USING_UART3
347     PORT_Init(PORTC, PIN2, PORTC_PIN2_UART3_RX, 1);
348     PORT_Init(PORTC, PIN3, PORTC_PIN3_UART3_TX, 0);
349 #endif
350 
351     for (i = 0; i < sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0]); i++)
352     {
353         uart_obj[i].uart_cfg = &swm_uart_cfg[i];
354         uart_obj[i].serial_device.ops = &swm_uart_ops;
355         uart_obj[i].serial_device.config = serial_cfg;
356 
357         result = rt_hw_serial_register(&uart_obj[i].serial_device, uart_obj[i].uart_cfg->name,
358                                        RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart_obj[i].uart_cfg);
359         RT_ASSERT(result == RT_EOK);
360     }
361 
362     return result;
363 }
364 
365 #endif /* BSP_USING_UART */
366 #endif /* RT_USING_SERIAL */
367