drv_uart.c 6.9 KB

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