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 * 2013-03-30 Bernard the first version
9 * 2025-04-08 Hydevcode second version
10 *
11 */
12 #include <rtthread.h>
13 #include <rtdevice.h>
14 #include <rtdbg.h>
15
16 #include "drv_uart.h"
17 #include "board.h"
18 #include "mmu.h"
19
20
21 #ifdef RT_USING_SERIAL_V1
22
23 struct hw_uart_device
24 {
25 rt_uint32_t hw_base;
26 rt_uint32_t irqno;
27 struct rt_serial_device *serial;
28 char *device_name;
29 };
30
31 #define UART_DR(base) __REG32(base + 0x00)
32 #define UART_FR(base) __REG32(base + 0x18)
33 #define UART_CR(base) __REG32(base + 0x30)
34 #define UART_IMSC(base) __REG32(base + 0x38)
35 #define UART_ICR(base) __REG32(base + 0x44)
36
37 #define UARTFR_RXFE 0x10
38 #define UARTFR_TXFF 0x20
39 #define UARTIMSC_RXIM 0x10
40 #define UARTIMSC_TXIM 0x20
41 #define UARTICR_RXIC 0x10
42 #define UARTICR_TXIC 0x20
43
44 #if defined(BSP_USING_UART0)
45 struct rt_serial_device serial0;
46 #endif
47
48 #if defined(BSP_USING_UART1)
49 struct rt_serial_device serial1;
50 #endif
51
52 #if defined(BSP_USING_UART2)
53 struct rt_serial_device serial2;
54 #endif
55
56
57 #if defined(BSP_USING_UART3)
58 struct rt_serial_device serial3;
59 #endif
60
61 static struct hw_uart_device _uart_device[] = {
62 #if defined(BSP_USING_UART0)
63 {
64 REALVIEW_UART0_BASE,
65 IRQ_PBA8_UART0,
66 &serial0,
67 "uart0",
68 },
69 #endif
70
71 #if defined(BSP_USING_UART1)
72 {
73 REALVIEW_UART1_BASE,
74 IRQ_PBA8_UART1,
75 &serial1,
76 "uart1",
77 },
78 #endif
79
80 #if defined(BSP_USING_UART2)
81 {
82 REALVIEW_UART2_BASE,
83 IRQ_PBA8_UART2,
84 &serial2,
85 "uart2",
86 },
87 #endif
88
89 #if defined(BSP_USING_UART3)
90 {
91 REALVIEW_UART3_BASE,
92 IRQ_PBA8_UART3,
93 &serial3,
94 "uart3",
95 },
96 #endif
97
98 };
99
100 /**
101 * @brief UART common interrupt process. This
102 *
103 * @param serial Serial device
104 */
rt_hw_uart_isr(int irqno,void * param)105 static void rt_hw_uart_isr(int irqno, void *param)
106 {
107 struct rt_serial_device *serial = (struct rt_serial_device *)param;
108 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
109 }
110
uart_configure(struct rt_serial_device * serial,struct serial_configure * cfg)111 static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
112 {
113 return RT_EOK;
114 }
115
uart_control(struct rt_serial_device * serial,int cmd,void * arg)116 static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
117 {
118 struct hw_uart_device *uart;
119
120 RT_ASSERT(serial != RT_NULL);
121
122 uart = (struct hw_uart_device *)serial->parent.user_data;
123
124 switch (cmd)
125 {
126 case RT_DEVICE_CTRL_CLR_INT:
127 /* disable rx irq */
128 UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM;
129 break;
130
131 case RT_DEVICE_CTRL_SET_INT:
132 /* enable rx irq */
133 UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM;
134 rt_hw_interrupt_umask(uart->irqno);
135 break;
136 }
137
138 return RT_EOK;
139 }
140
uart_putc(struct rt_serial_device * serial,char ch)141 static int uart_putc(struct rt_serial_device *serial, char ch)
142 {
143 struct hw_uart_device *uart;
144
145 RT_ASSERT(serial != RT_NULL);
146 uart = (struct hw_uart_device *)serial->parent.user_data;
147
148 while (UART_FR(uart->hw_base) & UARTFR_TXFF);
149 UART_DR(uart->hw_base) = ch;
150
151 return 1;
152 }
153
uart_getc(struct rt_serial_device * serial)154 static int uart_getc(struct rt_serial_device *serial)
155 {
156 int ch;
157 struct hw_uart_device *uart;
158
159 RT_ASSERT(serial != RT_NULL);
160 uart = (struct hw_uart_device *)serial->parent.user_data;
161
162 ch = -1;
163 if (!(UART_FR(uart->hw_base) & UARTFR_RXFE))
164 {
165 ch = UART_DR(uart->hw_base) & 0xff;
166 }
167
168 return ch;
169 }
170
171 static const struct rt_uart_ops _uart_ops = {
172 uart_configure,
173 uart_control,
174 uart_putc,
175 uart_getc,
176 };
177
rt_hw_uart_init(void)178 int rt_hw_uart_init(void)
179 {
180
181 rt_err_t err = RT_EOK;
182
183 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
184
185 for (uint32_t i = 0; i < sizeof(_uart_device) / sizeof(_uart_device[0]); i++)
186 {
187
188 #ifdef RT_USING_SMART
189 _uart_device[i].hw_base = (uint32_t)rt_ioremap((void*)_uart_device[i].hw_base, 0x1000);
190 #endif
191
192 _uart_device[i].serial->ops = &_uart_ops;
193 _uart_device[i].serial->config = config;
194
195 /* register UART device */
196 err = rt_hw_serial_register(_uart_device[i].serial,
197 _uart_device[i].device_name,
198 RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
199 (void*)&_uart_device[i]);
200 rt_hw_interrupt_install(_uart_device[i].irqno, rt_hw_uart_isr, _uart_device[i].serial, _uart_device[i].device_name);
201 /* enable Rx and Tx of UART */
202 UART_CR(_uart_device[i].hw_base) = (1 << 0) | (1 << 8) | (1 << 9);
203 }
204
205 return err;
206 }
207
208 INIT_BOARD_EXPORT(rt_hw_uart_init);
209
210 #endif /* RT_USING_SERIAL */