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
13 #include "rtconfig.h"
14
15 #include <rtdevice.h>
16 #include "board.h"
17 #include <mmu.h>
18 #include "drv_usart_msg.h"
19 #include "interrupt.h"
20 #include "fio_mux.h"
21 #include "fparameters.h"
22
23 #ifdef RT_USING_SMART
24 #include <ioremap.h>
25 #endif
26
27 #define RING_BUFFER_WAIT_TIMEOUT 10000
28 #define RING_BUFFER_SIZE 64
29
30 struct rt_ringbuffer *recv_ringbuffer = NULL;
31
32
rt_ringbuffer_status(struct rt_ringbuffer * rb)33 rt_inline enum rt_ringbuffer_state rt_ringbuffer_status(struct rt_ringbuffer *rb)
34 {
35 if (rb->read_index == rb->write_index)
36 {
37 if (rb->read_mirror == rb->write_mirror)
38 return RT_RINGBUFFER_EMPTY;
39 else
40 return RT_RINGBUFFER_FULL;
41 }
42 return RT_RINGBUFFER_HALFFULL;
43 }
44
45 static void Ft_Os_Uart_Msg_Callback(void *Args, u32 Event, u32 EventData);
46
rt_hw_uart_msg_isr(int irqno,void * param)47 static void rt_hw_uart_msg_isr(int irqno, void *param)
48 {
49 FUartMsgInterruptHandler(irqno, param);
50 }
51
uart_msg_configure(struct rt_serial_device * serial,struct serial_configure * cfg)52 static rt_err_t uart_msg_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
53 {
54 struct drv_usart_msg *uart_msg = RT_NULL;
55 FUartMsg *uart_msg_hw = RT_NULL;
56
57 FUartMsgConfig config;
58
59 RT_ASSERT(serial != RT_NULL);
60 RT_ASSERT(cfg != RT_NULL);
61 uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
62 uart_msg_hw = uart_msg->handle;
63 config = *(const FUartMsgConfig *)FUartMsgLookupConfig(uart_msg->config.uart_instance);
64
65 #ifdef RT_USING_SMART
66 config.msg.regfile = (uintptr)rt_ioremap((void *)config.msg.regfile, 0x1000);
67 config.msg.shmem = (uintptr)rt_ioremap((void *)config.msg.shmem, 0x1000);
68 #endif
69
70
71 FIOPadSetUartMux(uart_msg->config.uart_instance);
72
73 RT_ASSERT(FUartMsgCfgInitialize(uart_msg_hw, &config) == FT_SUCCESS);
74
75 FUartMsgSetStartUp(uart_msg_hw);
76
77 FUartMsgSetHandler(uart_msg_hw, Ft_Os_Uart_Msg_Callback, serial);
78
79
80 //<! 打开接收中断
81
82 rt_hw_interrupt_set_priority(uart_msg_hw->config.irq_num, uart_msg->config.isr_priority);
83 rt_hw_interrupt_install(uart_msg_hw->config.irq_num, rt_hw_uart_msg_isr, uart_msg_hw, "uart");
84 rt_hw_interrupt_umask(uart_msg_hw->config.irq_num);
85 FUartMsgEnableInterrups(uart_msg_hw);
86
87 return RT_EOK;
88 }
89
uart_msg_control(struct rt_serial_device * serial,int cmd,void * arg)90 static rt_err_t uart_msg_control(struct rt_serial_device *serial, int cmd, void *arg)
91 {
92 struct drv_usart_msg *uart_msg = RT_NULL;
93 FUartMsg *uart_msg_ptr = RT_NULL;
94 RT_ASSERT(serial != RT_NULL);
95
96 uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
97 uart_msg_ptr = uart_msg->handle;
98
99 switch (cmd)
100 {
101 case RT_DEVICE_CTRL_CLR_INT:
102 /* disable rx irq */
103 rt_hw_interrupt_mask(uart_msg_ptr->config.irq_num);
104 break;
105
106 case RT_DEVICE_CTRL_SET_INT:
107 /* enable rx irq */
108 rt_hw_interrupt_umask(uart_msg_ptr->config.irq_num);
109 break;
110 }
111
112 return RT_EOK;
113 }
114
uart_msg_putc(struct rt_serial_device * serial,char c)115 static int uart_msg_putc(struct rt_serial_device *serial, char c)
116 {
117 struct drv_usart_msg *uart_msg = RT_NULL;
118 FUartMsg *uart_msg_ptr = RT_NULL;
119 RT_ASSERT(serial != RT_NULL);
120
121 uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
122 uart_msg_ptr = uart_msg->handle;
123
124 while(-1 == FUartMsgTxChar(&(uart_msg_ptr->config.msg), (u8)c))
125 {
126 }
127
128 return 1;
129 }
130
FUartMsgRecvBufferNoBlocking(FUartMsg * uart_p)131 void FUartMsgRecvBufferNoBlocking(FUartMsg *uart_p)
132 {
133 u8 data[16] = {0};
134 rt_size_t write_length = 0;
135 u32 received_count = 0;
136
137 while (!FUartMsgRxRingBufferIsEmpty(uart_p->config.msg.regfile))
138 {
139 received_count += FUartMsgRxChars(&(uart_p->config.msg), data, 16);
140 }
141
142 if(received_count > 0)
143 {
144 write_length = rt_ringbuffer_put(recv_ringbuffer, data, received_count);
145 RT_ASSERT(write_length == received_count);
146 }
147
148 }
149
uart_msg_getc(struct rt_serial_device * serial)150 static int uart_msg_getc(struct rt_serial_device *serial)
151 {
152 int ch;
153 struct drv_usart_msg *uart_msg = RT_NULL;
154 FUartMsg *uart_msg_ptr = RT_NULL;
155 RT_ASSERT(serial != RT_NULL);
156
157 uart_msg = rt_container_of(serial, struct drv_usart_msg, serial);
158 uart_msg_ptr = uart_msg->handle;
159
160
161 if(RT_RINGBUFFER_EMPTY == rt_ringbuffer_status(recv_ringbuffer))
162 {
163 FUartMsgRecvBufferNoBlocking(uart_msg_ptr);
164 }
165
166 if(0 == rt_ringbuffer_getchar(recv_ringbuffer, (rt_uint8_t *)&ch))
167 {
168 return -1;
169 }
170
171 if (ch == 0xffff)
172 {
173 ch = -1;
174 }
175 else
176 {
177 ch &= 0xff;
178 }
179
180 return ch;
181 }
182
Ft_Os_Uart_Msg_Callback(void * Args,u32 Event,u32 EventData)183 static void Ft_Os_Uart_Msg_Callback(void *Args, u32 Event, u32 EventData)
184 {
185
186 struct rt_serial_device *serial = (struct rt_serial_device *)Args;
187 if(FUART_EVENT_RECV_DATA == Event)
188 {
189 if(serial->serial_rx)
190 {
191 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
192 }
193 }
194 else if(FUART_EVENT_SENT_DATA == Event)
195 {
196
197 }
198 else
199 {
200
201 }
202 }
203
204
205 static const struct rt_uart_ops _uart_ops =
206 {
207 uart_msg_configure,
208 uart_msg_control,
209 uart_msg_putc,
210 uart_msg_getc,
211 NULL
212 };
213
uart_msg_init(struct drv_usart_msg * uart_msg_dev)214 static int uart_msg_init(struct drv_usart_msg *uart_msg_dev)
215 {
216 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
217
218 config.bufsz = RT_SERIAL_RB_BUFSZ;
219 uart_msg_dev->serial.ops = &_uart_ops;
220 uart_msg_dev->serial.config = config;
221
222 uart_msg_dev->config.isr_priority = 0xd0;
223 uart_msg_dev->config.isr_event_mask = RTOS_UART_MSG_RX_ISR_MASK | RTOS_UART_MSG_TX_ISR_MASK;
224 uart_msg_dev->config.uart_baudrate = BAUD_RATE_115200;
225
226 recv_ringbuffer = rt_ringbuffer_create(RING_BUFFER_SIZE);
227
228 RT_ASSERT(recv_ringbuffer != RT_NULL);
229
230 rt_hw_serial_register(&uart_msg_dev->serial, uart_msg_dev->name,
231 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
232 uart_msg_dev);
233
234 return 0;
235 }
236
237 #ifdef RT_USING_UART0_MSG
238 static FUartMsg Ft_Uart0_Msg;
239 static struct drv_usart_msg drv_uart0_msg;
240 #endif
241 #ifdef RT_USING_UART1_MSG
242 static FUartMsg Ft_Uart1_Msg;
243 static struct drv_usart_msg drv_uart1_msg;
244 #endif
245 #ifdef RT_USING_UART2_MSG
246 static FUartMsg Ft_Uart2_Msg;
247 static struct drv_usart_msg drv_uart2_msg;
248 #endif
249
rt_hw_uart_init(void)250 int rt_hw_uart_init(void)
251 {
252
253 #ifdef RT_USING_UART0_MSG
254 drv_uart0_msg.name = "uart0";
255 drv_uart0_msg.handle = &Ft_Uart0_Msg;
256 drv_uart0_msg.config.uart_instance = FUART0_MSG_ID;
257 uart_msg_init(&drv_uart0_msg);
258 #endif
259 #ifdef RT_USING_UART1_MSG
260 drv_uart1_msg.name = "uart1";
261 drv_uart1_msg.handle = &Ft_Uart1_Msg;
262 drv_uart1_msg.config.uart_instance = FUART1_MSG_ID;
263 uart_msg_init(&drv_uart1_msg);
264 #endif
265 #ifdef RT_USING_UART2_MSG
266 drv_uart2_msg.name = "uart2";
267 drv_uart2_msg.handle = &Ft_Uart2_Msg;
268 drv_uart2_msg.config.uart_instance = FUART2_MSG_ID;
269 uart_msg_init(&drv_uart2_msg);
270 #endif
271
272 return 0;
273 }
274 INIT_BOARD_EXPORT(rt_hw_uart_init);
275