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