Skip to content

Commit 816a549

Browse files
committed
[bsp][qemu-vexpress-a9] Adapter driver for serial port v2 ([#10176](https://github.com/hydevcode/rt-thread/issues/10176))
1 parent 55428e4 commit 816a549

File tree

3 files changed

+169
-27
lines changed

3 files changed

+169
-27
lines changed

bsp/qemu-vexpress-a9/.ci/attachconfig/ci.attachconfig.yml

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
# ------ PERIPHERAL CI ------
2+
peripheral.UARTv2:
3+
kconfig:
4+
- CONFIG_RT_USING_SERIAL_V2=y
5+
- CONFIG_BSP_USING_UART1=y
6+
- CONFIG_BSP_USING_UART2=y
7+
- CONFIG_BSP_USING_UART3=y
28
peripheral.EMAC:
39
kconfig:
410
- CONFIG_BSP_DRV_EMAC=y

bsp/qemu-vexpress-a9/drivers/Kconfig

+61-9
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,74 @@ menuconfig BSP_USING_UART
1616
default y
1717
select RT_USING_SERIAL
1818
if BSP_USING_UART
19-
config BSP_USING_UART0
20-
bool "Enable UART0"
21-
select RT_USING_UART0
19+
menuconfig BSP_USING_UART0
20+
bool "Enable UART0 (Debugger)"
2221
default y
23-
config BSP_USING_UART1
22+
if BSP_USING_UART0
23+
config BSP_UART0_RX_BUFSIZE
24+
int "Set UART0 RX buffer size"
25+
range 64 65535
26+
depends on RT_USING_SERIAL_V2
27+
default 10240
28+
29+
config BSP_UART0_TX_BUFSIZE
30+
int "Set UART0 TX buffer size"
31+
range 0 65535
32+
depends on RT_USING_SERIAL_V2
33+
default 0
34+
endif
35+
36+
menuconfig BSP_USING_UART1
2437
bool "Enable UART1"
25-
select RT_USING_UART1
2638
default n
27-
config BSP_USING_UART2
39+
if BSP_USING_UART1
40+
config BSP_UART1_RX_BUFSIZE
41+
int "Set UART1 RX buffer size"
42+
range 64 65535
43+
depends on RT_USING_SERIAL_V2
44+
default 10240
45+
46+
config BSP_UART1_TX_BUFSIZE
47+
int "Set UART1 TX buffer size"
48+
range 0 65535
49+
depends on RT_USING_SERIAL_V2
50+
default 0
51+
endif
52+
53+
menuconfig BSP_USING_UART2
2854
bool "Enable UART2"
29-
select RT_USING_UART2
3055
default n
31-
config BSP_USING_UART3
56+
if BSP_USING_UART2
57+
config BSP_UART2_RX_BUFSIZE
58+
int "Set UART2 RX buffer size"
59+
range 64 65535
60+
depends on RT_USING_SERIAL_V2
61+
default 10240
62+
63+
config BSP_UART2_TX_BUFSIZE
64+
int "Set UART2 TX buffer size"
65+
range 0 65535
66+
depends on RT_USING_SERIAL_V2
67+
default 0
68+
endif
69+
70+
menuconfig BSP_USING_UART3
3271
bool "Enable UART3"
33-
select RT_USING_UART3
3472
default n
73+
if BSP_USING_UART3
74+
config BSP_UART3_RX_BUFSIZE
75+
int "Set UART3 RX buffer size"
76+
range 64 65535
77+
depends on RT_USING_SERIAL_V2
78+
default 10240
79+
80+
config BSP_UART3_TX_BUFSIZE
81+
int "Set UART3 TX buffer size"
82+
range 0 65535
83+
depends on RT_USING_SERIAL_V2
84+
default 0
85+
endif
86+
3587
endif
3688

3789
config BSP_USING_LVGL

bsp/qemu-vexpress-a9/drivers/drv_uart_v2.c

+102-18
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,34 @@ struct hw_uart_device
3636
#define UART_CR(base) __REG32(base + 0x30)
3737
#define UART_IMSC(base) __REG32(base + 0x38)
3838
#define UART_ICR(base) __REG32(base + 0x44)
39+
#define UART_LCR_H(base) __REG32(base + 0x2C)
40+
#define UART_DMACR(base) __REG32(base + 0x48)
41+
#define UART_IFLS(base) __REG32(base + 0x34)
42+
43+
/* test */
44+
#define UART_TCR(base) __REG32(base + 0x80)
45+
#define UART_ITOP(base) __REG32(base + 0x88)
46+
47+
#define UARTITOP_RXINTR 0x400
48+
49+
/* fifo */
50+
#define UARTLCR_H_FEN 0x10
3951

4052
#define UARTFR_RXFE 0x10
4153
#define UARTFR_TXFF 0x20
42-
#define UARTIMSC_RXIM 0x10
43-
#define UARTIMSC_TXIM 0x20
54+
#define UARTFR_RXFF 0x40
55+
#define UARTFR_TXFE 0x80
56+
#define UARTFR_BUSY 0x08
57+
58+
4459
#define UARTICR_RXIC 0x10
4560
#define UARTICR_TXIC 0x20
4661

62+
63+
#define UARTIMSC_RXIM 0x10
64+
#define UARTIMSC_RTIM 0x40
65+
#define UARTIMSC_TXIM 0x20
66+
4767
#if defined(BSP_USING_UART0)
4868
struct rt_serial_device serial0;
4969
#endif
@@ -105,17 +125,29 @@ static struct hw_uart_device _uart_device[] = {
105125
*
106126
* @param serial Serial device
107127
*/
128+
108129
static void rt_hw_uart_isr(int irqno, void *param)
109130
{
110131
struct rt_serial_device *serial = (struct rt_serial_device *)param;
111-
struct hw_uart_device *uart;
112132
RT_ASSERT(serial != RT_NULL);
133+
struct hw_uart_device *uart;
113134
uart = (struct hw_uart_device *)serial->parent.user_data;
114-
struct rt_serial_rx_fifo *rx_fifo;
115-
rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
116-
RT_ASSERT(rx_fifo != RT_NULL);
117-
rt_ringbuffer_putchar(&(rx_fifo->rb), UART_DR(uart->hw_base));
118-
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
135+
RT_ASSERT(uart != RT_NULL);
136+
137+
if(!(UART_FR(uart->hw_base) & UARTFR_RXFE) && (UART_IMSC(uart->hw_base) & UARTIMSC_RXIM))
138+
{
139+
struct rt_serial_rx_fifo *rx_fifo;
140+
rx_fifo = (struct rt_serial_rx_fifo *) serial->serial_rx;
141+
RT_ASSERT(rx_fifo != RT_NULL);
142+
char rec_ch=UART_DR(uart->hw_base)& 0xff;
143+
rt_ringbuffer_putchar(&(rx_fifo->rb), rec_ch);
144+
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
145+
}
146+
else if((UART_IMSC(uart->hw_base) & UARTIMSC_TXIM))
147+
{
148+
UART_ICR(uart->hw_base)|= UARTICR_TXIC;
149+
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
150+
}
119151
}
120152

121153
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
@@ -194,7 +226,6 @@ static int uart_putc(struct rt_serial_device *serial, char ch)
194226
RT_ASSERT(serial != RT_NULL);
195227

196228
uart = (struct hw_uart_device *)serial->parent.user_data;
197-
198229
while (UART_FR(uart->hw_base) & UARTFR_TXFF);
199230
UART_DR(uart->hw_base) = ch;
200231

@@ -207,6 +238,7 @@ static int uart_getc(struct rt_serial_device *serial)
207238
struct hw_uart_device *uart;
208239

209240
RT_ASSERT(serial != RT_NULL);
241+
210242
uart = (struct hw_uart_device *)serial->parent.user_data;
211243

212244
ch = -1;
@@ -218,18 +250,37 @@ static int uart_getc(struct rt_serial_device *serial)
218250
return ch;
219251
}
220252
static rt_ssize_t uart_transmit(struct rt_serial_device *serial,
221-
rt_uint8_t *buf,
222-
rt_size_t size,
223-
rt_uint32_t tx_flag)
253+
rt_uint8_t *buf,
254+
rt_size_t size,
255+
rt_uint32_t tx_flag)
224256
{
225257
RT_ASSERT(serial != RT_NULL);
226258
RT_ASSERT(buf != RT_NULL);
227-
228259
RT_ASSERT(size);
260+
uint32_t fifo_size = 0, tx_size = 0;
261+
struct hw_uart_device *uart = (struct hw_uart_device *)serial->parent.user_data;
262+
struct rt_serial_tx_fifo *tx_fifo;
263+
tx_fifo = (struct rt_serial_tx_fifo *) serial->serial_tx;
264+
uint8_t ch = 0;
265+
RT_ASSERT(tx_fifo != RT_NULL);
266+
267+
if (size > 0)
268+
{
269+
if (UART_IMSC(uart->hw_base) & UARTIMSC_TXIM)
270+
{
271+
UART_IMSC(uart->hw_base) &= ~UARTIMSC_TXIM;
272+
if(rt_ringbuffer_getchar(&tx_fifo->rb, &ch))
273+
{
274+
while (UART_FR(uart->hw_base) & UARTFR_TXFF);
275+
UART_DR(uart->hw_base) = ch;
276+
}
277+
UART_IMSC(uart->hw_base) |= UARTIMSC_TXIM;
278+
}
279+
}
229280

230-
uart_control(serial, RT_DEVICE_CTRL_SET_INT, (void *)tx_flag);
231281
return size;
232282
}
283+
233284
static const struct rt_uart_ops _uart_ops = {
234285
.configure = uart_configure,
235286
.control = uart_control,
@@ -238,12 +289,43 @@ static const struct rt_uart_ops _uart_ops = {
238289
.transmit = uart_transmit
239290
};
240291

292+
static int uart_config(void)
293+
{
294+
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
295+
296+
#ifdef BSP_USING_UART0
297+
_uart_device[0].serial->config = config;
298+
_uart_device[0].serial->config.rx_bufsz = BSP_UART0_RX_BUFSIZE;
299+
_uart_device[0].serial->config.tx_bufsz = BSP_UART0_TX_BUFSIZE;
300+
#endif /* BSP_USING_UART0 */
301+
302+
#ifdef BSP_USING_UART1
303+
_uart_device[1].serial->config = config;
304+
_uart_device[1].serial->config.rx_bufsz = BSP_UART1_RX_BUFSIZE;
305+
_uart_device[1].serial->config.tx_bufsz = BSP_UART1_TX_BUFSIZE;
306+
#endif /* BSP_USING_UART1 */
307+
308+
#ifdef BSP_USING_UART2
309+
_uart_device[2].serial->config = config;
310+
_uart_device[2].serial->config.rx_bufsz = BSP_UART2_RX_BUFSIZE;
311+
_uart_device[2].serial->config.tx_bufsz = BSP_UART2_TX_BUFSIZE;
312+
#endif /* BSP_USING_UART2 */
313+
314+
#ifdef BSP_USING_UART3
315+
_uart_device[3].serial->config = config;
316+
_uart_device[3].serial->config.rx_bufsz = BSP_UART3_RX_BUFSIZE;
317+
_uart_device[3].serial->config.tx_bufsz = BSP_UART3_TX_BUFSIZE;
318+
#endif /* BSP_USING_UART3 */
319+
320+
return RT_EOK;
321+
}
322+
241323
int rt_hw_uart_init(void)
242324
{
243325

244326
rt_err_t err = RT_EOK;
245327

246-
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
328+
uart_config();
247329

248330
for (uint32_t i = 0; i < sizeof(_uart_device) / sizeof(_uart_device[0]); i++)
249331
{
@@ -253,9 +335,6 @@ int rt_hw_uart_init(void)
253335
#endif
254336

255337
_uart_device[i].serial->ops = &_uart_ops;
256-
_uart_device[i].serial->config = config;
257-
_uart_device[i].serial->config.rx_bufsz = 64;
258-
_uart_device[i].serial->config.tx_bufsz = 0;
259338
/* register UART device */
260339
err = rt_hw_serial_register(_uart_device[i].serial,
261340
_uart_device[i].device_name,
@@ -264,6 +343,11 @@ int rt_hw_uart_init(void)
264343
rt_hw_interrupt_install(_uart_device[i].irqno, rt_hw_uart_isr, _uart_device[i].serial, _uart_device[i].device_name);
265344
/* enable Rx and Tx of UART */
266345
UART_CR(_uart_device[i].hw_base) = (1 << 0) | (1 << 8) | (1 << 9);
346+
347+
/* Fifo */
348+
UART_LCR_H(_uart_device[i].hw_base) =(1 << 4);
349+
/* UART_IFLS(_uart_device[i].hw_base) = (0 <<3 ) | (0 <<4 )| (1 <<5 ); */
350+
/* UART_DMACR(_uart_device[i].hw_base) = (1<<0); */
267351
}
268352

269353
return err;

0 commit comments

Comments
 (0)