drv_usart.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /*
  2. * Copyright (c) 2006-2019, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2009-01-05 Bernard the first version
  9. * 2018-04-19 misonyo Porting for gd32f30x
  10. * 2019-03-31 xuzhuoyi Porting for gd32e230
  11. */
  12. #include <rthw.h>
  13. #include <drv_usart.h>
  14. #include <rtthread.h>
  15. #include "gd32e230.h"
  16. #ifdef RT_USING_SERIAL
  17. #define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n))
  18. #define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n))
  19. #if !defined(RT_USING_USART0) && !defined(RT_USING_USART1)
  20. #error "Please define at least one UARTx"
  21. #endif
  22. #include <rtdevice.h>
  23. /* GD32 uart driver */
  24. // Todo: compress uart info
  25. struct gd32_uart
  26. {
  27. uint32_t uart_periph;
  28. IRQn_Type irqn;
  29. rcu_periph_enum per_clk;
  30. rcu_periph_enum tx_gpio_clk;
  31. rcu_periph_enum rx_gpio_clk;
  32. uint32_t tx_port;
  33. uint32_t tx_af;
  34. uint16_t tx_pin;
  35. uint32_t rx_port;
  36. uint32_t rx_af;
  37. uint16_t rx_pin;
  38. struct rt_serial_device * serial;
  39. char *device_name;
  40. };
  41. static void uart_isr(struct rt_serial_device *serial);
  42. #if defined(RT_USING_USART0)
  43. struct rt_serial_device serial0;
  44. void USART0_IRQHandler(void)
  45. {
  46. /* enter interrupt */
  47. rt_interrupt_enter();
  48. uart_isr(&serial0);
  49. /* leave interrupt */
  50. rt_interrupt_leave();
  51. }
  52. #endif /* RT_USING_USART0 */
  53. #if defined(RT_USING_USART1)
  54. struct rt_serial_device serial1;
  55. void USART1_IRQHandler(void)
  56. {
  57. /* enter interrupt */
  58. rt_interrupt_enter();
  59. uart_isr(&serial1);
  60. /* leave interrupt */
  61. rt_interrupt_leave();
  62. }
  63. #endif /* RT_USING_UART1 */
  64. static const struct gd32_uart uarts[] = {
  65. #ifdef RT_USING_USART0
  66. {
  67. USART0, // uart peripheral index
  68. USART0_IRQn, // uart iqrn
  69. RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock
  70. GPIOA, GPIO_AF_1, GPIO_PIN_9, // tx port, tx pin
  71. GPIOA, GPIO_AF_1, GPIO_PIN_10, // rx port, rx pin
  72. &serial0,
  73. "uart0",
  74. },
  75. #endif
  76. #ifdef RT_USING_USART1
  77. {
  78. USART1, // uart peripheral index
  79. USART1_IRQn, // uart iqrn
  80. RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock
  81. GPIOA, GPIO_AF_1, GPIO_PIN_2, // tx port, tx pin
  82. GPIOA, GPIO_AF_1, GPIO_PIN_3, // rx port, rx pin
  83. &serial1,
  84. "uart1",
  85. },
  86. #endif
  87. };
  88. /**
  89. * @brief UART MSP Initialization
  90. * This function configures the hardware resources used in this example:
  91. * - Peripheral's clock enable
  92. * - Peripheral's GPIO Configuration
  93. * - NVIC configuration for UART interrupt request enable
  94. * @param uart: UART handle pointer
  95. * @retval None
  96. */
  97. void gd32_uart_gpio_init(struct gd32_uart *uart)
  98. {
  99. /* enable USART clock */
  100. rcu_periph_clock_enable(uart->tx_gpio_clk);
  101. rcu_periph_clock_enable(uart->rx_gpio_clk);
  102. rcu_periph_clock_enable(uart->per_clk);
  103. /* connect port to USARTx_Tx */
  104. gpio_af_set(uart->tx_port, uart->tx_af, uart->tx_pin);
  105. gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, uart->tx_pin);
  106. gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, uart->tx_pin);
  107. /* connect port to USARTx_Rx */
  108. gpio_af_set(uart->rx_port, uart->rx_af, uart->rx_pin);
  109. gpio_mode_set(uart->rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, uart->rx_pin);
  110. gpio_output_options_set(uart->rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, uart->rx_pin);
  111. NVIC_SetPriority(uart->irqn, 0);
  112. NVIC_EnableIRQ(uart->irqn);
  113. }
  114. static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  115. {
  116. struct gd32_uart *uart;
  117. RT_ASSERT(serial != RT_NULL);
  118. RT_ASSERT(cfg != RT_NULL);
  119. uart = (struct gd32_uart *)serial->parent.user_data;
  120. gd32_uart_gpio_init(uart);
  121. usart_baudrate_set(uart->uart_periph, cfg->baud_rate);
  122. switch (cfg->data_bits)
  123. {
  124. case DATA_BITS_9:
  125. usart_word_length_set(uart->uart_periph, USART_WL_9BIT);
  126. break;
  127. default:
  128. usart_word_length_set(uart->uart_periph, USART_WL_8BIT);
  129. break;
  130. }
  131. switch (cfg->stop_bits)
  132. {
  133. case STOP_BITS_2:
  134. usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT);
  135. break;
  136. default:
  137. usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT);
  138. break;
  139. }
  140. switch (cfg->parity)
  141. {
  142. case PARITY_ODD:
  143. usart_parity_config(uart->uart_periph, USART_PM_ODD);
  144. break;
  145. case PARITY_EVEN:
  146. usart_parity_config(uart->uart_periph, USART_PM_EVEN);
  147. break;
  148. default:
  149. usart_parity_config(uart->uart_periph, USART_PM_NONE);
  150. break;
  151. }
  152. usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE);
  153. usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE);
  154. usart_enable(uart->uart_periph);
  155. return RT_EOK;
  156. }
  157. static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg)
  158. {
  159. struct gd32_uart *uart;
  160. RT_ASSERT(serial != RT_NULL);
  161. uart = (struct gd32_uart *)serial->parent.user_data;
  162. switch (cmd)
  163. {
  164. case RT_DEVICE_CTRL_CLR_INT:
  165. /* disable rx irq */
  166. NVIC_DisableIRQ(uart->irqn);
  167. /* disable interrupt */
  168. usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE);
  169. break;
  170. case RT_DEVICE_CTRL_SET_INT:
  171. /* enable rx irq */
  172. NVIC_EnableIRQ(uart->irqn);
  173. /* enable interrupt */
  174. usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE);
  175. break;
  176. }
  177. return RT_EOK;
  178. }
  179. static int gd32_putc(struct rt_serial_device *serial, char ch)
  180. {
  181. struct gd32_uart *uart;
  182. RT_ASSERT(serial != RT_NULL);
  183. uart = (struct gd32_uart *)serial->parent.user_data;
  184. usart_data_transmit(uart->uart_periph, ch);
  185. while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET));
  186. return 1;
  187. }
  188. static int gd32_getc(struct rt_serial_device *serial)
  189. {
  190. int ch;
  191. struct gd32_uart *uart;
  192. RT_ASSERT(serial != RT_NULL);
  193. uart = (struct gd32_uart *)serial->parent.user_data;
  194. ch = -1;
  195. if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)
  196. ch = usart_data_receive(uart->uart_periph);
  197. return ch;
  198. }
  199. /**
  200. * Uart common interrupt process. This need add to uart ISR.
  201. *
  202. * @param serial serial device
  203. */
  204. static void uart_isr(struct rt_serial_device *serial)
  205. {
  206. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  207. RT_ASSERT(uart != RT_NULL);
  208. /* UART in mode Receiver */
  209. if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) &&
  210. (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET))
  211. {
  212. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  213. /* Clear RXNE interrupt flag */
  214. usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE);
  215. }
  216. }
  217. static const struct rt_uart_ops gd32_uart_ops =
  218. {
  219. gd32_configure,
  220. gd32_control,
  221. gd32_putc,
  222. gd32_getc
  223. };
  224. int gd32_hw_usart_init(void)
  225. {
  226. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  227. int i;
  228. for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++)
  229. {
  230. uarts[i].serial->ops = &gd32_uart_ops;
  231. uarts[i].serial->config = config;
  232. /* register UART device */
  233. rt_hw_serial_register(uarts[i].serial,
  234. uarts[i].device_name,
  235. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  236. (void *)&uarts[i]);
  237. }
  238. return 0;
  239. }
  240. INIT_BOARD_EXPORT(gd32_hw_usart_init);
  241. #endif