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-02-22 airm2m first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "board.h"
14 #include "drv_usart.h"
15
16 #ifdef RT_USING_SERIAL
17
18 #define LOG_TAG "drv.usart"
19 #include <drv_log.h>
20
21 #if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) && \
22 !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6) && \
23 !defined(BSP_USING_UART7) && !defined(BSP_USING_UART8)
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 /* air32 config class */
29 struct air32_uart_config
30 {
31 const char *name;
32 USART_TypeDef *Instance;
33 IRQn_Type irq_type;
34 };
35
36 /* air32 uart dirver class */
37 struct air32_uart
38 {
39 USART_InitTypeDef Init;
40 struct air32_uart_config *config;
41 struct rt_serial_device serial;
42 };
43
44 #if defined(BSP_USING_UART1)
45 #ifndef UART1_CONFIG
46 #define UART1_CONFIG \
47 { \
48 .name = "uart1", \
49 .Instance = USART1, \
50 .irq_type = USART1_IRQn, \
51 }
52 #endif /* UART1_CONFIG */
53 #endif /* BSP_USING_UART1 */
54
55 #if defined(BSP_USING_UART2)
56 #ifndef UART2_CONFIG
57 #define UART2_CONFIG \
58 { \
59 .name = "uart2", \
60 .Instance = USART2, \
61 .irq_type = USART2_IRQn, \
62 }
63 #endif /* UART2_CONFIG */
64 #endif /* BSP_USING_UART2 */
65
66 #if defined(BSP_USING_UART3)
67 #ifndef UART3_CONFIG
68 #define UART3_CONFIG \
69 { \
70 .name = "uart3", \
71 .Instance = USART3, \
72 .irq_type = USART3_IRQn, \
73 }
74 #endif /* UART3_CONFIG */
75 #endif /* BSP_USING_UART3 */
76
77
78 enum
79 {
80 #ifdef BSP_USING_UART1
81 UART1_INDEX,
82 #endif
83 #ifdef BSP_USING_UART2
84 UART2_INDEX,
85 #endif
86 #ifdef BSP_USING_UART3
87 UART3_INDEX,
88 #endif
89 #ifdef BSP_USING_UART4
90 UART4_INDEX,
91 #endif
92 #ifdef BSP_USING_UART5
93 UART5_INDEX,
94 #endif
95 #ifdef BSP_USING_UART6
96 UART6_INDEX,
97 #endif
98 #ifdef BSP_USING_UART7
99 UART7_INDEX,
100 #endif
101 #ifdef BSP_USING_UART8
102 UART8_INDEX,
103 #endif
104 };
105
106 static struct air32_uart_config uart_config[] =
107 {
108 #ifdef BSP_USING_UART1
109 UART1_CONFIG,
110 #endif
111 #ifdef BSP_USING_UART2
112 UART2_CONFIG,
113 #endif
114 #ifdef BSP_USING_UART3
115 UART3_CONFIG,
116 #endif
117 #ifdef BSP_USING_UART4
118 UART4_CONFIG,
119 #endif
120 #ifdef BSP_USING_UART5
121 UART5_CONFIG,
122 #endif
123 #ifdef BSP_USING_UART6
124 UART6_CONFIG,
125 #endif
126 #ifdef BSP_USING_UART7
127 UART7_CONFIG,
128 #endif
129 #ifdef BSP_USING_UART8
130 UART8_CONFIG,
131 #endif
132 };
133
134 static struct air32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
135
air32_configure(struct rt_serial_device * serial,struct serial_configure * cfg)136 static rt_err_t air32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
137 {
138 struct air32_uart *uart;
139 RT_ASSERT(serial != RT_NULL);
140 RT_ASSERT(cfg != RT_NULL);
141
142 uart = rt_container_of(serial, struct air32_uart, serial);
143
144 air32_usart_clock_and_io_init(uart->config->Instance);
145 USART_StructInit(&uart->Init);
146
147 uart->Init.USART_BaudRate = cfg->baud_rate;
148 uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
149 uart->Init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
150
151 switch (cfg->flowcontrol)
152 {
153 case RT_SERIAL_FLOWCONTROL_NONE:
154 uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
155 break;
156 case RT_SERIAL_FLOWCONTROL_CTSRTS:
157 uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
158 break;
159 default:
160 uart->Init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
161 break;
162 }
163
164 switch (cfg->data_bits)
165 {
166 case DATA_BITS_8:
167 if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN)
168 uart->Init.USART_WordLength = USART_WordLength_9b;
169 else
170 uart->Init.USART_WordLength = USART_WordLength_8b;
171 break;
172 case DATA_BITS_9:
173 uart->Init.USART_WordLength = USART_WordLength_9b;
174 break;
175 default:
176 uart->Init.USART_WordLength = USART_WordLength_8b;
177 break;
178 }
179
180 switch (cfg->stop_bits)
181 {
182 case STOP_BITS_1:
183 uart->Init.USART_StopBits = USART_StopBits_1;
184 break;
185 case STOP_BITS_2:
186 uart->Init.USART_StopBits = USART_StopBits_2;
187 break;
188 default:
189 uart->Init.USART_StopBits = USART_StopBits_1;
190 break;
191 }
192
193 switch (cfg->parity)
194 {
195 case PARITY_NONE:
196 uart->Init.USART_Parity = USART_Parity_No;
197 break;
198 case PARITY_ODD:
199 uart->Init.USART_Parity = USART_Parity_Odd;
200 break;
201 case PARITY_EVEN:
202 uart->Init.USART_Parity = USART_Parity_Even;
203 break;
204 default:
205 uart->Init.USART_Parity = USART_Parity_No;
206 break;
207 }
208
209 USART_Init(uart->config->Instance, &uart->Init);
210 USART_Cmd(uart->config->Instance, ENABLE);
211
212 return RT_EOK;
213 }
214
air32_control(struct rt_serial_device * serial,int cmd,void * arg)215 static rt_err_t air32_control(struct rt_serial_device *serial, int cmd, void *arg)
216 {
217 struct air32_uart *uart;
218 NVIC_InitTypeDef NVIC_InitStruct;
219
220 RT_ASSERT(serial != RT_NULL);
221 uart = rt_container_of(serial, struct air32_uart, serial);
222
223 NVIC_InitStruct.NVIC_IRQChannel = uart->config->irq_type;
224 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
225 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
226
227 switch (cmd)
228 {
229 /* disable interrupt */
230 case RT_DEVICE_CTRL_CLR_INT:
231 /* disable rx irq */
232 // NVIC_DisableIRQ(uart->config->irq_type);
233 NVIC_InitStruct.NVIC_IRQChannelCmd = DISABLE;
234 NVIC_Init(&NVIC_InitStruct);
235 /* disable interrupt */
236 USART_ITConfig(uart->config->Instance,USART_IT_RXNE,DISABLE);
237
238 break;
239
240 /* enable interrupt */
241 case RT_DEVICE_CTRL_SET_INT:
242 /* enable rx irq */
243 // NVIC_EnableIRQ(uart->config->irq_type);
244 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
245 NVIC_Init(&NVIC_InitStruct);
246 /* enable interrupt */
247 USART_ITConfig(uart->config->Instance, USART_IT_RXNE,ENABLE);
248 break;
249 }
250
251 return RT_EOK;
252 }
253
air32_putc(struct rt_serial_device * serial,char c)254 static int air32_putc(struct rt_serial_device *serial, char c)
255 {
256 struct air32_uart *uart;
257 RT_ASSERT(serial != RT_NULL);
258 uart = rt_container_of(serial, struct air32_uart, serial);
259 while (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TXE) == RESET);
260 USART_SendData(uart->config->Instance, (uint8_t)c);
261 return 1;
262 }
263
air32_getc(struct rt_serial_device * serial)264 static int air32_getc(struct rt_serial_device *serial)
265 {
266 int ch;
267 struct air32_uart *uart;
268 RT_ASSERT(serial != RT_NULL);
269 uart = rt_container_of(serial, struct air32_uart, serial);
270 ch = -1;
271 if (RESET != USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE))
272 {
273 ch = USART_ReceiveData(uart->config->Instance) & 0xff;
274 }
275 return ch;
276 }
277
air32_dma_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,int direction)278 static rt_ssize_t air32_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
279 {
280 return 0;
281 }
282
283
284 /**
285 * Uart common interrupt process. This need add to uart ISR.
286 *
287 * @param serial serial device
288 */
uart_isr(struct rt_serial_device * serial)289 static void uart_isr(struct rt_serial_device *serial)
290 {
291 struct air32_uart *uart;
292
293 RT_ASSERT(serial != RT_NULL);
294 uart = rt_container_of(serial, struct air32_uart, serial);
295
296 /* UART in mode Receiver -------------------------------------------------*/
297
298 if ((USART_GetITStatus(uart->config->Instance, USART_IT_RXNE) != RESET) && (RESET != USART_GetFlagStatus(uart->config->Instance, USART_FLAG_RXNE)))
299 {
300 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
301 USART_ClearITPendingBit(uart->config->Instance, USART_IT_RXNE);
302 USART_ClearFlag(uart->config->Instance, USART_FLAG_RXNE);
303 }
304 else
305 {
306 if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_CTS) != RESET)
307 {
308 USART_ClearFlag(uart->config->Instance, USART_FLAG_CTS);
309 }
310
311 if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_LBD) != RESET)
312 {
313 USART_ClearFlag(uart->config->Instance, USART_FLAG_LBD);
314 }
315
316 if (USART_GetFlagStatus(uart->config->Instance, USART_FLAG_TC) != RESET)
317 {
318 USART_ClearFlag(uart->config->Instance, USART_FLAG_TC);
319 }
320 }
321
322 }
323
324 #if defined(BSP_USING_UART1)
USART1_IRQHandler(void)325 void USART1_IRQHandler(void)
326 {
327 /* enter interrupt */
328 rt_interrupt_enter();
329
330 uart_isr(&(uart_obj[UART1_INDEX].serial));
331
332 /* leave interrupt */
333 rt_interrupt_leave();
334 }
335 #endif /* BSP_USING_UART1 */
336
337 #if defined(BSP_USING_UART2)
USART2_IRQHandler(void)338 void USART2_IRQHandler(void)
339 {
340 /* enter interrupt */
341 rt_interrupt_enter();
342
343 uart_isr(&(uart_obj[UART2_INDEX].serial));
344
345 /* leave interrupt */
346 rt_interrupt_leave();
347 }
348 #endif /* BSP_USING_UART2 */
349
350 #if defined(BSP_USING_UART3)
USART3_IRQHandler(void)351 void USART3_IRQHandler(void)
352 {
353 /* enter interrupt */
354 rt_interrupt_enter();
355
356 uart_isr(&(uart_obj[UART3_INDEX].serial));
357
358 /* leave interrupt */
359 rt_interrupt_leave();
360 }
361 #endif /* BSP_USING_UART3*/
362
363 #if defined(BSP_USING_UART4)
UART4_IRQHandler(void)364 void UART4_IRQHandler(void)
365 {
366 /* enter interrupt */
367 rt_interrupt_enter();
368
369 uart_isr(&(uart_obj[UART4_INDEX].serial));
370
371 /* leave interrupt */
372 rt_interrupt_leave();
373 }
374 #endif /* BSP_USING_UART4*/
375
376 #if defined(BSP_USING_UART5)
UART5_IRQHandler(void)377 void UART5_IRQHandler(void)
378 {
379 /* enter interrupt */
380 rt_interrupt_enter();
381
382 uart_isr(&(uart_obj[UART5_INDEX].serial));
383
384 /* leave interrupt */
385 rt_interrupt_leave();
386 }
387 #endif /* BSP_USING_UART5*/
388
389 #if defined(BSP_USING_UART6)
USART6_IRQHandler(void)390 void USART6_IRQHandler(void)
391 {
392 /* enter interrupt */
393 rt_interrupt_enter();
394
395 uart_isr(&(uart_obj[UART6_INDEX].serial));
396
397 /* leave interrupt */
398 rt_interrupt_leave();
399 }
400 #endif /* BSP_USING_UART6*/
401
402 #if defined(BSP_USING_UART7)
UART7_IRQHandler(void)403 void UART7_IRQHandler(void)
404 {
405 /* enter interrupt */
406 rt_interrupt_enter();
407
408 uart_isr(&(uart_obj[UART7_INDEX].serial));
409
410 /* leave interrupt */
411 rt_interrupt_leave();
412 }
413 #endif /* BSP_USING_UART7*/
414
415 #if defined(BSP_USING_UART8)
UART8_IRQHandler(void)416 void UART8_IRQHandler(void)
417 {
418 /* enter interrupt */
419 rt_interrupt_enter();
420
421 uart_isr(&(uart_obj[UART8_INDEX].serial));
422
423 /* leave interrupt */
424 rt_interrupt_leave();
425 }
426 #endif /* BSP_USING_UART8*/
427
428 static const struct rt_uart_ops air32_uart_ops =
429 {
430 .configure = air32_configure,
431 .control = air32_control,
432 .putc = air32_putc,
433 .getc = air32_getc,
434 .dma_transmit = air32_dma_transmit
435 };
436
rt_hw_usart_init(void)437 int rt_hw_usart_init(void)
438 {
439 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
440 rt_err_t result = 0;
441
442 for (rt_size_t i = 0; i < sizeof(uart_obj) / sizeof(struct air32_uart); i++)
443 {
444 /* init UART object */
445 uart_obj[i].config = &uart_config[i];
446 uart_obj[i].serial.ops = &air32_uart_ops;
447 uart_obj[i].serial.config = config;
448
449 /* register UART device */
450 result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
451 RT_DEVICE_FLAG_RDWR
452 | RT_DEVICE_FLAG_INT_RX
453 | RT_DEVICE_FLAG_INT_TX
454 , RT_NULL);
455 RT_ASSERT(result == RT_EOK);
456 }
457
458 return result;
459 }
460
461 #endif /* RT_USING_SERIAL */
462