drv_uart.c 7.1 KB

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