drv_uart.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-06-29 Rbb666 first version
  9. * 2025-04-21 hydevcode modify xmc7100d uart
  10. */
  11. #include <rtthread.h>
  12. #include "drv_uart.h"
  13. #include "uart_config.h"
  14. #include "cyhal_scb_common.h"
  15. enum
  16. {
  17. #ifdef BSP_USING_UART0
  18. UART0_INDEX,
  19. #endif
  20. #ifdef BSP_USING_UART1
  21. UART1_INDEX,
  22. #endif
  23. #ifdef BSP_USING_UART2
  24. UART2_INDEX,
  25. #endif
  26. #ifdef BSP_USING_UART3
  27. UART3_INDEX,
  28. #endif
  29. #ifdef BSP_USING_UART4
  30. UART4_INDEX,
  31. #endif
  32. #ifdef BSP_USING_UART5
  33. UART5_INDEX,
  34. #endif
  35. #ifdef BSP_USING_UART6
  36. UART6_INDEX,
  37. #endif
  38. };
  39. static struct ifx_uart_config uart_config[] =
  40. {
  41. #ifdef BSP_USING_UART0
  42. UART0_CONFIG,
  43. #endif
  44. #ifdef BSP_USING_UART1
  45. UART1_CONFIG,
  46. #endif
  47. #ifdef BSP_USING_UART2
  48. UART2_CONFIG,
  49. #endif
  50. #ifdef BSP_USING_UART3
  51. UART3_CONFIG,
  52. #endif
  53. #ifdef BSP_USING_UART4
  54. UART4_CONFIG,
  55. #endif
  56. #ifdef BSP_USING_UART5
  57. UART5_CONFIG,
  58. #endif
  59. #ifdef BSP_USING_UART6
  60. UART6_CONFIG,
  61. #endif
  62. };
  63. static struct ifx_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] =
  64. {0};
  65. static void uart_isr(struct rt_serial_device *serial)
  66. {
  67. RT_ASSERT(serial != RT_NULL);
  68. struct ifx_uart *uart = (struct ifx_uart *) serial->parent.user_data;
  69. RT_ASSERT(uart != RT_NULL);
  70. if ((uart->config->usart_x->INTR_RX_MASKED & SCB_INTR_RX_MASKED_NOT_EMPTY_Msk) != 0)
  71. {
  72. /* Clear UART "RX fifo not empty interrupt" */
  73. uart->config->usart_x->INTR_RX = uart->config->usart_x->INTR_RX & SCB_INTR_RX_NOT_EMPTY_Msk;
  74. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  75. }
  76. }
  77. #ifdef BSP_USING_UART0
  78. /* UART0 Interrupt Hanlder */
  79. void uart0_isr_callback(void)
  80. {
  81. /* enter interrupt */
  82. rt_interrupt_enter();
  83. uart_isr(&uart_obj[UART0_INDEX].serial);
  84. /* leave interrupt */
  85. rt_interrupt_leave();
  86. }
  87. #endif
  88. #ifdef BSP_USING_UART1
  89. /* UART1 Interrupt Hanlder */
  90. void uart1_isr_callback(void)
  91. {
  92. /* enter interrupt */
  93. rt_interrupt_enter();
  94. uart_isr(&uart_obj[UART1_INDEX].serial);
  95. /* leave interrupt */
  96. rt_interrupt_leave();
  97. }
  98. #endif
  99. #ifdef BSP_USING_UART2
  100. /* UART2 Interrupt Hanlder */
  101. void uart2_isr_callback(void)
  102. {
  103. /* enter interrupt */
  104. rt_interrupt_enter();
  105. uart_isr(&uart_obj[UART2_INDEX].serial);
  106. /* leave interrupt */
  107. rt_interrupt_leave();
  108. }
  109. #endif
  110. #ifdef BSP_USING_UART3
  111. /* UART3 Interrupt Hanlder */
  112. void uart3_isr_callback(void)
  113. {
  114. /* enter interrupt */
  115. rt_interrupt_enter();
  116. uart_isr(&uart_obj[UART3_INDEX].serial);
  117. /* leave interrupt */
  118. rt_interrupt_leave();
  119. }
  120. #endif
  121. #ifdef BSP_USING_UART4
  122. /* UART4 Interrupt Hanlder */
  123. void uart4_isr_callback(void)
  124. {
  125. /* enter interrupt */
  126. rt_interrupt_enter();
  127. uart_isr(&uart_obj[UART4_INDEX].serial);
  128. /* leave interrupt */
  129. rt_interrupt_leave();
  130. }
  131. #endif
  132. #ifdef BSP_USING_UART5
  133. /* UART5 Interrupt Hanlder */
  134. void uart5_isr_callback(void)
  135. {
  136. /* enter interrupt */
  137. rt_interrupt_enter();
  138. uart_isr(&uart_obj[UART5_INDEX].serial);
  139. /* leave interrupt */
  140. rt_interrupt_leave();
  141. }
  142. #endif
  143. #ifdef BSP_USING_UART6
  144. /* UART5 Interrupt Hanlder */
  145. void uart6_isr_callback(void)
  146. {
  147. /* enter interrupt */
  148. rt_interrupt_enter();
  149. uart_isr(&uart_obj[UART6_INDEX].serial);
  150. /* leave interrupt */
  151. rt_interrupt_leave();
  152. }
  153. #endif
  154. /*
  155. * UARTHS interface
  156. */
  157. static rt_err_t ifx_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  158. {
  159. RT_ASSERT(serial != RT_NULL);
  160. struct ifx_uart *uart = (struct ifx_uart *) serial->parent.user_data;
  161. RT_ASSERT(uart != RT_NULL);
  162. cy_en_scb_uart_status_t result;
  163. const cyhal_uart_cfg_t uart_config =
  164. {
  165. .data_bits = 8,
  166. .stop_bits = 1,
  167. .parity = CYHAL_UART_PARITY_NONE,
  168. .rx_buffer = NULL,
  169. .rx_buffer_size = 0
  170. };
  171. /* Initialize retarget-io to use the debug UART port */
  172. result = cyhal_uart_init(uart->config->uart_obj, uart->config->tx_pin, uart->config->rx_pin, NC, NC, NULL, &uart_config);
  173. if (result == CY_RSLT_SUCCESS)
  174. {
  175. result = cyhal_uart_set_baud(uart->config->uart_obj, cfg->baud_rate, NULL);
  176. }
  177. RT_ASSERT(result == RT_EOK);
  178. return RT_EOK;
  179. }
  180. static rt_err_t ifx_control(struct rt_serial_device *serial, int cmd, void *arg)
  181. {
  182. RT_ASSERT(serial != RT_NULL);
  183. struct ifx_uart *uart = (struct ifx_uart *) serial->parent.user_data;
  184. RT_ASSERT(uart != RT_NULL);
  185. switch (cmd)
  186. {
  187. case RT_DEVICE_CTRL_CLR_INT:
  188. break;
  189. case RT_DEVICE_CTRL_SET_INT:
  190. /* Unmasking only the RX fifo not empty interrupt bit */
  191. uart->config->usart_x->INTR_RX_MASK = SCB_INTR_RX_MASK_NOT_EMPTY_Msk;
  192. /* Interrupt Settings for UART */
  193. Cy_SysInt_Init(uart->config->UART_SCB_IRQ_cfg, uart->config->userIsr);
  194. /* Enable the interrupt */
  195. #if defined(SOC_SERIES_IFX_XMC)
  196. NVIC_DisableIRQ(UART_NvicMuxN_IRQn);
  197. NVIC_EnableIRQ(UART_NvicMuxN_IRQn);
  198. #else
  199. NVIC_EnableIRQ(uart->config->UART_SCB_IRQ_cfg->intrSrc);
  200. #endif
  201. break;
  202. }
  203. return (RT_EOK);
  204. }
  205. static int ifx_uarths_putc(struct rt_serial_device *serial, char c)
  206. {
  207. RT_ASSERT(serial != RT_NULL);
  208. struct ifx_uart *uart = (struct ifx_uart *) serial->parent.user_data;
  209. RT_ASSERT(uart != RT_NULL);
  210. if (_cyhal_scb_pm_transition_pending())
  211. return CYHAL_SYSPM_RSLT_ERR_PM_PENDING;
  212. uint32_t count = 0;
  213. while (count == 0)
  214. {
  215. count = Cy_SCB_UART_Put(uart->config->usart_x, c);
  216. }
  217. return (1);
  218. }
  219. static int ifx_uarths_getc(struct rt_serial_device *serial)
  220. {
  221. int ch;
  222. rt_uint8_t read_data;
  223. RT_ASSERT(serial != RT_NULL);
  224. struct ifx_uart *uart = (struct ifx_uart *) serial->parent.user_data;
  225. RT_ASSERT(uart != RT_NULL);
  226. ch = -1;
  227. if (RT_EOK == cyhal_uart_getc(uart->config->uart_obj, (uint8_t *)&read_data, 10))
  228. {
  229. ch = read_data & 0xff;
  230. }
  231. else
  232. {
  233. ch = -1;
  234. }
  235. return ch;
  236. }
  237. const struct rt_uart_ops _uart_ops =
  238. {
  239. ifx_configure,
  240. ifx_control,
  241. ifx_uarths_putc,
  242. ifx_uarths_getc,
  243. RT_NULL
  244. };
  245. void rt_hw_uart_init(void)
  246. {
  247. int index;
  248. rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct ifx_uart);
  249. struct serial_configure serial_config = RT_SERIAL_CONFIG_DEFAULT;
  250. rt_err_t result = 0;
  251. for (index = 0; index < obj_num; index++)
  252. {
  253. uart_obj[index].config = &uart_config[index];
  254. uart_obj[index].serial.ops = &_uart_ops;
  255. uart_obj[index].serial.config = serial_config;
  256. uart_obj[index].config->uart_obj = rt_malloc(sizeof(cyhal_uart_t));
  257. RT_ASSERT(uart_obj[index].config->uart_obj != RT_NULL);
  258. /* register uart device */
  259. result = rt_hw_serial_register(&uart_obj[index].serial,
  260. uart_obj[index].config->name,
  261. RT_DEVICE_FLAG_RDWR |
  262. RT_DEVICE_FLAG_INT_RX,
  263. &uart_obj[index]);
  264. RT_ASSERT(result == RT_EOK);
  265. }
  266. }