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