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
+ */
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
+
111
+ static rt_err_t uart_configure (struct rt_serial_device * serial , struct serial_configure * cfg )
112
+ {
113
+ return RT_EOK ;
114
+ }
115
+
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
+
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
+
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
+
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 */
0 commit comments