drv_uart.c 6.5 KB

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