1 /*
2 * Copyright (c) 2006-2025 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2025-04-08 Hydevcode the first version
9 */
10 #include <rtthread.h>
11 #include <rtdevice.h>
12 #include <rtdbg.h>
13 #include "board.h"
14 #include "drv_uart_v2.h"
15 #include "mmu.h"
16
17 #ifdef RT_USING_SERIAL_V2
18
19 #include <rtdbg.h>
20
21 #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3)
22 #error "Please define at least one BSP_USING_UARTx"
23 /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
24 #endif
25
26 struct hw_uart_device
27 {
28 rt_uint32_t hw_base;
29 rt_uint32_t irqno;
30 struct rt_serial_device *serial;
31 char *device_name;
32 };
33
34 #define UART_DR(base) __REG32(base + 0x00)
35 #define UART_FR(base) __REG32(base + 0x18)
36 #define UART_CR(base) __REG32(base + 0x30)
37 #define UART_IMSC(base) __REG32(base + 0x38)
38 #define UART_ICR(base) __REG32(base + 0x44)
39 #define UART_IFLS(base) __REG32(base + 0x34)
40 #define UART_TCR(base) __REG32(base + 0x80)
41 #define UART_ITOP(base) __REG32(base + 0x88)
42
43 #define UART_LCR_H(base) __REG32(base + 0x2C)
44 #define UART_DMACR(base) __REG32(base + 0x48)
45
46 #define UARTITOP_RXINTR 0x400
47
48 #define UARTLCR_H_FEN 0x10
49
50 #define UARTFR_RXFE 0x10
51 #define UARTFR_TXFF 0x20
52 #define UARTFR_RXFF 0x40
53 #define UARTFR_TXFE 0x80
54 #define UARTFR_BUSY 0x08
55
56 #define UARTICR_RXIC 0x10
57 #define UARTICR_TXIC 0x20
58
59 #define UARTIMSC_RXIM 0x10
60 #define UARTIMSC_RTIM 0x40
61 #define UARTIMSC_TXIM 0x20
62
63 #if defined(BSP_USING_UART0)
64 struct rt_serial_device serial0;
65 #endif
66
67 #if defined(BSP_USING_UART1)
68 struct rt_serial_device serial1;
69 #endif
70
71 #if defined(BSP_USING_UART2)
72 struct rt_serial_device serial2;
73 #endif
74
75
76 #if defined(BSP_USING_UART3)
77 struct rt_serial_device serial3;
78 #endif
79
80 static struct hw_uart_device _uart_device[] = {
81 #if defined(BSP_USING_UART0)
82 {
83 REALVIEW_UART0_BASE,
84 IRQ_PBA8_UART0,
85 &serial0,
86 "uart0",
87 },
88 #endif
89
90 #if defined(BSP_USING_UART1)
91 {
92 REALVIEW_UART1_BASE,
93 IRQ_PBA8_UART1,
94 &serial1,
95 "uart1",
96 },
97 #endif
98
99 #if defined(BSP_USING_UART2)
100 {
101 REALVIEW_UART2_BASE,
102 IRQ_PBA8_UART2,
103 &serial2,
104 "uart2",
105 },
106 #endif
107
108 #if defined(BSP_USING_UART3)
109 {
110 REALVIEW_UART3_BASE,
111 IRQ_PBA8_UART3,
112 &serial3,
113 "uart3",
114 },
115 #endif
116
117 };
118
119 /**
120 * @brief UART common interrupt process. This
121 *
122 * @param serial Serial device
123 */
124
rt_hw_uart_isr(int irqno,void * param)125 static void rt_hw_uart_isr(int irqno, void *param)
126 {
127 struct rt_serial_device *serial = (struct rt_serial_device *)param;
128
129 RT_ASSERT(serial != RT_NULL);
130
131 struct hw_uart_device *uart;
132
133 uart = (struct hw_uart_device *)serial->parent.user_data;
134
135 RT_ASSERT(uart != RT_NULL);
136
137 if((UART_FR(uart->hw_base) & UARTFR_RXFF) && (UART_IMSC(uart->hw_base) & UARTIMSC_RXIM))
138 {
139
140 struct rt_serial_rx_fifo *rx_fifo;
141
142 rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
143
144 RT_ASSERT(rx_fifo != RT_NULL);
145
146 char rec_ch;
147 while (!(UART_FR(uart->hw_base) & UARTFR_RXFE))
148 {
149 rec_ch = UART_DR(uart->hw_base) & 0xff;
150 rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &rec_ch);
151
152 }
153 rt_hw_serial_isr(serial,RT_SERIAL_EVENT_RX_IND);
154
155 }
156 else if(UART_IMSC(uart->hw_base) & UARTIMSC_RTIM)
157 {
158 struct rt_serial_rx_fifo *rx_fifo;
159
160 rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
161
162 RT_ASSERT(rx_fifo != RT_NULL);
163
164 char rec_ch;
165
166 while (!(UART_FR(uart->hw_base) & UARTFR_RXFE))
167 {
168 rec_ch = UART_DR(uart->hw_base) & 0xff;
169 rt_hw_serial_control_isr(serial, RT_HW_SERIAL_CTRL_PUTC, &rec_ch);
170
171 }
172 rt_hw_serial_isr(serial,RT_SERIAL_EVENT_RX_IND);
173 }
174 else if((UART_IMSC(uart->hw_base) & UARTIMSC_TXIM))
175 {
176 UART_ICR(uart->hw_base) |= UARTICR_TXIC;
177
178 rt_hw_serial_isr(serial,RT_SERIAL_EVENT_TX_DONE);
179 }
180 }
181
uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)182 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
183 {
184 return RT_EOK;
185 }
186
uart_control(struct rt_serial_device * serial,int cmd,void * arg)187 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
188 {
189 struct hw_uart_device *uart;
190
191 RT_ASSERT(serial != RT_NULL);
192
193 uart = (struct hw_uart_device *)serial->parent.user_data;
194
195 rt_ubase_t ctrl_arg = (rt_ubase_t) arg;
196
197 if(ctrl_arg & (RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_RX_NON_BLOCKING))
198 {
199 ctrl_arg = RT_DEVICE_FLAG_INT_RX;
200 }
201 else if(ctrl_arg & (RT_DEVICE_FLAG_TX_BLOCKING | RT_DEVICE_FLAG_TX_NON_BLOCKING))
202 {
203 ctrl_arg = RT_DEVICE_FLAG_INT_TX;
204 }
205
206 switch (cmd)
207 {
208 case RT_DEVICE_CTRL_CLR_INT:
209 if (ctrl_arg == RT_DEVICE_FLAG_INT_RX)
210 {
211 /* disable rx irq */
212 UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM;
213 UART_IMSC(uart->hw_base) &= ~UARTIMSC_RTIM;
214 }
215 else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX)
216 {
217 /* disable tx irq */
218 UART_IMSC(uart->hw_base) &= ~UARTIMSC_TXIM;
219 }
220 break;
221
222 case RT_DEVICE_CTRL_SET_INT:
223 if (ctrl_arg == RT_DEVICE_FLAG_INT_RX)
224 {
225 /* enable rx irq */
226 UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM;
227 UART_IMSC(uart->hw_base) |= UARTIMSC_RTIM;
228 rt_hw_interrupt_umask(uart->irqno);
229
230 } else if (ctrl_arg == RT_DEVICE_FLAG_INT_TX)
231 {
232 /* enable tx irq */
233 UART_IMSC(uart->hw_base) |= UARTIMSC_TXIM;
234 rt_hw_interrupt_umask(uart->irqno);
235 }
236
237 break;
238 case RT_DEVICE_CTRL_CONFIG:
239 uart_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)ctrl_arg);
240 break;
241 }
242 return RT_EOK;
243 }
244
uart_putc(struct rt_serial_device * serial,char ch)245 static int uart_putc(struct rt_serial_device *serial, char ch)
246 {
247 struct hw_uart_device *uart;
248
249 RT_ASSERT(serial != RT_NULL);
250
251 uart = (struct hw_uart_device *)serial->parent.user_data;
252 while (UART_FR(uart->hw_base) & UARTFR_TXFF);
253 UART_DR(uart->hw_base) = ch;
254
255 return 1;
256 }
257
uart_getc(struct rt_serial_device * serial)258 static int uart_getc(struct rt_serial_device *serial)
259 {
260 int ch;
261 struct hw_uart_device *uart;
262
263 RT_ASSERT(serial != RT_NULL);
264
265 uart = (struct hw_uart_device *)serial->parent.user_data;
266
267 ch = -1;
268 if (!(UART_FR(uart->hw_base) & UARTFR_RXFE))
269 {
270 ch = UART_DR(uart->hw_base) & 0xff;
271 }
272
273 return ch;
274 }
uart_transmit(struct rt_serial_device * serial,rt_uint8_t * buf,rt_size_t size,rt_uint32_t tx_flag)275 static rt_ssize_t uart_transmit(struct rt_serial_device *serial,
276 rt_uint8_t *buf,
277 rt_size_t size,
278 rt_uint32_t tx_flag)
279 {
280 RT_ASSERT(serial != RT_NULL);
281 RT_ASSERT(buf != RT_NULL);
282 RT_ASSERT(size);
283 struct hw_uart_device *uart = (struct hw_uart_device *)serial->parent.user_data;
284 struct rt_serial_tx_fifo *tx_fifo;
285 tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx;
286 uint8_t ch = 0;
287 RT_ASSERT(tx_fifo != RT_NULL);
288
289 if (size > 0)
290 {
291 if (UART_IMSC(uart->hw_base) & UARTIMSC_TXIM)
292 {
293 UART_IMSC(uart->hw_base) &= ~UARTIMSC_TXIM;
294 if(rt_ringbuffer_getchar(&tx_fifo->rb, &ch))
295 {
296 while (UART_FR(uart->hw_base) & UARTFR_TXFF);
297 UART_DR(uart->hw_base) = ch;
298 }
299 UART_IMSC(uart->hw_base) |= UARTIMSC_TXIM;
300 }
301 }
302
303 return size;
304 }
305
306 static const struct rt_uart_ops _uart_ops = {
307 .configure = uart_configure,
308 .control = uart_control,
309 .putc = uart_putc,
310 .getc = uart_getc,
311 .transmit = uart_transmit
312 };
313
uart_config(void)314 static int uart_config(void)
315 {
316 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
317
318 #ifdef BSP_USING_UART0
319 _uart_device[0].serial->config = config;
320 _uart_device[0].serial->config.rx_bufsz = BSP_UART0_RX_BUFSIZE;
321 _uart_device[0].serial->config.tx_bufsz = BSP_UART0_TX_BUFSIZE;
322 #endif /* BSP_USING_UART0 */
323
324 #ifdef BSP_USING_UART1
325 _uart_device[1].serial->config = config;
326 _uart_device[1].serial->config.rx_bufsz = BSP_UART1_RX_BUFSIZE;
327 _uart_device[1].serial->config.tx_bufsz = BSP_UART1_TX_BUFSIZE;
328 #endif /* BSP_USING_UART1 */
329
330 #ifdef BSP_USING_UART2
331 _uart_device[2].serial->config = config;
332 _uart_device[2].serial->config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
333 _uart_device[2].serial->config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
334 #endif /* BSP_USING_UART2 */
335
336 #ifdef BSP_USING_UART3
337 _uart_device[3].serial->config = config;
338 _uart_device[3].serial->config.rx_bufsz = BSP_UART3_RX_BUFSIZE;
339 _uart_device[3].serial->config.tx_bufsz = BSP_UART3_TX_BUFSIZE;
340 #endif /* BSP_USING_UART3 */
341
342 return RT_EOK;
343 }
344
rt_hw_uart_init(void)345 int rt_hw_uart_init(void)
346 {
347
348 rt_err_t err = RT_EOK;
349
350 uart_config();
351
352 for (uint32_t i = 0; i < sizeof(_uart_device) / sizeof(_uart_device[0]); i++)
353 {
354
355 #ifdef RT_USING_SMART
356 _uart_device[i].hw_base = (uint32_t)rt_ioremap((void*)_uart_device[i].hw_base, 0x1000);
357 #endif
358
359 _uart_device[i].serial->ops = &_uart_ops;
360 /* register UART device */
361 err = rt_hw_serial_register(_uart_device[i].serial,
362 _uart_device[i].device_name,
363 RT_DEVICE_FLAG_RDWR,
364 (void*)&_uart_device[i]);
365 rt_hw_interrupt_install(_uart_device[i].irqno, rt_hw_uart_isr, _uart_device[i].serial, _uart_device[i].device_name);
366 /* enable Rx and Tx of UART */
367 UART_CR(_uart_device[i].hw_base) = (1 << 0) | (1 << 8) | (1 << 9);
368
369 UART_LCR_H(_uart_device[i].hw_base) =(1 << 4);
370
371 UART_IFLS(_uart_device[i].hw_base) =0;
372 UART_IFLS(_uart_device[i].hw_base) =(1 << 3);
373
374 }
375
376 return err;
377 }
378 INIT_BOARD_EXPORT(rt_hw_uart_init);
379 #endif /* RT_USING_SERIAL_V2 */