drv_uart.c 6.8 KB

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