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 * 2022-01-21 charlown first version
9 */
10
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "board.h"
14 #include "drv_uart.h"
15 #include "ch32f20x_usart.h"
16 #include "ch32f20x_misc.h"
17
18 #ifdef BSP_USING_UART
19
20 #ifndef ITEM_NUM
21 #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
22 #endif
23
24 struct usart_device
25 {
26 struct rt_serial_device parent;
27 char *name;
28 USART_TypeDef *periph;
29 IRQn_Type irqn;
30 };
31
32 #ifdef BSP_USING_UART1
33 static struct usart_device usart_device1 =
34 {
35 .name = "uart1",
36 .periph = USART1,
37 .irqn = USART1_IRQn,
38 };
39 #endif
40
41 #ifdef BSP_USING_UART2
42 static struct usart_device usart_device2 =
43 {
44 .name = "uart2",
45 .periph = USART2,
46 .irqn = USART2_IRQn,
47 };
48 #endif
49 #ifdef BSP_USING_UART3
50 static struct usart_device usart_device3 =
51 {
52 .name = "uart3",
53 .periph = USART3,
54 .irqn = USART3_IRQn,
55 };
56 #endif
57 #ifdef BSP_USING_UART4
58 static struct usart_device usart_device4 =
59 {
60 .name = "uart4",
61 .periph = UART4,
62 .irqn = UART4_IRQn,
63 };
64 #endif
65 #ifdef BSP_USING_UART5
66 static struct usart_device usart_device5 =
67 {
68 .name = "uart5",
69 .periph = UART5,
70 .irqn = UART5_IRQn,
71 };
72 #endif
73 #ifdef BSP_USING_UART6
74 static struct usart_device usart_device6 =
75 {
76 .name = "uart6",
77 .periph = UART6,
78 .irqn = UART6_IRQn,
79 };
80 #endif
81 #ifdef BSP_USING_UART7
82 static struct usart_device usart_device7 =
83 {
84 .name = "uart7",
85 .periph = UART7,
86 .irqn = UART7_IRQn,
87 };
88 #endif
89 #ifdef BSP_USING_UART8
90 static struct usart_device usart_device8 =
91 {
92 .name = "uart8",
93 .periph = UART8,
94 .irqn = UART8_IRQn,
95 };
96 #endif
97
ch32f2_usart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)98 static rt_err_t ch32f2_usart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
99 {
100 struct usart_device *usart_dev;
101 USART_InitTypeDef USART_InitStructure;
102
103 RT_ASSERT(serial != RT_NULL);
104 RT_ASSERT(cfg != RT_NULL);
105
106 usart_dev = (struct usart_device *)serial;
107 RT_ASSERT(usart_dev != RT_NULL);
108
109 ch32f2_usart_clock_and_io_init(usart_dev->periph);
110
111 USART_StructInit(&USART_InitStructure);
112
113 USART_InitStructure.USART_BaudRate = cfg->baud_rate;
114 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
115 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
116
117 switch (cfg->data_bits)
118 {
119 case DATA_BITS_8:
120 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
121 break;
122
123 case DATA_BITS_9:
124 USART_InitStructure.USART_WordLength = USART_WordLength_9b;
125 break;
126 default:
127 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
128 break;
129 }
130
131 switch (cfg->stop_bits)
132 {
133 case STOP_BITS_1:
134 USART_InitStructure.USART_StopBits = USART_StopBits_1;
135 break;
136 case STOP_BITS_2:
137 USART_InitStructure.USART_StopBits = USART_StopBits_2;
138 break;
139 default:
140 USART_InitStructure.USART_StopBits = USART_StopBits_1;
141 break;
142 }
143
144 switch (cfg->parity)
145 {
146 case PARITY_NONE:
147 USART_InitStructure.USART_Parity = USART_Parity_No;
148 break;
149 case PARITY_ODD:
150 USART_InitStructure.USART_Parity = USART_Parity_Odd;
151 break;
152 case PARITY_EVEN:
153 USART_InitStructure.USART_Parity = USART_Parity_Even;
154 break;
155 default:
156 USART_InitStructure.USART_Parity = USART_Parity_No;
157 break;
158 }
159 USART_Init(usart_dev->periph, &USART_InitStructure);
160 USART_Cmd(usart_dev->periph, ENABLE);
161
162 return RT_EOK;
163 }
164
ch32f2_usart_control(struct rt_serial_device * serial,int cmd,void * arg)165 static rt_err_t ch32f2_usart_control(struct rt_serial_device *serial, int cmd, void *arg)
166 {
167 struct usart_device *usart_dev;
168
169 NVIC_InitTypeDef NVIC_InitStruct;
170
171 RT_ASSERT(serial != RT_NULL);
172
173 usart_dev = (struct usart_device *)serial;
174
175 RT_ASSERT(usart_dev != RT_NULL);
176
177 NVIC_InitStruct.NVIC_IRQChannel = usart_dev->irqn;
178 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
179 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
180
181 switch (cmd)
182 {
183 case RT_DEVICE_CTRL_CLR_INT:
184 NVIC_InitStruct.NVIC_IRQChannelCmd = DISABLE;
185 NVIC_Init(&NVIC_InitStruct);
186 USART_ITConfig(usart_dev->periph, USART_IT_RXNE, DISABLE);
187 break;
188
189 case RT_DEVICE_CTRL_SET_INT:
190 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
191 NVIC_Init(&NVIC_InitStruct);
192 USART_ITConfig(usart_dev->periph, USART_IT_RXNE, ENABLE);
193 break;
194 }
195
196 return RT_EOK;
197 }
198
ch32f2_usart_putc(struct rt_serial_device * serial,char ch)199 static int ch32f2_usart_putc(struct rt_serial_device *serial, char ch)
200 {
201 struct usart_device *usart_dev;
202
203 RT_ASSERT(serial != RT_NULL);
204
205 usart_dev = (struct usart_device *)serial;
206
207 RT_ASSERT(usart_dev != RT_NULL);
208
209 USART_SendData(usart_dev->periph, (uint8_t)ch);
210 while (USART_GetFlagStatus(usart_dev->periph, USART_FLAG_TXE) == RESET)
211 ;
212
213 return 1;
214 }
215
ch32f2_usart_getc(struct rt_serial_device * serial)216 static int ch32f2_usart_getc(struct rt_serial_device *serial)
217 {
218 struct usart_device *usart_dev;
219 int ch;
220
221 RT_ASSERT(serial != RT_NULL);
222
223 usart_dev = (struct usart_device *)serial;
224
225 RT_ASSERT(usart_dev != RT_NULL);
226
227 ch = -1;
228 if (RESET != USART_GetFlagStatus(usart_dev->periph, USART_FLAG_RXNE))
229 {
230 ch = USART_ReceiveData(usart_dev->periph) & 0xff;
231 }
232
233 return ch;
234 }
235
236 static const struct rt_uart_ops usart_ops = {
237 .configure = ch32f2_usart_configure,
238 .control = ch32f2_usart_control,
239 .putc = ch32f2_usart_putc,
240 .getc = ch32f2_usart_getc,
241 .dma_transmit = RT_NULL};
242
usart_isr(struct usart_device * usart_dev)243 static void usart_isr(struct usart_device *usart_dev)
244 {
245
246 RT_ASSERT(usart_dev != RT_NULL);
247
248 if ((USART_GetITStatus(usart_dev->periph, USART_IT_RXNE) != RESET) && (RESET != USART_GetFlagStatus(usart_dev->periph, USART_FLAG_RXNE)))
249 {
250 rt_hw_serial_isr(&usart_dev->parent, RT_SERIAL_EVENT_RX_IND);
251 USART_ClearITPendingBit(usart_dev->periph, USART_IT_RXNE);
252 USART_ClearFlag(usart_dev->periph, USART_FLAG_RXNE);
253 }
254 else
255 {
256 if (USART_GetFlagStatus(usart_dev->periph, USART_FLAG_CTS) != RESET)
257 {
258 USART_ClearFlag(usart_dev->periph, USART_FLAG_CTS);
259 }
260
261 if (USART_GetFlagStatus(usart_dev->periph, USART_FLAG_LBD) != RESET)
262 {
263 USART_ClearFlag(usart_dev->periph, USART_FLAG_LBD);
264 }
265
266 if (USART_GetFlagStatus(usart_dev->periph, USART_FLAG_TC) != RESET)
267 {
268 USART_ClearFlag(usart_dev->periph, USART_FLAG_TC);
269 }
270 }
271 }
272
273 #ifdef BSP_USING_UART1
USART1_IRQHandler(void)274 void USART1_IRQHandler(void)
275 {
276 rt_interrupt_enter();
277
278 usart_isr(&usart_device1);
279
280 rt_interrupt_leave();
281 }
282 #endif
283 #ifdef BSP_USING_UART2
USART2_IRQHandler(void)284 void USART2_IRQHandler(void)
285 {
286 rt_interrupt_enter();
287
288 usart_isr(&usart_device2);
289
290 rt_interrupt_leave();
291 }
292 #endif
293 #ifdef BSP_USING_UART3
USART3_IRQHandler(void)294 void USART3_IRQHandler(void)
295 {
296 rt_interrupt_enter();
297
298 usart_isr(&usart_device3);
299
300 rt_interrupt_leave();
301 }
302 #endif
303 #ifdef BSP_USING_UART4
USART4_IRQHandler(void)304 void USART4_IRQHandler(void)
305 {
306 rt_interrupt_enter();
307
308 usart_isr(&usart_device4);
309
310 rt_interrupt_leave();
311 }
312 #endif
313 #ifdef BSP_USING_UART5
USART5_IRQHandler(void)314 void USART5_IRQHandler(void)
315 {
316 rt_interrupt_enter();
317
318 usart_isr(&usart_device5);
319
320 rt_interrupt_leave();
321 }
322 #endif
323 #ifdef BSP_USING_UART6
USART6_IRQHandler(void)324 void USART6_IRQHandler(void)
325 {
326 rt_interrupt_enter();
327
328 usart_isr(&usart_device6);
329
330 rt_interrupt_leave();
331 }
332 #endif
333 #ifdef BSP_USING_UART7
USART7_IRQHandler(void)334 void USART7_IRQHandler(void)
335 {
336 rt_interrupt_enter();
337
338 usart_isr(&usart_device7);
339
340 rt_interrupt_leave();
341 }
342 #endif
343 #ifdef BSP_USING_UART8
USART8_IRQHandler(void)344 void USART8_IRQHandler(void)
345 {
346 rt_interrupt_enter();
347
348 usart_isr(&usart_device8);
349
350 rt_interrupt_leave();
351 }
352 #endif
353
rt_hw_uart_init(void)354 int rt_hw_uart_init(void)
355 {
356 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
357
358 #ifdef BSP_USING_UART1
359 usart_device1.parent.ops = &usart_ops;
360 usart_device1.parent.config = config;
361 rt_hw_serial_register(&usart_device1.parent, usart_device1.name,
362 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
363 RT_NULL);
364 #endif
365
366 #ifdef BSP_USING_UART2
367 usart_device2.parent.ops = &usart_ops;
368 usart_device2.parent.config = config;
369 rt_hw_serial_register(&usart_device2.parent, usart_device2.name,
370 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
371 RT_NULL);
372 #endif
373
374 #ifdef BSP_USING_UART3
375 usart_device3.parent.ops = &usart_ops;
376 usart_device3.parent.config = config;
377 rt_hw_serial_register(&usart_device3.parent, usart_device3.name,
378 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
379 RT_NULL);
380 #endif
381
382 #ifdef BSP_USING_UART4
383 usart_device4.parent.ops = &usart_ops;
384 usart_device4.parent.config = config;
385 rt_hw_serial_register(&usart_device4.parent, usart_device4.name,
386 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
387 RT_NULL);
388 #endif
389
390 #ifdef BSP_USING_UART5
391 usart_device5.parent.ops = &usart_ops;
392 usart_device5.parent.config = config;
393 rt_hw_serial_register(&usart_device5.parent, usart_device5.name,
394 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
395 RT_NULL);
396 #endif
397
398 #ifdef BSP_USING_UART6
399 usart_device6.parent.ops = &usart_ops;
400 usart_device6.parent.config = config;
401 rt_hw_serial_register(&usart_device6.parent, usart_device6.name,
402 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
403 RT_NULL);
404 #endif
405
406 #ifdef BSP_USING_UART7
407 usart_device7.parent.ops = &usart_ops;
408 usart_device7.parent.config = config;
409 rt_hw_serial_register(&usart_device7.parent, usart_device7.name,
410 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
411 RT_NULL);
412 #endif
413
414 #ifdef BSP_USING_UART8
415 usart_device8.parent.ops = &usart_ops;
416 usart_device8.parent.config = config;
417 rt_hw_serial_register(&usart_device8.parent, usart_device8.name,
418 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX,
419 RT_NULL);
420 #endif
421
422 return RT_EOK;
423 }
424
425 #endif /* BSP_USING_UART */
426