1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2020-08-20     Abbcc        first version
9  * 2022-12-26     luobeihai    add APM2F0 series MCU support
10  * 2023-03-27     luobeihai    add APM32E1/S1 series MCU support
11  */
12 
13 #include "board.h"
14 #include "drv_usart.h"
15 
16 #ifdef RT_USING_SERIAL
17 #if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
18     !defined(BSP_USING_UART3) && !defined(BSP_USING_UART4) && \
19     !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6)
20     #error "Please define at least one BSP_USING_UARTx"
21     /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
22 #endif
23 
24 struct apm32_usart
25 {
26     const char *name;
27     USART_T *usartx;
28     IRQn_Type irq_type;
29     struct rt_serial_device serial;
30 };
31 
32 enum
33 {
34 #ifdef BSP_USING_UART1
35     UART1_INDEX,
36 #endif
37 #ifdef BSP_USING_UART2
38     UART2_INDEX,
39 #endif
40 #ifdef BSP_USING_UART3
41     UART3_INDEX,
42 #endif
43 #ifdef BSP_USING_UART4
44     UART4_INDEX,
45 #endif
46 #ifdef BSP_USING_UART5
47     UART5_INDEX,
48 #endif
49 #ifdef BSP_USING_UART6
50     UART6_INDEX,
51 #endif
52 };
53 
54 static struct apm32_usart usart_config[] =
55 {
56 #ifdef BSP_USING_UART1
57     {
58         "uart1",
59         USART1,
60         USART1_IRQn,
61     },
62 #endif
63 #ifdef BSP_USING_UART2
64     {
65         "uart2",
66         USART2,
67         USART2_IRQn,
68     },
69 #endif
70 #if defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
71     || defined(SOC_SERIES_APM32F4)
72 #ifdef BSP_USING_UART3
73     {
74         "uart3",
75         USART3,
76         USART3_IRQn,
77     },
78 #endif
79 #ifdef BSP_USING_UART4
80     {
81         "uart4",
82         UART4,
83         UART4_IRQn,
84     },
85 #endif
86 #ifdef BSP_USING_UART5
87     {
88         "uart5",
89         UART5,
90         UART5_IRQn,
91     },
92 #endif
93 #ifdef BSP_USING_UART6
94     {
95         "uart6",
96         USART6,
97         USART6_IRQn,
98     },
99 #endif
100 #endif /* SOC_SERIES_APM32F0 */
101 };
102 
apm32_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)103 static rt_err_t apm32_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
104 {
105     USART_Config_T USART_ConfigStruct;
106     RT_ASSERT(serial != RT_NULL);
107     RT_ASSERT(cfg != RT_NULL);
108 
109     struct apm32_usart *usart_instance = (struct apm32_usart *) serial->parent.user_data;
110 
111     apm32_usart_init();
112 
113     USART_ConfigStruct.baudRate = cfg->baud_rate;
114     USART_ConfigStruct.mode = USART_MODE_TX_RX;
115     USART_ConfigStruct.parity = USART_PARITY_NONE;
116 
117 #if defined(SOC_SERIES_APM32F0)
118     switch (cfg->flowcontrol)
119     {
120     case RT_SERIAL_FLOWCONTROL_NONE:
121 
122         USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
123         break;
124     case RT_SERIAL_FLOWCONTROL_CTSRTS:
125         USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_RTS_CTS;
126         break;
127     default:
128         USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
129         break;
130     }
131 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
132     || defined(SOC_SERIES_APM32F4)
133     switch (cfg->flowcontrol)
134     {
135     case RT_SERIAL_FLOWCONTROL_NONE:
136         USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
137         break;
138     case RT_SERIAL_FLOWCONTROL_CTSRTS:
139         USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_RTS_CTS;
140         break;
141     default:
142         USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
143         break;
144     }
145 #endif /* SOC_SERIES_APM32F0 */
146 
147     switch (cfg->data_bits)
148     {
149     case DATA_BITS_8:
150         if (cfg->parity == PARITY_ODD || cfg->parity == PARITY_EVEN)
151             USART_ConfigStruct.wordLength = USART_WORD_LEN_9B;
152         else
153             USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
154         break;
155     case DATA_BITS_9:
156         USART_ConfigStruct.wordLength = USART_WORD_LEN_9B;
157         break;
158     default:
159         USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
160         break;
161     }
162 
163     switch (cfg->stop_bits)
164     {
165     case STOP_BITS_1:
166         USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
167         break;
168     case STOP_BITS_2:
169         USART_ConfigStruct.stopBits = USART_STOP_BIT_2;
170         break;
171     default:
172         USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
173         break;
174     }
175 
176     switch (cfg->parity)
177     {
178     case PARITY_NONE:
179         USART_ConfigStruct.parity     = USART_PARITY_NONE;
180         break;
181     case PARITY_ODD:
182         USART_ConfigStruct.parity     = USART_PARITY_ODD;
183         break;
184     case PARITY_EVEN:
185         USART_ConfigStruct.parity     = USART_PARITY_EVEN;
186         break;
187     default:
188         USART_ConfigStruct.parity     = USART_PARITY_NONE;
189         break;
190     }
191 
192     USART_Config(usart_instance->usartx, &USART_ConfigStruct);
193     USART_Enable(usart_instance->usartx);
194 
195     return RT_EOK;
196 }
197 
apm32_uart_control(struct rt_serial_device * serial,int cmd,void * arg)198 static rt_err_t apm32_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
199 {
200     struct apm32_usart *usart;
201 
202     RT_ASSERT(serial != RT_NULL);
203 
204     usart = (struct apm32_usart *) serial->parent.user_data;
205     RT_ASSERT(usart != RT_NULL);
206 
207 #if defined(SOC_SERIES_APM32F0)
208     switch (cmd)
209     {
210     /* disable interrupt */
211     case RT_DEVICE_CTRL_CLR_INT:
212 
213         /* disable rx irq */
214         NVIC_DisableIRQRequest(usart->irq_type);
215 
216         /* disable interrupt */
217         USART_DisableInterrupt(usart->usartx, USART_INT_RXBNEIE);
218 
219         break;
220 
221     /* enable interrupt */
222     case RT_DEVICE_CTRL_SET_INT:
223         /* enable rx irq */
224         NVIC_EnableIRQRequest(usart->irq_type, 1);
225 
226         /* enable interrupt */
227         USART_EnableInterrupt(usart->usartx, USART_INT_RXBNEIE);
228         break;
229     }
230 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
231     || defined(SOC_SERIES_APM32F4)
232     switch (cmd)
233     {
234     /* disable interrupt */
235     case RT_DEVICE_CTRL_CLR_INT:
236 
237         /* disable rx irq */
238         NVIC_DisableIRQRequest(usart->irq_type);
239 
240         /* disable interrupt */
241         USART_DisableInterrupt(usart->usartx, USART_INT_RXBNE);
242 
243         break;
244 
245     /* enable interrupt */
246     case RT_DEVICE_CTRL_SET_INT:
247         /* enable rx irq */
248         NVIC_EnableIRQRequest(usart->irq_type, 1, 0);
249 
250         /* enable interrupt */
251         USART_EnableInterrupt(usart->usartx, USART_INT_RXBNE);
252         break;
253     }
254 #endif /* SOC_SERIES_APM32F0 */
255     return RT_EOK;
256 }
257 
apm32_uart_putc(struct rt_serial_device * serial,char c)258 static int apm32_uart_putc(struct rt_serial_device *serial, char c)
259 {
260     struct apm32_usart *usart;
261     RT_ASSERT(serial != RT_NULL);
262 
263     usart = (struct apm32_usart *) serial->parent.user_data;
264 
265     RT_ASSERT(usart != RT_NULL);
266 
267     USART_TxData(usart->usartx, (uint8_t) c);
268 
269     while (USART_ReadStatusFlag(usart->usartx, USART_FLAG_TXC) == RESET);
270 
271     return 1;
272 }
273 
apm32_uart_getc(struct rt_serial_device * serial)274 static int apm32_uart_getc(struct rt_serial_device *serial)
275 {
276     int ch;
277     struct apm32_usart *usart;
278     RT_ASSERT(serial != RT_NULL);
279     usart = (struct apm32_usart *) serial->parent.user_data;
280 
281     RT_ASSERT(usart != RT_NULL);
282 
283     ch = -1;
284     if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET)
285     {
286         ch = USART_RxData(usart->usartx);
287     }
288     return ch;
289 }
290 
291 /**
292  * Uart common interrupt process. This need add to usart ISR.
293  *
294  * @param serial serial device
295  */
usart_isr(struct rt_serial_device * serial)296 static void usart_isr(struct rt_serial_device *serial)
297 {
298     struct apm32_usart *usart;
299 
300     RT_ASSERT(serial != RT_NULL);
301     usart = (struct apm32_usart *) serial->parent.user_data;
302 
303     RT_ASSERT(usart != RT_NULL);
304 
305     /* UART in mode Receiver */
306 #if defined(SOC_SERIES_APM32F0)
307     if ((USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET) &&
308             (USART_ReadIntFlag(usart->usartx, USART_INT_FLAG_RXBNE) != RESET))
309 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
310     || defined(SOC_SERIES_APM32F4)
311     if ((USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET) &&
312             (USART_ReadIntFlag(usart->usartx, USART_INT_RXBNE) != RESET))
313 #endif
314     {
315         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
316     }
317     else
318     {
319 #if defined(SOC_SERIES_APM32F0)
320         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_OVRE) != RESET)
321         {
322             USART_ClearStatusFlag(usart->usartx, USART_FLAG_OVRE);
323         }
324         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_NEF) != RESET)
325         {
326             USART_ClearStatusFlag(usart->usartx, USART_FLAG_NEF);
327         }
328         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_FEF) != RESET)
329         {
330             USART_ClearStatusFlag(usart->usartx, USART_FLAG_FEF);
331         }
332         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_PEF) != RESET)
333         {
334             USART_ClearStatusFlag(usart->usartx, USART_FLAG_PEF);
335         }
336         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_CTSF) != RESET)
337         {
338             USART_ClearStatusFlag(usart->usartx, USART_FLAG_CTSF);
339         }
340         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_LBDF) != RESET)
341         {
342             USART_ClearStatusFlag(usart->usartx, USART_FLAG_LBDF);
343         }
344 #elif defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32E1) || defined(SOC_SERIES_APM32S1) \
345     || defined(SOC_SERIES_APM32F4)
346         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_OVRE) != RESET)
347         {
348             USART_ClearStatusFlag(usart->usartx, USART_FLAG_OVRE);
349         }
350         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_NE) != RESET)
351         {
352             USART_ClearStatusFlag(usart->usartx, USART_FLAG_NE);
353         }
354         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_FE) != RESET)
355         {
356             USART_ClearStatusFlag(usart->usartx, USART_FLAG_FE);
357         }
358         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_PE) != RESET)
359         {
360             USART_ClearStatusFlag(usart->usartx, USART_FLAG_PE);
361         }
362         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_CTS) != RESET)
363         {
364             USART_ClearStatusFlag(usart->usartx, USART_FLAG_CTS);
365         }
366         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_LBD) != RESET)
367         {
368             USART_ClearStatusFlag(usart->usartx, USART_FLAG_LBD);
369         }
370 #endif /* SOC_SERIES_APM32F0 */
371         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_TXBE) != RESET)
372         {
373             USART_ClearStatusFlag(usart->usartx, USART_FLAG_TXBE);
374         }
375     }
376 }
377 
378 #if defined(BSP_USING_UART1)
USART1_IRQHandler(void)379 void USART1_IRQHandler(void)
380 {
381     /* enter interrupt */
382     rt_interrupt_enter();
383 
384     usart_isr(&(usart_config[UART1_INDEX].serial));
385 
386     /* leave interrupt */
387     rt_interrupt_leave();
388 }
389 #endif /* BSP_USING_UART1 */
390 
391 #if defined(BSP_USING_UART2)
USART2_IRQHandler(void)392 void USART2_IRQHandler(void)
393 {
394     /* enter interrupt */
395     rt_interrupt_enter();
396 
397     usart_isr(&(usart_config[UART2_INDEX].serial));
398 
399     /* leave interrupt */
400     rt_interrupt_leave();
401 }
402 #endif /* BSP_USING_UART2 */
403 
404 #if defined(BSP_USING_UART3)
USART3_IRQHandler(void)405 void USART3_IRQHandler(void)
406 {
407     /* enter interrupt */
408     rt_interrupt_enter();
409 
410     usart_isr(&(usart_config[UART3_INDEX].serial));
411 
412     /* leave interrupt */
413     rt_interrupt_leave();
414 }
415 #endif /* BSP_USING_UART3 */
416 
417 #if defined(BSP_USING_UART4)
UART4_IRQHandler(void)418 void UART4_IRQHandler(void)
419 {
420     /* enter interrupt */
421     rt_interrupt_enter();
422 
423     usart_isr(&(usart_config[UART4_INDEX].serial));
424 
425     /* leave interrupt */
426     rt_interrupt_leave();
427 }
428 #endif /* BSP_USING_UART4 */
429 
430 #if defined(BSP_USING_UART5)
UART5_IRQHandler(void)431 void UART5_IRQHandler(void)
432 {
433     /* enter interrupt */
434     rt_interrupt_enter();
435 
436     usart_isr(&(usart_config[UART5_INDEX].serial));
437 
438     /* leave interrupt */
439     rt_interrupt_leave();
440 }
441 #endif /* BSP_USING_UART5 */
442 
443 #if defined(BSP_USING_UART6)
USART6_IRQHandler(void)444 void USART6_IRQHandler(void)
445 {
446     /* enter interrupt */
447     rt_interrupt_enter();
448 
449     usart_isr(&(usart_config[UART6_INDEX].serial));
450 
451     /* leave interrupt */
452     rt_interrupt_leave();
453 }
454 #endif /* BSP_USING_UART6 */
455 
456 static const struct rt_uart_ops apm32_usart_ops =
457 {
458     .configure = apm32_uart_configure,
459     .control = apm32_uart_control,
460     .putc = apm32_uart_putc,
461     .getc = apm32_uart_getc,
462     .dma_transmit = RT_NULL
463 };
464 
rt_hw_usart_init(void)465 int rt_hw_usart_init(void)
466 {
467     rt_size_t obj_num;
468     int index;
469 
470     obj_num = sizeof(usart_config) / sizeof(struct apm32_usart);
471     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
472     rt_err_t result = 0;
473 
474     for (index = 0; index < obj_num; index++)
475     {
476         usart_config[index].serial.ops = &apm32_usart_ops;
477         usart_config[index].serial.config = config;
478 
479         /* register USART device */
480         result = rt_hw_serial_register(&usart_config[index].serial,
481                                        usart_config[index].name,
482                                        RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX
483                                        | RT_DEVICE_FLAG_INT_TX, &usart_config[index]);
484         RT_ASSERT(result == RT_EOK);
485     }
486 
487     return result;
488 }
489 
490 #endif /* RT_USING_SERIAL */
491