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-20 BruceOu first implementation
9 */
10
11 #include "drv_usart.h"
12
13 #define RT_USING_SERIAL
14
15 #ifdef RT_USING_SERIAL
16
17 #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && \
18 !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) && \
19 !defined(BSP_USING_UART4)
20 #error "Please define at least one UARTx"
21
22 #endif
23
24 #include <rtdevice.h>
25
26 static void GD32_UART_IRQHandler(struct rt_serial_device *serial);
27
28 #if defined(BSP_USING_UART0)
29 struct rt_serial_device serial0;
30
USART0_IRQHandler(void)31 void USART0_IRQHandler(void)
32 {
33 /* enter interrupt */
34 rt_interrupt_enter();
35
36 GD32_UART_IRQHandler(&serial0);
37
38 /* leave interrupt */
39 rt_interrupt_leave();
40 }
41
42 #endif /* BSP_USING_UART0 */
43
44 #if defined(BSP_USING_UART1)
45 struct rt_serial_device serial1;
46
USART1_IRQHandler(void)47 void USART1_IRQHandler(void)
48 {
49 /* enter interrupt */
50 rt_interrupt_enter();
51
52 GD32_UART_IRQHandler(&serial1);
53
54 /* leave interrupt */
55 rt_interrupt_leave();
56 }
57
58 #endif /* BSP_USING_UART1 */
59
60 #if defined(BSP_USING_UART2)
61 struct rt_serial_device serial2;
62
USART2_IRQHandler(void)63 void USART2_IRQHandler(void)
64 {
65 /* enter interrupt */
66 rt_interrupt_enter();
67
68 GD32_UART_IRQHandler(&serial2);
69
70 /* leave interrupt */
71 rt_interrupt_leave();
72 }
73
74 #endif /* BSP_USING_UART2 */
75
76 #if defined(BSP_USING_UART3)
77 struct rt_serial_device serial3;
78
UART3_IRQHandler(void)79 void UART3_IRQHandler(void)
80 {
81 /* enter interrupt */
82 rt_interrupt_enter();
83
84 GD32_UART_IRQHandler(&serial3);
85
86 /* leave interrupt */
87 rt_interrupt_leave();
88 }
89
90 #endif /* BSP_USING_UART3 */
91
92 #if defined(BSP_USING_UART4)
93 struct rt_serial_device serial4;
94
UART4_IRQHandler(void)95 void UART4_IRQHandler(void)
96 {
97 /* enter interrupt */
98 rt_interrupt_enter();
99
100 GD32_UART_IRQHandler(&serial4);
101
102 /* leave interrupt */
103 rt_interrupt_leave();
104 }
105 #endif /* BSP_USING_UART4 */
106
107 #if defined(BSP_USING_UART5)
108 struct rt_serial_device serial5;
109
USART5_IRQHandler(void)110 void USART5_IRQHandler(void)
111 {
112 /* enter interrupt */
113 rt_interrupt_enter();
114
115 GD32_UART_IRQHandler(&serial5);
116
117 /* leave interrupt */
118 rt_interrupt_leave();
119 }
120
121 #endif /* BSP_USING_UART5 */
122
123 #if defined(BSP_USING_UART6)
124 struct rt_serial_device serial6;
125
UART6_IRQHandler(void)126 void UART6_IRQHandler(void)
127 {
128 /* enter interrupt */
129 rt_interrupt_enter();
130
131 GD32_UART_IRQHandler(&serial6);
132
133 /* leave interrupt */
134 rt_interrupt_leave();
135 }
136
137 #endif /* BSP_USING_UART6 */
138
139 #if defined(BSP_USING_UART7)
140 struct rt_serial_device serial7;
141
UART7_IRQHandler(void)142 void UART7_IRQHandler(void)
143 {
144 /* enter interrupt */
145 rt_interrupt_enter();
146
147 GD32_UART_IRQHandler(&serial7);
148
149 /* leave interrupt */
150 rt_interrupt_leave();
151 }
152
153 #endif /* BSP_USING_UART7 */
154
155 static const struct gd32_uart uart_obj[] = {
156 #ifdef BSP_USING_UART0
157 {
158 USART0, // uart peripheral index
159 USART0_IRQn, // uart iqrn
160 RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock
161 GPIOA, GPIO_PIN_9, // tx port, tx pin
162 GPIOA, GPIO_PIN_10, // rx port, rx pin
163 &serial0,
164 "uart0",
165 },
166 #endif
167
168 #ifdef BSP_USING_UART1
169 {
170 USART1, // uart peripheral index
171 USART1_IRQn, // uart iqrn
172 RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock
173 GPIOA, GPIO_PIN_2, // tx port, tx pin
174 GPIOA, GPIO_PIN_3, // rx port, rx pin
175 &serial1,
176 "uart1",
177 },
178 #endif
179
180 #ifdef BSP_USING_UART2
181 {
182 USART2, // uart peripheral index
183 USART2_IRQn, // uart iqrn
184 RCU_USART2, RCU_GPIOB, RCU_GPIOB, // periph clock, tx gpio clock, rt gpio clock
185 GPIOB, GPIO_PIN_10, // tx port, tx pin
186 GPIOB, GPIO_PIN_11, // rx port, rx pin
187 &serial2,
188 "uart2",
189 },
190 #endif
191
192 #ifdef BSP_USING_UART3
193 {
194 UART3, // uart peripheral index
195 UART3_IRQn, // uart iqrn
196 RCU_UART3, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock
197 GPIOC, GPIO_PIN_10, // tx port, tx pin
198 GPIOC, GPIO_PIN_11, // rx port, rx pin
199 &serial3,
200 "uart3",
201 },
202 #endif
203
204 #ifdef BSP_USING_UART4
205 {
206 UART4, // uart peripheral index
207 UART4_IRQn, // uart iqrn
208 RCU_UART4, RCU_GPIOC, RCU_GPIOD, // periph clock, tx gpio clock, rt gpio clock
209 GPIOC, GPIO_PIN_12, // tx port, tx pin
210 GPIOD, GPIO_PIN_2, // rx port, rx pin
211 &serial4,
212 "uart4",
213 },
214 #endif
215 };
216
217
218 /**
219 * @brief UART MSP Initialization
220 * This function configures the hardware resources used in this example:
221 * - Peripheral's clock enable
222 * - Peripheral's GPIO Configuration
223 * - NVIC configuration for UART interrupt request enable
224 * @param huart: UART handle pointer
225 * @retval None
226 */
gd32_uart_gpio_init(struct gd32_uart * uart)227 void gd32_uart_gpio_init(struct gd32_uart *uart)
228 {
229 /* enable USART clock */
230 rcu_periph_clock_enable(uart->tx_gpio_clk);
231 rcu_periph_clock_enable(uart->rx_gpio_clk);
232 rcu_periph_clock_enable(uart->per_clk);
233
234 /* connect port to USARTx_Tx */
235 gpio_init(uart->tx_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, uart->tx_pin);
236
237 /* connect port to USARTx_Rx */
238 gpio_init(uart->rx_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, uart->rx_pin);
239 }
240
241 /**
242 * @brief uart configure
243 * @param serial, cfg
244 * @retval None
245 */
gd32_uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)246 static rt_err_t gd32_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
247 {
248 struct gd32_uart *uart;
249
250 RT_ASSERT(serial != RT_NULL);
251 RT_ASSERT(cfg != RT_NULL);
252
253 uart = (struct gd32_uart *)serial->parent.user_data;
254
255 gd32_uart_gpio_init(uart);
256
257 usart_baudrate_set(uart->uart_periph, cfg->baud_rate);
258
259 switch (cfg->data_bits)
260 {
261 case DATA_BITS_9:
262 usart_word_length_set(uart->uart_periph, USART_WL_9BIT);
263 break;
264
265 default:
266 usart_word_length_set(uart->uart_periph, USART_WL_8BIT);
267 break;
268 }
269
270 switch (cfg->stop_bits)
271 {
272 case STOP_BITS_2:
273 usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT);
274 break;
275 default:
276 usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT);
277 break;
278 }
279
280 switch (cfg->parity)
281 {
282 case PARITY_ODD:
283 usart_parity_config(uart->uart_periph, USART_PM_ODD);
284 break;
285 case PARITY_EVEN:
286 usart_parity_config(uart->uart_periph, USART_PM_EVEN);
287 break;
288 default:
289 usart_parity_config(uart->uart_periph, USART_PM_NONE);
290 break;
291 }
292
293 usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE);
294 usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE);
295 usart_enable(uart->uart_periph);
296
297 return RT_EOK;
298 }
299
300 /**
301 * @brief uart control
302 * @param serial, arg
303 * @retval None
304 */
gd32_uart_control(struct rt_serial_device * serial,int cmd,void * arg)305 static rt_err_t gd32_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
306 {
307 struct gd32_uart *uart;
308
309 RT_ASSERT(serial != RT_NULL);
310 uart = (struct gd32_uart *)serial->parent.user_data;
311
312 switch (cmd)
313 {
314 case RT_DEVICE_CTRL_CLR_INT:
315 /* disable rx irq */
316 eclic_irq_disable(uart->uart_periph);
317 /* disable interrupt */
318 usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE);
319
320 break;
321 case RT_DEVICE_CTRL_SET_INT:
322 eclic_set_nlbits(ECLIC_GROUP_LEVEL3_PRIO1);
323 /* enable rx irq */
324 eclic_irq_enable(uart->irqn, 1, 0);
325 /* enable interrupt */
326 usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE);
327 break;
328 }
329
330 return RT_EOK;
331 }
332
333 /**
334 * @brief uart put char
335 * @param serial, ch
336 * @retval None
337 */
gd32_uart_putc(struct rt_serial_device * serial,char ch)338 static int gd32_uart_putc(struct rt_serial_device *serial, char ch)
339 {
340 struct gd32_uart *uart;
341
342 RT_ASSERT(serial != RT_NULL);
343 uart = (struct gd32_uart *)serial->parent.user_data;
344
345 usart_data_transmit(uart->uart_periph, ch);
346 while((usart_flag_get(uart->uart_periph, USART_FLAG_TBE) == RESET));
347
348 return RT_EOK;
349 }
350
351 /**
352 * @brief uart get char
353 * @param serial
354 * @retval None
355 */
gd32_uart_getc(struct rt_serial_device * serial)356 static int gd32_uart_getc(struct rt_serial_device *serial)
357 {
358 int ch;
359 struct gd32_uart *uart;
360
361 RT_ASSERT(serial != RT_NULL);
362 uart = (struct gd32_uart *)serial->parent.user_data;
363
364 ch = -1;
365 if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)
366 ch = usart_data_receive(uart->uart_periph);
367 return ch;
368 }
369
370 /**
371 * Uart common interrupt process. This need add to uart ISR.
372 *
373 * @param serial serial device
374 */
GD32_UART_IRQHandler(struct rt_serial_device * serial)375 static void GD32_UART_IRQHandler(struct rt_serial_device *serial)
376 {
377 struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
378
379 RT_ASSERT(uart != RT_NULL);
380
381 /* UART in mode Receiver -------------------------------------------------*/
382 if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) &&
383 (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET))
384 {
385 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
386 usart_interrupt_flag_clear(uart->uart_periph, USART_INT_FLAG_RBNE);
387 /* Clear RXNE interrupt flag */
388 usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE);
389 }
390 else
391 {
392 if (usart_flag_get(uart->uart_periph, USART_FLAG_CTS) != RESET)
393 {
394 usart_flag_clear(uart->uart_periph, USART_FLAG_CTS);
395 }
396
397 if (usart_flag_get(uart->uart_periph, USART_FLAG_LBD) != RESET)
398 {
399 usart_flag_clear(uart->uart_periph, USART_FLAG_LBD);
400 }
401
402 if (usart_flag_get(uart->uart_periph, USART_FLAG_TC) != RESET)
403 {
404 usart_flag_clear(uart->uart_periph, USART_FLAG_TC);
405 }
406 }
407 }
408
409 static const struct rt_uart_ops gd32_uart_ops =
410 {
411 .configure = gd32_uart_configure,
412 .control = gd32_uart_control,
413 .putc = gd32_uart_putc,
414 .getc = gd32_uart_getc,
415 RT_NULL,
416 };
417
418 /**
419 * @brief uart init
420 * @param None
421 * @retval None
422 */
rt_hw_usart_init(void)423 int rt_hw_usart_init(void)
424 {
425 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
426 int i;
427
428 int result;
429
430 for (i = 0; i < sizeof(uart_obj) / sizeof(uart_obj[0]); i++)
431 {
432 uart_obj[i].serial->ops = &gd32_uart_ops;
433 uart_obj[i].serial->config = config;
434
435 /* register UART1 device */
436 result = rt_hw_serial_register(uart_obj[i].serial,
437 uart_obj[i].device_name,
438 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
439 (void *)&uart_obj[i]);
440 RT_ASSERT(result == RT_EOK);
441 }
442
443 return result;
444 }
445
446 //INIT_BOARD_EXPORT(rt_hw_usart_init);
447
448 #endif
449