drv_usart.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) 2006-2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2025-04-27 WangShun the first version
  9. */
  10. #include "board.h"
  11. #include "rtthread.h"
  12. #include <rtdevice.h>
  13. #include <string.h>
  14. #include <drv_usart.h>
  15. #ifdef RT_USING_SERIAL
  16. #define DRV_DEBUG
  17. #define LOG_TAG "drv.uart"
  18. #ifdef DRV_DEBUG
  19. #define DBG_LVL DBG_LOG
  20. #else
  21. #define DBG_LVL DBG_INFO
  22. #endif /* DRV_DEBUG */
  23. #include <rtdbg.h>
  24. #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3) \
  25. && !defined(BSP_USING_UART4) && !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6) && !defined(BSP_USING_UART7)
  26. #error "Please define at least one BSP_USING_UARTx"
  27. /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
  28. #endif
  29. static void xuantie_uart0_rx_isr(csi_uart_t *uart_handler, csi_uart_event_t event, void *arg);
  30. enum
  31. {
  32. #ifdef BSP_USING_UART0
  33. UART0_INDEX,
  34. #endif
  35. };
  36. struct xuantie_uart_config uart_config[] =
  37. {
  38. #ifdef BSP_USING_UART0
  39. {
  40. "uart0",
  41. 0,
  42. xuantie_uart0_rx_isr
  43. }
  44. #endif
  45. };
  46. struct xuantie_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};
  47. static rt_err_t xuantie_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  48. {
  49. struct xuantie_uart *uart = (struct xuantie_uart *)serial->parent.user_data;
  50. csi_error_t ret;
  51. ret = csi_uart_baud(&uart->uart, cfg->baud_rate);
  52. if (ret != CSI_OK)
  53. {
  54. return -RT_ERROR;
  55. }
  56. csi_uart_data_bits_t data_bits;
  57. csi_uart_parity_t parity;
  58. csi_uart_stop_bits_t stop_bits;
  59. switch (cfg->data_bits)
  60. {
  61. case DATA_BITS_5:
  62. data_bits = UART_DATA_BITS_5;
  63. break;
  64. case DATA_BITS_6:
  65. data_bits = UART_DATA_BITS_6;
  66. break;
  67. case DATA_BITS_7:
  68. data_bits = UART_DATA_BITS_7;
  69. break;
  70. case DATA_BITS_8:
  71. data_bits = UART_DATA_BITS_8;
  72. break;
  73. case DATA_BITS_9:
  74. data_bits = UART_DATA_BITS_9;
  75. break;
  76. default:
  77. data_bits = UART_DATA_BITS_8;
  78. break;
  79. }
  80. switch (cfg->parity)
  81. {
  82. case PARITY_NONE:
  83. parity = UART_PARITY_NONE;
  84. break;
  85. case PARITY_ODD:
  86. parity = UART_PARITY_ODD;
  87. break;
  88. case PARITY_EVEN:
  89. parity = UART_PARITY_EVEN;
  90. break;
  91. default:
  92. parity = UART_PARITY_NONE;
  93. break;
  94. }
  95. switch (cfg->stop_bits)
  96. {
  97. case STOP_BITS_1:
  98. stop_bits = UART_STOP_BITS_1;
  99. break;
  100. case STOP_BITS_2:
  101. stop_bits = UART_STOP_BITS_2;
  102. break;
  103. default:
  104. stop_bits = UART_STOP_BITS_1;
  105. break;
  106. }
  107. ret = csi_uart_format(&uart->uart, data_bits, parity, stop_bits);
  108. if (ret != CSI_OK)
  109. {
  110. return -RT_ERROR;
  111. }
  112. return RT_EOK;
  113. }
  114. static rt_err_t xuantie_control(struct rt_serial_device *serial, int cmd, void *arg)
  115. {
  116. switch (cmd)
  117. {
  118. case RT_DEVICE_CTRL_CONFIG:
  119. return xuantie_configure(serial, (struct serial_configure *)arg);
  120. default:
  121. return -RT_ERROR;
  122. }
  123. }
  124. static int xuantie_putc(struct rt_serial_device *serial, char c)
  125. {
  126. struct xuantie_uart *uart = (struct xuantie_uart *)serial->parent.user_data;
  127. int32_t ret;
  128. ret = csi_uart_send(&uart->uart, &c, 1, 50);
  129. if (ret == 1)
  130. return RT_EOK;
  131. return -RT_ERROR;
  132. }
  133. static int xuantie_getc(struct rt_serial_device *serial)
  134. {
  135. int c = -1;
  136. struct xuantie_uart *uart = (struct xuantie_uart *)serial->parent.user_data;
  137. dw_uart_regs_t *uart_base = (dw_uart_regs_t *)HANDLE_REG_BASE((&uart->uart));
  138. csi_uart_receive(&uart->uart, &c, 1, 0x5);
  139. dw_uart_enable_recv_irq(uart_base);
  140. return c;
  141. }
  142. static const struct rt_uart_ops xuantie_uart_ops =
  143. {
  144. xuantie_configure,
  145. xuantie_control,
  146. xuantie_putc,
  147. xuantie_getc,
  148. RT_NULL,
  149. };
  150. static void xuantie_uart0_rx_isr(csi_uart_t *uart_handler, csi_uart_event_t event, void *arg)
  151. {
  152. rt_interrupt_enter();
  153. rt_hw_serial_isr(&uart_obj[UART0_INDEX].serial, RT_SERIAL_EVENT_RX_IND);
  154. rt_interrupt_leave();
  155. }
  156. int rt_hw_usart_init(void)
  157. {
  158. rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct xuantie_uart);
  159. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  160. rt_err_t result = 0;
  161. for (int i = 0; i < obj_num; i++)
  162. {
  163. /* Initialize YOC UART */
  164. result = csi_uart_init(&uart_obj[i].uart, 0);
  165. if (result != CSI_OK)
  166. {
  167. LOG_E("Failed to initialize UART %d", uart_obj[i].config->idx);
  168. return -RT_ERROR;
  169. }
  170. /* Init UART object */
  171. uart_obj[i].config = &uart_config[i];
  172. uart_obj[i].serial.ops = &xuantie_uart_ops;
  173. uart_obj[i].serial.config = config;
  174. csi_uart_attach_callback(&uart_obj[i].uart, uart_obj[i].config->xuantie_uart_rx_isr, NULL);
  175. /* Register UART device */
  176. result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,
  177. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  178. &uart_obj[i]);
  179. if (result != RT_EOK)
  180. {
  181. LOG_E("Failed to register UART device %s", uart_obj[i].config->name);
  182. csi_uart_uninit(&uart_obj[i].uart);
  183. return -RT_ERROR;
  184. }
  185. }
  186. return result;
  187. }
  188. #endif /* RT_USING_SERIAL */