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