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 deivce */
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