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