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 * 2021-08-27 Jiao first version
9 */
10
11 #include "drv_usart.h"
12 #include "drv_config.h"
13
14 #ifdef RT_USING_SERIAL
15
16 //#define DRV_DEBUG
17 #define LOG_TAG "drv.usart"
18 #include <drv_log.h>
19
20 enum
21 {
22 #ifdef BSP_USING_UART0
23 UART0_INDEX,
24 #endif
25 #ifdef BSP_USING_UART1
26 UART1_INDEX,
27 #endif
28 #ifdef BSP_USING_UART4
29 UART4_INDEX,
30 #endif
31 #ifdef BSP_USING_UART5
32 UART5_INDEX,
33 #endif
34 #ifdef BSP_USING_LPUART0
35 LPUART0_INDEX,
36 #endif
37 #ifdef BSP_USING_LPUART1
38 LPUART1_INDEX,
39 #endif
40 };
41
42 static struct _uart_config uart_config[] =
43 {
44 #ifdef BSP_USING_UART0
45 UART0_CONFIG,
46 #endif
47 #ifdef BSP_USING_UART1
48 UART1_CONFIG,
49 #endif
50 #ifdef BSP_USING_UART4
51 UART4_CONFIG,
52 #endif
53 #ifdef BSP_USING_UART5
54 UART5_CONFIG,
55 #endif
56 #ifdef BSP_USING_LPUART0
57 LPUART0_CONFIG,
58 #endif
59 #ifdef BSP_USING_LPUART1
60 LPUART1_CONFIG,
61 #endif
62 };
63
64 static struct _uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
65
uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)66 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
67 {
68 extern FL_ErrorStatus FL_UART_GPIO_Init(UART_Type * UARTx);
69
70 struct _uart *uart;
71 RT_ASSERT(serial != RT_NULL);
72 RT_ASSERT(cfg != RT_NULL);
73
74 uart = rt_container_of(serial, struct _uart, serial);
75
76 if (FL_UART_GPIO_Init(uart->config->InitTypeDef) != FL_PASS)
77 {
78 return -RT_ERROR;
79 }
80
81 uart->handle.clockSrc = uart->config->clockSrc;
82 uart->handle.baudRate = cfg->baud_rate;
83
84 switch (cfg->data_bits)
85 {
86 case DATA_BITS_8:
87 uart->handle.dataWidth = FL_UART_DATA_WIDTH_8B;
88 break;
89 case DATA_BITS_9:
90 uart->handle.dataWidth = FL_UART_DATA_WIDTH_9B;
91 break;
92 default:
93 uart->handle.dataWidth = FL_UART_DATA_WIDTH_8B;
94 break;
95 }
96
97 switch (cfg->stop_bits)
98 {
99 case STOP_BITS_1:
100 uart->handle.stopBits = FL_UART_STOP_BIT_WIDTH_1B;
101 break;
102 case STOP_BITS_2:
103 uart->handle.stopBits = FL_UART_STOP_BIT_WIDTH_2B;
104 break;
105 default:
106 uart->handle.stopBits = FL_UART_STOP_BIT_WIDTH_1B;
107 break;
108 }
109 switch (cfg->parity)
110 {
111 case PARITY_NONE:
112 uart->handle.parity = FL_UART_PARITY_NONE;
113 break;
114 case PARITY_ODD:
115 uart->handle.parity = FL_UART_PARITY_ODD;
116 break;
117 case PARITY_EVEN:
118 uart->handle.parity = FL_UART_PARITY_EVEN;
119 break;
120 default:
121 uart->handle.parity = FL_UART_PARITY_NONE;
122 break;
123 }
124
125 uart->handle.transferDirection = FL_UART_DIRECTION_TX_RX;
126
127 if (FL_UART_Init(uart->config->InitTypeDef, &uart->handle) != FL_PASS)
128 {
129 return -RT_ERROR;
130 }
131
132 return RT_EOK;
133 }
134
uart_control(struct rt_serial_device * serial,int cmd,void * arg)135 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
136 {
137 struct _uart *uart;
138 #ifdef RT_SERIAL_USING_DMA
139 rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
140 #endif
141
142 RT_ASSERT(serial != RT_NULL);
143 uart = rt_container_of(serial, struct _uart, serial);
144
145 switch (cmd)
146 {
147 /* disable interrupt */
148 case RT_DEVICE_CTRL_CLR_INT:
149 /* disable rx irq */
150 NVIC_DisableIRQ(uart->config->irq_type);
151 /* disable interrupt */
152 FL_UART_DisableIT_RXBuffFull(uart->config->InitTypeDef);
153
154 break;
155
156 /* enable interrupt */
157 case RT_DEVICE_CTRL_SET_INT:
158 /* enable rx irq */
159 NVIC_SetPriority(uart->config->irq_type, 1);
160 NVIC_EnableIRQ(uart->config->irq_type);
161 /* enable interrupt */
162 FL_UART_EnableIT_RXBuffFull(uart->config->InitTypeDef);
163 break;
164
165 #ifdef RT_SERIAL_USING_DMA
166 case RT_DEVICE_CTRL_CONFIG:
167 stm32_dma_config(serial, ctrl_arg);
168 break;
169 #endif
170
171 case RT_DEVICE_CTRL_CLOSE:
172 if (FL_UART_DeInit(uart->config->InitTypeDef) != FL_PASS)
173 {
174 RT_ASSERT(0)
175 }
176 break;
177
178 }
179 return RT_EOK;
180 }
181
uart_putc(struct rt_serial_device * serial,char c)182 static int uart_putc(struct rt_serial_device *serial, char c)
183 {
184 struct _uart *uart;
185 RT_ASSERT(serial != RT_NULL);
186
187 uart = rt_container_of(serial, struct _uart, serial);
188 FL_UART_WriteTXBuff(uart->config->InitTypeDef, c); //发送一个数据
189 while (FL_SET != FL_UART_IsActiveFlag_TXShiftBuffEmpty(uart->config->InitTypeDef));
190 return 1;
191 }
192
uart_getc(struct rt_serial_device * serial)193 static int uart_getc(struct rt_serial_device *serial)
194 {
195 int ch;
196 struct _uart *uart;
197 RT_ASSERT(serial != RT_NULL);
198 uart = rt_container_of(serial, struct _uart, serial);
199
200 ch = -1;
201 if (FL_SET == FL_UART_IsActiveFlag_RXBuffFull(uart->config->InitTypeDef))
202 {
203 ch = FL_UART_ReadRXBuff(uart->config->InitTypeDef);//接收中断标志可通过读取rxreg寄存器清除
204 }
205 return ch;
206 }
207
208 /**
209 * Uart common interrupt process. This need add to uart ISR.
210 *
211 * @param serial serial device
212 */
uart_isr(struct rt_serial_device * serial)213 static void uart_isr(struct rt_serial_device *serial)
214 {
215 struct _uart *uart;
216
217 RT_ASSERT(serial != RT_NULL);
218 uart = rt_container_of(serial, struct _uart, serial);
219
220 /* UART in mode Receiver -------------------------------------------------*/
221 if ((FL_ENABLE == FL_UART_IsEnabledIT_RXBuffFull(uart->config->InitTypeDef))
222 && (FL_SET == FL_UART_IsActiveFlag_RXBuffFull(uart->config->InitTypeDef)))
223 {
224 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
225 }
226 }
227
228 #if defined(BSP_USING_UART0)
UART0_IRQHandler(void)229 void UART0_IRQHandler(void)
230 {
231 /* enter interrupt */
232 rt_interrupt_enter();
233
234 uart_isr(&(uart_obj[UART0_INDEX].serial));
235
236 /* leave interrupt */
237 rt_interrupt_leave();
238 }
239 #endif /* BSP_USING_UART1 */
240
241 #if defined(BSP_USING_UART1)
UART1_IRQHandler(void)242 void UART1_IRQHandler(void)
243 {
244 /* enter interrupt */
245 rt_interrupt_enter();
246
247 uart_isr(&(uart_obj[UART1_INDEX].serial));
248
249 /* leave interrupt */
250 rt_interrupt_leave();
251 }
252 #endif /* BSP_USING_UART1 */
253
254 #if defined(BSP_USING_UART4)
UART4_IRQHandler(void)255 void UART4_IRQHandler(void)
256 {
257 /* enter interrupt */
258 rt_interrupt_enter();
259
260 uart_isr(&(uart_obj[UART4_INDEX].serial));
261
262 /* leave interrupt */
263 rt_interrupt_leave();
264 }
265 #endif /* BSP_USING_UART4 */
266
267 #if defined(BSP_USING_UART5)
UART5_IRQHandler(void)268 void UART5_IRQHandler(void)
269 {
270 /* enter interrupt */
271 rt_interrupt_enter();
272
273 uart_isr(&(uart_obj[UART5_INDEX].serial));
274
275 /* leave interrupt */
276 rt_interrupt_leave();
277 }
278 #endif /* BSP_USING_UART5 */
279
280 #if defined(BSP_USING_LPUART0)
LPUART0_IRQHandler(void)281 void LPUART0_IRQHandler(void)
282 {
283 /* enter interrupt */
284 rt_interrupt_enter();
285
286 uart_isr(&(uart_obj[LPUART0_INDEX].serial));
287
288 /* leave interrupt */
289 rt_interrupt_leave();
290 }
291 #endif /* BSP_USING_LPUART0*/
292
293 #if defined(BSP_USING_LPUART1)
LPUART1_IRQHandler(void)294 void LPUART1_IRQHandler(void)
295 {
296 /* enter interrupt */
297 rt_interrupt_enter();
298
299 uart_isr(&(uart_obj[LPUART1_INDEX].serial));
300
301 /* leave interrupt */
302 rt_interrupt_leave();
303 }
304 #endif /* BSP_USING_LPUART1*/
305
306 static const struct rt_uart_ops _uart_ops =
307 {
308 .configure = uart_configure,
309 .control = uart_control,
310 .putc = uart_putc,
311 .getc = uart_getc,
312 .dma_transmit = 0
313 };
314
rt_hw_usart_init(void)315 int rt_hw_usart_init(void)
316 {
317 rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct _uart);
318 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
319 rt_err_t result = 0;
320
321 for (int i = 0; i < obj_num; i++)
322 {
323 /* init UART object */
324 uart_obj[i].config = &uart_config[i];
325 uart_obj[i].serial.ops = &_uart_ops;
326 uart_obj[i].serial.config = config;
327
328 /* register UART device */
329 result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
330 RT_DEVICE_FLAG_RDWR
331 | RT_DEVICE_FLAG_INT_RX
332 | RT_DEVICE_FLAG_INT_TX
333 | uart_obj[i].uart_dma_flag
334 , NULL);
335 RT_ASSERT(result == RT_EOK);
336 }
337
338 return result;
339 }
340
341 #endif /* RT_USING_SERIAL */
342