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 *
9 */
10
11 #include <rtthread.h>
12 #include "utest.h"
13 #include <rtdevice.h>
14 #include <stdlib.h>
15
16
17 #ifdef UTEST_SERIAL_TC
18
19 static struct rt_serial_device *serial;
20
uart_find(void)21 static rt_err_t uart_find(void)
22 {
23 serial = (struct rt_serial_device *)rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
24
25 if (serial == RT_NULL)
26 {
27 LOG_E("find %s device failed!\n", RT_SERIAL_TC_DEVICE_NAME);
28 return -RT_ERROR;
29 }
30
31 return RT_EOK;
32 }
33
test_item(rt_uint8_t * uart_write_buffer,rt_uint32_t send_size)34 static rt_err_t test_item(rt_uint8_t *uart_write_buffer, rt_uint32_t send_size)
35 {
36 rt_uint8_t readBuf[16] = {0};
37 rt_uint32_t readSize = 0;
38 if (send_size >= sizeof(readBuf))
39 {
40 readSize = sizeof(readBuf);
41 }
42 else
43 {
44 readSize = send_size;
45 }
46
47 rt_ssize_t size = rt_device_write(&serial->parent, 0, uart_write_buffer, send_size);
48 if (size != send_size)
49 {
50 LOG_E("size [%4d], send_size [%4d]", size, send_size);
51 return -RT_ERROR;
52 }
53 rt_thread_mdelay(send_size * 0.0868 + 5);
54 if (1 != rt_device_read(&serial->parent, 0, uart_write_buffer, 1))
55 {
56 LOG_E("read failed.");
57 return -RT_ERROR;
58 }
59
60 rt_device_control(&serial->parent, RT_SERIAL_CTRL_RX_FLUSH, RT_NULL);
61 if (0 != rt_device_read(&serial->parent, 0, uart_write_buffer, 1))
62 {
63 LOG_E("read failed.");
64 return -RT_ERROR;
65 }
66
67 /* Resend the data and check for any discrepancies upon reception */
68 if (readSize > 0)
69 {
70 rt_device_write(&serial->parent, 0, uart_write_buffer, readSize);
71 rt_thread_mdelay(readSize * 0.0868 + 5);
72 rt_device_read(&serial->parent, 0, readBuf, readSize);
73
74 for (rt_uint32_t i = 0; i < readSize; i++)
75 {
76 if (readBuf[i] != uart_write_buffer[i])
77 {
78 LOG_E("index: %d, Read Different data -> former data: %x, current data: %x.", i, uart_write_buffer[i], readBuf[i]);
79 return -RT_ERROR;
80 }
81 }
82 }
83
84 LOG_I("flush rx send_size [%4d]", send_size);
85
86 return RT_EOK;
87 }
88
uart_api()89 static rt_bool_t uart_api()
90 {
91 rt_err_t result = RT_EOK;
92
93 result = uart_find();
94 if (result != RT_EOK)
95 {
96 return RT_FALSE;
97 }
98
99 /* Reinitialize */
100 struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
101 config.baud_rate = BAUD_RATE_115200;
102 config.rx_bufsz = RT_SERIAL_TC_RXBUF_SIZE;
103 config.tx_bufsz = RT_SERIAL_TC_TXBUF_SIZE;
104 #ifdef RT_SERIAL_USING_DMA
105 config.dma_ping_bufsz = RT_SERIAL_TC_RXBUF_SIZE / 2;
106 #endif
107 rt_device_control(&serial->parent, RT_DEVICE_CTRL_CONFIG, &config);
108
109 result = rt_device_open(&serial->parent, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
110 if (result != RT_EOK)
111 {
112 LOG_E("Open uart device failed.");
113 return RT_FALSE;
114 }
115
116 rt_uint8_t *uart_write_buffer;
117 rt_uint32_t i;
118 uart_write_buffer = (rt_uint8_t *)rt_malloc(RT_SERIAL_TC_RXBUF_SIZE * 5 + 1);
119 for (rt_uint32_t count = 0; count < (RT_SERIAL_TC_RXBUF_SIZE * 5 + 1); count++)
120 {
121 uart_write_buffer[count] = count;
122 }
123
124 srand(rt_tick_get());
125 for (i = 0; i < RT_SERIAL_TC_SEND_ITERATIONS; i++)
126 {
127 if (RT_EOK != test_item(uart_write_buffer, RT_SERIAL_TC_RXBUF_SIZE + RT_SERIAL_TC_RXBUF_SIZE * (rand() % 5)))
128 {
129 LOG_E("test_item failed.");
130 result = -RT_ERROR;
131 goto __exit;
132 }
133
134 if (RT_EOK != test_item(uart_write_buffer, rand() % (RT_SERIAL_TC_RXBUF_SIZE * 5)))
135 {
136 LOG_E("test_item failed.");
137 result = -RT_ERROR;
138 goto __exit;
139 }
140 }
141
142 __exit:
143 rt_free(uart_write_buffer);
144 rt_device_close(&serial->parent);
145 rt_thread_mdelay(5);
146 return result == RT_EOK ? RT_TRUE : RT_FALSE;
147 }
148
tc_uart_api(void)149 static void tc_uart_api(void)
150 {
151 uassert_true(uart_api() == RT_TRUE);
152 }
153
utest_tc_init(void)154 static rt_err_t utest_tc_init(void)
155 {
156 LOG_I("UART TEST: Please connect Tx and Rx directly for self testing.");
157 return RT_EOK;
158 }
159
utest_tc_cleanup(void)160 static rt_err_t utest_tc_cleanup(void)
161 {
162 rt_device_t uart_dev = rt_device_find(RT_SERIAL_TC_DEVICE_NAME);
163 while (rt_device_close(uart_dev) != -RT_ERROR);
164 return RT_EOK;
165 }
166
testcase(void)167 static void testcase(void)
168 {
169 UTEST_UNIT_RUN(tc_uart_api);
170 }
171
172 UTEST_TC_EXPORT(testcase, "testcases.drivers.uart_flush_rx", utest_tc_init, utest_tc_cleanup, 30);
173
174 #endif /* TC_UART_USING_TC */
175