1 /*
2  * Copyright (c) 2006-2024 RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2024-11-20     zhujiale     the first version
9  */
10 #include <rtthread.h>
11 #include <rtdevice.h>
12 #include "utest.h"
13 
14 static struct rt_serial_device* _serial0;
15 static int cnt = 0;
16 
17 #define __REG32(x) (*((volatile unsigned int*)((rt_ubase_t)x)))
18 #define UART_FR(base)   __REG32(base + 0x18)
19 #define UART_DR(base)   __REG32(base + 0x00)
20 #define UARTFR_TXFF     0x20
21 
22 struct hw_uart_device
23 {
24     rt_size_t hw_base;
25     rt_size_t irqno;
26 };
27 
uart_putc(struct rt_serial_device * serial,char c)28 static int uart_putc(struct rt_serial_device* serial, char c)
29 {
30     struct hw_uart_device* uart;
31 
32     RT_ASSERT(serial != RT_NULL);
33     uart = (struct hw_uart_device*)serial->parent.user_data;
34 
35     while (UART_FR(uart->hw_base) & UARTFR_TXFF);
36     UART_DR(uart->hw_base) = c;
37 
38     return 1;
39 }
40 
utest_lower_run_test2(struct rt_serial_device * serial,char ch,void * data)41 static rt_err_t utest_lower_run_test2(struct rt_serial_device* serial, char ch, void* data)
42 {
43     static rt_uint8_t num = 0;
44     num++;
45     uassert_true(ch == ('a' + num));
46     return RT_EOK;
47 }
48 
utest_getc_2(struct rt_serial_device * serial)49 static int utest_getc_2(struct rt_serial_device* serial)
50 {
51     static rt_uint8_t num = 0;
52     if (num == 20)
53         return -1;
54     num++;
55     return 'a' + num;
56 }
57 
58 static const struct rt_uart_ops _utest_ops2 =
59 {
60     RT_NULL,
61     RT_NULL,
62     uart_putc,
63     utest_getc_2,
64 };
65 
utest_lower_run(struct rt_serial_device * serial,char ch,void * data)66 static rt_err_t utest_lower_run(struct rt_serial_device* serial, char ch, void* data)
67 {
68     uassert_true(ch == 'a');
69     cnt++;
70     return RT_EOK;
71 }
72 
73 
utest_getc(struct rt_serial_device * serial)74 static int utest_getc(struct rt_serial_device* serial)
75 {
76     static rt_uint8_t num = 0;
77     if (num == 10)
78         return -1;
79     num++;
80     return 'a';
81 }
82 
83 static const struct rt_uart_ops _utest_ops =
84 {
85     RT_NULL,
86     RT_NULL,
87     uart_putc,
88     utest_getc,
89 };
bypass_lower_001(void)90 static void bypass_lower_001(void)
91 {
92     const struct rt_uart_ops* tmp = _serial0->ops;
93     _serial0->ops = &_utest_ops;
94     rt_bypass_lower_register(_serial0, "utest", RT_BYPASS_MAX_LEVEL, utest_lower_run, RT_NULL);
95 
96     rt_hw_serial_isr(_serial0, RT_SERIAL_EVENT_RX_IND);
97     rt_thread_mdelay(100);
98     uassert_true(cnt == 10);
99     _serial0->ops = tmp;
100     rt_bypass_lower_unregister(_serial0, RT_BYPASS_MAX_LEVEL);
101 }
102 
bypass_lower_002(void)103 static void bypass_lower_002(void)
104 {
105     const struct rt_uart_ops* tmp = _serial0->ops;
106     _serial0->ops = &_utest_ops2;
107     rt_bypass_lower_register(_serial0, "utest", RT_BYPASS_MAX_LEVEL, utest_lower_run_test2, RT_NULL);
108 
109     rt_hw_serial_isr(_serial0, RT_SERIAL_EVENT_RX_IND);
110     rt_thread_mdelay(100);
111     uassert_true(cnt == 10);
112     _serial0->ops = tmp;
113     rt_bypass_lower_unregister(_serial0, RT_BYPASS_MAX_LEVEL);
114 }
115 
utest_tc_init(void)116 static rt_err_t utest_tc_init(void)
117 {
118     _serial0 = (struct rt_serial_device*)rt_console_get_device();
119     return RT_EOK;
120 }
121 
utest_tc_cleanup(void)122 static rt_err_t utest_tc_cleanup(void)
123 {
124     return RT_EOK;
125 }
126 
_testcase(void)127 static void _testcase(void)
128 {
129     UTEST_UNIT_RUN(bypass_lower_001);
130     UTEST_UNIT_RUN(bypass_lower_002);
131 }
132 
133 UTEST_TC_EXPORT(_testcase, "testcase.bypass.lower.001", utest_tc_init, utest_tc_cleanup, 10);
134