drv_uart.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * Copyright (c) 2006-2020, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-04-22 hqfang First version
  9. */
  10. #include <drv_uart.h>
  11. #ifdef RT_USING_SERIAL
  12. #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1)
  13. #error "Please define at least one BSP_USING_UARTx"
  14. /* this driver can be enabled at menuconfig ->
  15. Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable UART */
  16. #endif
  17. enum
  18. {
  19. #ifdef BSP_USING_UART0
  20. UART0_INDEX,
  21. #endif
  22. #ifdef BSP_USING_UART1
  23. UART1_INDEX,
  24. #endif
  25. };
  26. static struct hbird_uart_config uart_config[] =
  27. {
  28. #ifdef BSP_USING_UART0
  29. {
  30. "uart0",
  31. UART0,
  32. SOC_INT19_IRQn,
  33. },
  34. #endif
  35. #ifdef BSP_USING_UART1
  36. {
  37. "uart1",
  38. UART1,
  39. SOC_INT20_IRQn,
  40. },
  41. #endif
  42. };
  43. static struct hbird_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
  44. static rt_err_t hbird_configure(struct rt_serial_device *serial,
  45. struct serial_configure *cfg)
  46. {
  47. struct hbird_uart *uart_obj;
  48. struct hbird_uart_config *uart_cfg;
  49. RT_ASSERT(serial != RT_NULL);
  50. RT_ASSERT(cfg != RT_NULL);
  51. uart_obj = (struct hbird_uart *) serial->parent.user_data;
  52. uart_cfg = uart_obj->config;
  53. RT_ASSERT(uart_cfg != RT_NULL);
  54. uart_init(uart_cfg->uart, cfg->baud_rate);
  55. switch (cfg->stop_bits)
  56. {
  57. case STOP_BITS_1:
  58. uart_config_stopbit(uart_cfg->uart, UART_STOP_BIT_1);
  59. break;
  60. case STOP_BITS_2:
  61. uart_config_stopbit(uart_cfg->uart, UART_STOP_BIT_2);
  62. break;
  63. default:
  64. uart_config_stopbit(uart_cfg->uart, UART_STOP_BIT_1);
  65. break;
  66. }
  67. return RT_EOK;
  68. }
  69. static rt_err_t hbird_control(struct rt_serial_device *serial, int cmd,
  70. void *arg)
  71. {
  72. struct hbird_uart *uart_obj;
  73. struct hbird_uart_config *uart_cfg;
  74. RT_ASSERT(serial != RT_NULL);
  75. uart_obj = (struct hbird_uart *) serial->parent.user_data;
  76. uart_cfg = uart_obj->config;
  77. RT_ASSERT(uart_cfg != RT_NULL);
  78. switch (cmd)
  79. {
  80. case RT_DEVICE_CTRL_CLR_INT:
  81. ECLIC_DisableIRQ(uart_cfg->irqn);
  82. uart_disable_rxint(uart_cfg->uart);
  83. break;
  84. case RT_DEVICE_CTRL_SET_INT:
  85. ECLIC_EnableIRQ(uart_cfg->irqn);
  86. ECLIC_SetShvIRQ(uart_cfg->irqn, ECLIC_NON_VECTOR_INTERRUPT);
  87. ECLIC_SetLevelIRQ(uart_cfg->irqn, 1);
  88. uart_enable_rxint(uart_cfg->uart);
  89. break;
  90. }
  91. return RT_EOK;
  92. }
  93. static int hbird_putc(struct rt_serial_device *serial, char ch)
  94. {
  95. struct hbird_uart *uart_obj;
  96. struct hbird_uart_config *uart_cfg;
  97. RT_ASSERT(serial != RT_NULL);
  98. uart_obj = (struct hbird_uart *) serial->parent.user_data;
  99. uart_cfg = uart_obj->config;
  100. RT_ASSERT(uart_cfg != RT_NULL);
  101. uart_write(uart_cfg->uart, ch);
  102. return 1;
  103. }
  104. static int hbird_getc(struct rt_serial_device *serial)
  105. {
  106. int ch;
  107. uint32_t rxfifo;
  108. struct hbird_uart *uart_obj;
  109. struct hbird_uart_config *uart_cfg;
  110. RT_ASSERT(serial != RT_NULL);
  111. uart_obj = (struct hbird_uart *) serial->parent.user_data;
  112. uart_cfg = uart_obj->config;
  113. RT_ASSERT(uart_cfg != RT_NULL);
  114. ch = -1;
  115. rxfifo = uart_cfg->uart->RXFIFO;
  116. if ((rxfifo & UART_RXFIFO_EMPTY) != UART_RXFIFO_EMPTY) {
  117. ch = (int)(uint8_t)(rxfifo);
  118. }
  119. return ch;
  120. }
  121. static const struct rt_uart_ops hbird_uart_ops = { hbird_configure, hbird_control,
  122. hbird_putc, hbird_getc,
  123. RT_NULL
  124. };
  125. static void gd32_uart_isr(struct rt_serial_device *serial)
  126. {
  127. struct hbird_uart *uart_obj;
  128. struct hbird_uart_config *uart_cfg;
  129. RT_ASSERT(serial != RT_NULL);
  130. uart_obj = (struct hbird_uart *) serial->parent.user_data;
  131. uart_cfg = uart_obj->config;
  132. RT_ASSERT(uart_cfg != RT_NULL);
  133. if (uart_cfg->uart->IP & UART_IP_RXIP_MASK) {
  134. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  135. }
  136. }
  137. #ifdef BSP_USING_UART0
  138. void eclic_irq19_handler(void)
  139. {
  140. rt_interrupt_enter();
  141. gd32_uart_isr(&uart_obj[UART0_INDEX].serial);
  142. rt_interrupt_leave();
  143. }
  144. #endif
  145. #ifdef BSP_USING_UART1
  146. void eclic_irq20_handler(void)
  147. {
  148. rt_interrupt_enter();
  149. gd32_uart_isr(&uart_obj[UART1_INDEX].serial);
  150. rt_interrupt_leave();
  151. }
  152. #endif
  153. /* For Nuclei demosoc Uart, when CPU freq is lower than 8M
  154. The uart read will only work on baudrate <= 57600.
  155. Nowadays, we usually distribute FPGA bitsteam with CPU Freq 16MHz */
  156. #define DRV_UART_BAUDRATE BAUD_RATE_115200
  157. int rt_hw_uart_init(void)
  158. {
  159. rt_size_t obj_num;
  160. int index;
  161. obj_num = sizeof(uart_obj) / sizeof(struct hbird_uart);
  162. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  163. config.baud_rate = DRV_UART_BAUDRATE;
  164. rt_err_t result = 0;
  165. for (index = 0; index < obj_num; index++)
  166. {
  167. /* init UART object */
  168. uart_obj[index].config = &uart_config[index];
  169. uart_obj[index].serial.ops = &hbird_uart_ops;
  170. uart_obj[index].serial.config = config;
  171. /* register UART device */
  172. result = rt_hw_serial_register(&uart_obj[index].serial,
  173. uart_obj[index].config->name,
  174. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  175. &uart_obj[index]);
  176. RT_ASSERT(result == RT_EOK);
  177. }
  178. return result;
  179. }
  180. void rt_hw_serial_rcvtsk(void *parameter)
  181. {
  182. struct hbird_uart_config *uart_cfg;
  183. while (1) {
  184. #ifdef BSP_USING_UART0
  185. uart_cfg = uart_obj[UART0_INDEX].config;
  186. if (uart_cfg->uart->IP & UART_IP_RXIP_MASK) {
  187. gd32_uart_isr(&uart_obj[UART0_INDEX].serial);
  188. }
  189. #endif
  190. #ifdef BSP_USING_UART1
  191. uart_cfg = uart_obj[UART1_INDEX].config;
  192. if (uart_cfg->uart->IP & UART_IP_RXIP_MASK) {
  193. gd32_uart_isr(&uart_obj[UART1_INDEX].serial);
  194. }
  195. #endif
  196. rt_thread_mdelay(50);
  197. }
  198. }
  199. #endif /* RT_USING_SERIAL */
  200. /******************** end of file *******************/