1
0

drv_usart.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * File : drv_usart.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2009-01-05 Bernard the first version
  13. * 2018-04-19 misonyo Porting for gd32f30x
  14. */
  15. #include <rthw.h>
  16. #include <drv_usart.h>
  17. #include <rtthread.h>
  18. #include "gd32f30x.h"
  19. #ifdef RT_USING_SERIAL
  20. #define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n))
  21. #define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n))
  22. #if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) && \
  23. !defined(RT_USING_USART2) && !defined(RT_USING_UART3) && \
  24. !defined(RT_USING_UART4)
  25. #error "Please define at least one UARTx"
  26. #endif
  27. #include <rtdevice.h>
  28. /* GD32 uart driver */
  29. // Todo: compress uart info
  30. struct gd32_uart
  31. {
  32. uint32_t uart_periph;
  33. IRQn_Type irqn;
  34. rcu_periph_enum per_clk;
  35. rcu_periph_enum tx_gpio_clk;
  36. rcu_periph_enum rx_gpio_clk;
  37. uint32_t tx_port;
  38. uint16_t tx_pin;
  39. uint32_t rx_port;
  40. uint16_t rx_pin;
  41. struct rt_serial_device * serial;
  42. char *device_name;
  43. };
  44. static void uart_isr(struct rt_serial_device *serial);
  45. #if defined(RT_USING_USART0)
  46. struct rt_serial_device serial0;
  47. void USART0_IRQHandler(void)
  48. {
  49. /* enter interrupt */
  50. rt_interrupt_enter();
  51. uart_isr(&serial0);
  52. /* leave interrupt */
  53. rt_interrupt_leave();
  54. }
  55. #endif /* RT_USING_USART0 */
  56. #if defined(RT_USING_USART1)
  57. struct rt_serial_device serial1;
  58. void USART1_IRQHandler(void)
  59. {
  60. /* enter interrupt */
  61. rt_interrupt_enter();
  62. uart_isr(&serial1);
  63. /* leave interrupt */
  64. rt_interrupt_leave();
  65. }
  66. #endif /* RT_USING_UART1 */
  67. #if defined(RT_USING_USART2)
  68. struct rt_serial_device serial2;
  69. void USART2_IRQHandler(void)
  70. {
  71. /* enter interrupt */
  72. rt_interrupt_enter();
  73. uart_isr(&serial2);
  74. /* leave interrupt */
  75. rt_interrupt_leave();
  76. }
  77. #endif /* RT_USING_UART2 */
  78. #if defined(RT_USING_UART3)
  79. struct rt_serial_device serial3;
  80. void UART3_IRQHandler(void)
  81. {
  82. /* enter interrupt */
  83. rt_interrupt_enter();
  84. uart_isr(&serial3);
  85. /* leave interrupt */
  86. rt_interrupt_leave();
  87. }
  88. #endif /* RT_USING_UART3 */
  89. #if defined(RT_USING_UART4)
  90. struct rt_serial_device serial4;
  91. void UART4_IRQHandler(void)
  92. {
  93. /* enter interrupt */
  94. rt_interrupt_enter();
  95. uart_isr(&serial4);
  96. /* leave interrupt */
  97. rt_interrupt_leave();
  98. }
  99. #endif /* RT_USING_UART4 */
  100. static const struct gd32_uart uarts[] = {
  101. #ifdef RT_USING_USART0
  102. {
  103. USART0, // uart peripheral index
  104. USART0_IRQn, // uart iqrn
  105. RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock
  106. GPIOA, GPIO_PIN_9, // tx port, tx pin
  107. GPIOA, GPIO_PIN_10, // rx port, rx pin
  108. &serial0,
  109. "uart0",
  110. },
  111. #endif
  112. #ifdef RT_USING_USART1
  113. {
  114. USART1, // uart peripheral index
  115. USART1_IRQn, // uart iqrn
  116. RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock
  117. GPIOA, GPIO_PIN_2, // tx port, tx pin
  118. GPIOA, GPIO_PIN_3, // rx port, rx pin
  119. &serial1,
  120. "uart1",
  121. },
  122. #endif
  123. #ifdef RT_USING_USART2
  124. {
  125. USART2, // uart peripheral index
  126. USART2_IRQn, // uart iqrn
  127. RCU_USART2, RCU_GPIOB, RCU_GPIOB, // periph clock, tx gpio clock, rt gpio clock
  128. GPIOB, GPIO_PIN_10, // tx port, tx alternate, tx pin
  129. GPIOB, GPIO_PIN_11, // rx port, rx alternate, rx pin
  130. &serial2,
  131. "uart2",
  132. },
  133. #endif
  134. #ifdef RT_USING_UART3
  135. {
  136. UART3, // uart peripheral index
  137. UART3_IRQn, // uart iqrn
  138. RCU_UART3, RCU_GPIOC, RCU_GPIOC, // periph clock, tx gpio clock, rt gpio clock
  139. GPIOC, GPIO_PIN_10, // tx port, tx alternate, tx pin
  140. GPIOC, GPIO_PIN_11, // rx port, rx alternate, rx pin
  141. &serial3,
  142. "uart3",
  143. },
  144. #endif
  145. #ifdef RT_USING_UART4
  146. {
  147. UART4, // uart peripheral index
  148. UART4_IRQn, // uart iqrn
  149. RCU_UART4, RCU_GPIOC, RCU_GPIOD, // periph clock, tx gpio clock, rt gpio clock
  150. GPIOC, GPIO_PIN_12, // tx port, tx alternate, tx pin
  151. GPIOD, GPIO_PIN_2, // rx port, rx alternate, rx pin
  152. &serial4,
  153. "uart4",
  154. },
  155. #endif
  156. };
  157. /**
  158. * @brief UART MSP Initialization
  159. * This function configures the hardware resources used in this example:
  160. * - Peripheral's clock enable
  161. * - Peripheral's GPIO Configuration
  162. * - NVIC configuration for UART interrupt request enable
  163. * @param uart: UART handle pointer
  164. * @retval None
  165. */
  166. void gd32_uart_gpio_init(struct gd32_uart *uart)
  167. {
  168. /* enable USART clock */
  169. rcu_periph_clock_enable(uart->tx_gpio_clk);
  170. rcu_periph_clock_enable(uart->rx_gpio_clk);
  171. rcu_periph_clock_enable(uart->per_clk);
  172. /* connect port to USARTx_Tx */
  173. gpio_init(uart->tx_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, uart->tx_pin);
  174. /* connect port to USARTx_Rx */
  175. gpio_init(uart->rx_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, uart->rx_pin);
  176. NVIC_SetPriority(uart->irqn, 0);
  177. NVIC_EnableIRQ(uart->irqn);
  178. }
  179. static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  180. {
  181. struct gd32_uart *uart;
  182. RT_ASSERT(serial != RT_NULL);
  183. RT_ASSERT(cfg != RT_NULL);
  184. uart = (struct gd32_uart *)serial->parent.user_data;
  185. gd32_uart_gpio_init(uart);
  186. usart_baudrate_set(uart->uart_periph, cfg->baud_rate);
  187. switch (cfg->data_bits)
  188. {
  189. case DATA_BITS_9:
  190. usart_word_length_set(uart->uart_periph, USART_WL_9BIT);
  191. break;
  192. default:
  193. usart_word_length_set(uart->uart_periph, USART_WL_8BIT);
  194. break;
  195. }
  196. switch (cfg->stop_bits)
  197. {
  198. case STOP_BITS_2:
  199. usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT);
  200. break;
  201. default:
  202. usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT);
  203. break;
  204. }
  205. switch (cfg->parity)
  206. {
  207. case PARITY_ODD:
  208. usart_parity_config(uart->uart_periph, USART_PM_ODD);
  209. break;
  210. case PARITY_EVEN:
  211. usart_parity_config(uart->uart_periph, USART_PM_EVEN);
  212. break;
  213. default:
  214. usart_parity_config(uart->uart_periph, USART_PM_NONE);
  215. break;
  216. }
  217. usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE);
  218. usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE);
  219. usart_enable(uart->uart_periph);
  220. return RT_EOK;
  221. }
  222. static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg)
  223. {
  224. struct gd32_uart *uart;
  225. RT_ASSERT(serial != RT_NULL);
  226. uart = (struct gd32_uart *)serial->parent.user_data;
  227. switch (cmd)
  228. {
  229. case RT_DEVICE_CTRL_CLR_INT:
  230. /* disable rx irq */
  231. NVIC_DisableIRQ(uart->irqn);
  232. /* disable interrupt */
  233. usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE);
  234. break;
  235. case RT_DEVICE_CTRL_SET_INT:
  236. /* enable rx irq */
  237. NVIC_EnableIRQ(uart->irqn);
  238. /* enable interrupt */
  239. usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE);
  240. break;
  241. }
  242. return RT_EOK;
  243. }
  244. static int gd32_putc(struct rt_serial_device *serial, char ch)
  245. {
  246. struct gd32_uart *uart;
  247. RT_ASSERT(serial != RT_NULL);
  248. uart = (struct gd32_uart *)serial->parent.user_data;
  249. usart_data_transmit(uart->uart_periph, ch);
  250. while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET));
  251. return 1;
  252. }
  253. static int gd32_getc(struct rt_serial_device *serial)
  254. {
  255. int ch;
  256. struct gd32_uart *uart;
  257. RT_ASSERT(serial != RT_NULL);
  258. uart = (struct gd32_uart *)serial->parent.user_data;
  259. ch = -1;
  260. if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)
  261. ch = usart_data_receive(uart->uart_periph);
  262. return ch;
  263. }
  264. /**
  265. * Uart common interrupt process. This need add to uart ISR.
  266. *
  267. * @param serial serial device
  268. */
  269. static void uart_isr(struct rt_serial_device *serial)
  270. {
  271. struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data;
  272. RT_ASSERT(uart != RT_NULL);
  273. /* UART in mode Receiver */
  274. if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) &&
  275. (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET))
  276. {
  277. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  278. /* Clear RXNE interrupt flag */
  279. usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE);
  280. }
  281. }
  282. static const struct rt_uart_ops gd32_uart_ops =
  283. {
  284. gd32_configure,
  285. gd32_control,
  286. gd32_putc,
  287. gd32_getc
  288. };
  289. int gd32_hw_usart_init(void)
  290. {
  291. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  292. int i;
  293. for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++)
  294. {
  295. uarts[i].serial->ops = &gd32_uart_ops;
  296. uarts[i].serial->config = config;
  297. /* register UART device */
  298. rt_hw_serial_register(uarts[i].serial,
  299. uarts[i].device_name,
  300. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  301. (void *)&uarts[i]);
  302. }
  303. return 0;
  304. }
  305. INIT_BOARD_EXPORT(gd32_hw_usart_init);
  306. #endif