drv_usart_msg.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Email: opensource_embedded@phytium.com.cn
  7. *
  8. * Change Logs:
  9. * Date Author Notes
  10. * 2025-05-23 liyilun first commit
  11. */
  12. #include "rtconfig.h"
  13. #include <rtdevice.h>
  14. #include "board.h"
  15. #include <mmu.h>
  16. #include "drv_usart_msg.h"
  17. #include "interrupt.h"
  18. #include "fio_mux.h"
  19. #include "fparameters.h"
  20. #ifdef RT_USING_SMART
  21. #include <ioremap.h>
  22. #endif
  23. #define RING_BUFFER_WAIT_TIMEOUT 10000
  24. #define RING_BUFFER_SIZE 64
  25. struct rt_ringbuffer *recv_ringbuffer = NULL;
  26. rt_inline enum rt_ringbuffer_state rt_ringbuffer_status(struct rt_ringbuffer *rb)
  27. {
  28. if (rb->read_index == rb->write_index)
  29. {
  30. if (rb->read_mirror == rb->write_mirror)
  31. return RT_RINGBUFFER_EMPTY;
  32. else
  33. return RT_RINGBUFFER_FULL;
  34. }
  35. return RT_RINGBUFFER_HALFFULL;
  36. }
  37. static void Ft_Os_Uart_Msg_Callback(void *Args, u32 Event, u32 EventData);
  38. static void rt_hw_uart_msg_isr(int irqno, void *param)
  39. {
  40. FUartMsgInterruptHandler(irqno, param);
  41. }
  42. static rt_err_t uart_msg_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  43. {
  44. struct drv_usart_msg *uart_msg = RT_NULL;
  45. FUartMsg *uart_msg_hw = RT_NULL;
  46. FUartMsgConfig config;
  47. RT_ASSERT(serial != RT_NULL);
  48. RT_ASSERT(cfg != RT_NULL);
  49. uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
  50. uart_msg_hw = uart_msg->handle;
  51. config = *(const FUartMsgConfig *)FUartMsgLookupConfig(uart_msg->config.uart_instance);
  52. #ifdef RT_USING_SMART
  53. config.msg.regfile = (uintptr)rt_ioremap((void *)config.msg.regfile, 0x1000);
  54. config.msg.shmem = (uintptr)rt_ioremap((void *)config.msg.shmem, 0x1000);
  55. #endif
  56. FIOPadSetUartMux(uart_msg->config.uart_instance);
  57. RT_ASSERT(FUartMsgCfgInitialize(uart_msg_hw, &config) == FT_SUCCESS);
  58. FUartMsgSetStartUp(uart_msg_hw);
  59. FUartMsgSetHandler(uart_msg_hw, Ft_Os_Uart_Msg_Callback, serial);
  60. //<! 打开接收中断
  61. rt_hw_interrupt_set_priority(uart_msg_hw->config.irq_num, uart_msg->config.isr_priority);
  62. rt_hw_interrupt_install(uart_msg_hw->config.irq_num, rt_hw_uart_msg_isr, uart_msg_hw, "uart");
  63. rt_hw_interrupt_umask(uart_msg_hw->config.irq_num);
  64. FUartMsgEnableInterrups(uart_msg_hw);
  65. return RT_EOK;
  66. }
  67. static rt_err_t uart_msg_control(struct rt_serial_device *serial, int cmd, void *arg)
  68. {
  69. struct drv_usart_msg *uart_msg = RT_NULL;
  70. FUartMsg *uart_msg_ptr = RT_NULL;
  71. RT_ASSERT(serial != RT_NULL);
  72. uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
  73. uart_msg_ptr = uart_msg->handle;
  74. switch (cmd)
  75. {
  76. case RT_DEVICE_CTRL_CLR_INT:
  77. /* disable rx irq */
  78. rt_hw_interrupt_mask(uart_msg_ptr->config.irq_num);
  79. break;
  80. case RT_DEVICE_CTRL_SET_INT:
  81. /* enable rx irq */
  82. rt_hw_interrupt_umask(uart_msg_ptr->config.irq_num);
  83. break;
  84. }
  85. return RT_EOK;
  86. }
  87. static int uart_msg_putc(struct rt_serial_device *serial, char c)
  88. {
  89. struct drv_usart_msg *uart_msg = RT_NULL;
  90. FUartMsg *uart_msg_ptr = RT_NULL;
  91. RT_ASSERT(serial != RT_NULL);
  92. uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
  93. uart_msg_ptr = uart_msg->handle;
  94. while(-1 == FUartMsgTxChar(&(uart_msg_ptr->config.msg), (u8)c))
  95. {
  96. }
  97. return 1;
  98. }
  99. void FUartMsgRecvBufferNoBlocking(FUartMsg *uart_p)
  100. {
  101. u8 data[16] = {0};
  102. rt_size_t write_length = 0;
  103. u32 received_count = 0;
  104. while (!FUartMsgRxRingBufferIsEmpty(uart_p->config.msg.regfile))
  105. {
  106. received_count += FUartMsgRxChars(&(uart_p->config.msg), data, 16);
  107. }
  108. if(received_count > 0)
  109. {
  110. write_length = rt_ringbuffer_put(recv_ringbuffer, data, received_count);
  111. RT_ASSERT(write_length == received_count);
  112. }
  113. }
  114. static int uart_msg_getc(struct rt_serial_device *serial)
  115. {
  116. int ch;
  117. struct drv_usart_msg *uart_msg = RT_NULL;
  118. FUartMsg *uart_msg_ptr = RT_NULL;
  119. RT_ASSERT(serial != RT_NULL);
  120. uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
  121. uart_msg_ptr = uart_msg->handle;
  122. if(RT_RINGBUFFER_EMPTY == rt_ringbuffer_status(recv_ringbuffer))
  123. {
  124. FUartMsgRecvBufferNoBlocking(uart_msg_ptr);
  125. }
  126. if(0 == rt_ringbuffer_getchar(recv_ringbuffer, (rt_uint8_t *)&ch))
  127. {
  128. return -1;
  129. }
  130. if (ch == 0xffff)
  131. {
  132. ch = -1;
  133. }
  134. else
  135. {
  136. ch &= 0xff;
  137. }
  138. return ch;
  139. }
  140. static void Ft_Os_Uart_Msg_Callback(void *Args, u32 Event, u32 EventData)
  141. {
  142. struct rt_serial_device *serial = (struct rt_serial_device *)Args;
  143. if(FUART_EVENT_RECV_DATA == Event)
  144. {
  145. if(serial->serial_rx)
  146. {
  147. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  148. }
  149. }
  150. else if(FUART_EVENT_SENT_DATA == Event)
  151. {
  152. }
  153. else
  154. {
  155. }
  156. }
  157. static const struct rt_uart_ops _uart_ops =
  158. {
  159. uart_msg_configure,
  160. uart_msg_control,
  161. uart_msg_putc,
  162. uart_msg_getc,
  163. NULL
  164. };
  165. static int uart_msg_init(struct drv_usart_msg *uart_msg_dev)
  166. {
  167. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  168. config.bufsz = RT_SERIAL_RB_BUFSZ;
  169. uart_msg_dev->serial.ops = &_uart_ops;
  170. uart_msg_dev->serial.config = config;
  171. uart_msg_dev->config.isr_priority = 0xd0;
  172. uart_msg_dev->config.isr_event_mask = RTOS_UART_MSG_RX_ISR_MASK | RTOS_UART_MSG_TX_ISR_MASK;
  173. uart_msg_dev->config.uart_baudrate = BAUD_RATE_115200;
  174. recv_ringbuffer = rt_ringbuffer_create(RING_BUFFER_SIZE);
  175. RT_ASSERT(recv_ringbuffer != RT_NULL);
  176. rt_hw_serial_register(&uart_msg_dev->serial, uart_msg_dev->name,
  177. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
  178. uart_msg_dev);
  179. return 0;
  180. }
  181. #ifdef RT_USING_UART0_MSG
  182. static FUartMsg Ft_Uart0_Msg;
  183. static struct drv_usart_msg drv_uart0_msg;
  184. #endif
  185. #ifdef RT_USING_UART1_MSG
  186. static FUartMsg Ft_Uart1_Msg;
  187. static struct drv_usart_msg drv_uart1_msg;
  188. #endif
  189. #ifdef RT_USING_UART2_MSG
  190. static FUartMsg Ft_Uart2_Msg;
  191. static struct drv_usart_msg drv_uart2_msg;
  192. #endif
  193. int rt_hw_uart_init(void)
  194. {
  195. #ifdef RT_USING_UART0_MSG
  196. drv_uart0_msg.name = "uart0";
  197. drv_uart0_msg.handle = &Ft_Uart0_Msg;
  198. drv_uart0_msg.config.uart_instance = FUART0_MSG_ID;
  199. uart_msg_init(&drv_uart0_msg);
  200. #endif
  201. #ifdef RT_USING_UART1_MSG
  202. drv_uart1_msg.name = "uart1";
  203. drv_uart1_msg.handle = &Ft_Uart1_Msg;
  204. drv_uart1_msg.config.uart_instance = FUART1_MSG_ID;
  205. uart_msg_init(&drv_uart1_msg);
  206. #endif
  207. #ifdef RT_USING_UART2_MSG
  208. drv_uart2_msg.name = "uart2";
  209. drv_uart2_msg.handle = &Ft_Uart2_Msg;
  210. drv_uart2_msg.config.uart_instance = FUART2_MSG_ID;
  211. uart_msg_init(&drv_uart2_msg);
  212. #endif
  213. return 0;
  214. }
  215. INIT_BOARD_EXPORT(rt_hw_uart_init);