1 /*
2 * QTest testcase for STML4X5_USART
3 *
4 * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5 * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
9 */
10
11 #include "qemu/osdep.h"
12 #include "libqtest.h"
13 #include "hw/misc/stm32l4x5_rcc_internals.h"
14 #include "hw/registerfields.h"
15
16 #define RCC_BASE_ADDR 0x40021000
17 /* Use USART 1 ADDR, assume the others work the same */
18 #define USART1_BASE_ADDR 0x40013800
19
20 /* See stm32l4x5_usart for definitions */
21 REG32(CR1, 0x00)
22 FIELD(CR1, M1, 28, 1)
23 FIELD(CR1, OVER8, 15, 1)
24 FIELD(CR1, M0, 12, 1)
25 FIELD(CR1, PCE, 10, 1)
26 FIELD(CR1, TXEIE, 7, 1)
27 FIELD(CR1, RXNEIE, 5, 1)
28 FIELD(CR1, TE, 3, 1)
29 FIELD(CR1, RE, 2, 1)
30 FIELD(CR1, UE, 0, 1)
31 REG32(CR2, 0x04)
32 REG32(CR3, 0x08)
33 FIELD(CR3, OVRDIS, 12, 1)
34 REG32(BRR, 0x0C)
35 REG32(GTPR, 0x10)
36 REG32(RTOR, 0x14)
37 REG32(RQR, 0x18)
38 REG32(ISR, 0x1C)
39 FIELD(ISR, REACK, 22, 1)
40 FIELD(ISR, TEACK, 21, 1)
41 FIELD(ISR, TXE, 7, 1)
42 FIELD(ISR, RXNE, 5, 1)
43 FIELD(ISR, ORE, 3, 1)
44 REG32(ICR, 0x20)
45 REG32(RDR, 0x24)
46 REG32(TDR, 0x28)
47
48 #define NVIC_ISPR1 0XE000E204
49 #define NVIC_ICPR1 0xE000E284
50 #define USART1_IRQ 37
51
check_nvic_pending(QTestState * qts,unsigned int n)52 static bool check_nvic_pending(QTestState *qts, unsigned int n)
53 {
54 /* No USART interrupts are less than 32 */
55 assert(n > 32);
56 n -= 32;
57 return qtest_readl(qts, NVIC_ISPR1) & (1 << n);
58 }
59
clear_nvic_pending(QTestState * qts,unsigned int n)60 static bool clear_nvic_pending(QTestState *qts, unsigned int n)
61 {
62 /* No USART interrupts are less than 32 */
63 assert(n > 32);
64 n -= 32;
65 qtest_writel(qts, NVIC_ICPR1, (1 << n));
66 return true;
67 }
68
69 /*
70 * Wait indefinitely for the flag to be updated.
71 * If this is run on a slow CI runner,
72 * the meson harness will timeout after 10 minutes for us.
73 */
usart_wait_for_flag(QTestState * qts,uint32_t event_addr,uint32_t flag)74 static bool usart_wait_for_flag(QTestState *qts, uint32_t event_addr,
75 uint32_t flag)
76 {
77 while (true) {
78 if ((qtest_readl(qts, event_addr) & flag)) {
79 return true;
80 }
81 g_usleep(1000);
82 }
83
84 return false;
85 }
86
usart_receive_string(QTestState * qts,int sock_fd,const char * in,char * out)87 static void usart_receive_string(QTestState *qts, int sock_fd, const char *in,
88 char *out)
89 {
90 int i, in_len = strlen(in);
91
92 g_assert_true(send(sock_fd, in, in_len, 0) == in_len);
93 for (i = 0; i < in_len; i++) {
94 g_assert_true(usart_wait_for_flag(qts,
95 USART1_BASE_ADDR + A_ISR, R_ISR_RXNE_MASK));
96 out[i] = qtest_readl(qts, USART1_BASE_ADDR + A_RDR);
97 }
98 out[i] = '\0';
99 }
100
usart_send_string(QTestState * qts,const char * in)101 static void usart_send_string(QTestState *qts, const char *in)
102 {
103 int i, in_len = strlen(in);
104
105 for (i = 0; i < in_len; i++) {
106 qtest_writel(qts, USART1_BASE_ADDR + A_TDR, in[i]);
107 g_assert_true(usart_wait_for_flag(qts,
108 USART1_BASE_ADDR + A_ISR, R_ISR_TXE_MASK));
109 }
110 }
111
112 /* Init the RCC clocks to run at 80 MHz */
init_clocks(QTestState * qts)113 static void init_clocks(QTestState *qts)
114 {
115 uint32_t value;
116
117 /* MSIRANGE can be set only when MSI is OFF or READY */
118 qtest_writel(qts, (RCC_BASE_ADDR + A_CR), R_CR_MSION_MASK);
119
120 /* Clocking from MSI, in case MSI was not the default source */
121 qtest_writel(qts, (RCC_BASE_ADDR + A_CFGR), 0);
122
123 /*
124 * Update PLL and set MSI as the source clock.
125 * PLLM = 1 --> 000
126 * PLLN = 40 --> 40
127 * PPLLR = 2 --> 00
128 * PLLDIV = unused, PLLP = unused (SAI3), PLLQ = unused (48M1)
129 * SRC = MSI --> 01
130 */
131 qtest_writel(qts, (RCC_BASE_ADDR + A_PLLCFGR), R_PLLCFGR_PLLREN_MASK |
132 (40 << R_PLLCFGR_PLLN_SHIFT) |
133 (0b01 << R_PLLCFGR_PLLSRC_SHIFT));
134
135 /* PLL activation */
136
137 value = qtest_readl(qts, (RCC_BASE_ADDR + A_CR));
138 qtest_writel(qts, (RCC_BASE_ADDR + A_CR), value | R_CR_PLLON_MASK);
139
140 /* RCC_CFGR is OK by defaut */
141 qtest_writel(qts, (RCC_BASE_ADDR + A_CFGR), 0);
142
143 /* CCIPR : no periph clock by default */
144 qtest_writel(qts, (RCC_BASE_ADDR + A_CCIPR), 0);
145
146 /* Switches on the PLL clock source */
147 value = qtest_readl(qts, (RCC_BASE_ADDR + A_CFGR));
148 qtest_writel(qts, (RCC_BASE_ADDR + A_CFGR), (value & ~R_CFGR_SW_MASK) |
149 (0b11 << R_CFGR_SW_SHIFT));
150
151 /* Enable SYSCFG clock enabled */
152 qtest_writel(qts, (RCC_BASE_ADDR + A_APB2ENR), R_APB2ENR_SYSCFGEN_MASK);
153
154 /* Enable the IO port B clock (See p.252) */
155 qtest_writel(qts, (RCC_BASE_ADDR + A_AHB2ENR), R_AHB2ENR_GPIOBEN_MASK);
156
157 /* Enable the clock for USART1 (cf p.259) */
158 /* We rewrite SYSCFGEN to not disable it */
159 qtest_writel(qts, (RCC_BASE_ADDR + A_APB2ENR),
160 R_APB2ENR_SYSCFGEN_MASK | R_APB2ENR_USART1EN_MASK);
161
162 /* TODO: Enable usart via gpio */
163
164 /* Set PCLK as the clock for USART1(cf p.272) i.e. reset both bits */
165 qtest_writel(qts, (RCC_BASE_ADDR + A_CCIPR), 0);
166
167 /* Reset USART1 (see p.249) */
168 qtest_writel(qts, (RCC_BASE_ADDR + A_APB2RSTR), 1 << 14);
169 qtest_writel(qts, (RCC_BASE_ADDR + A_APB2RSTR), 0);
170 }
171
init_uart(QTestState * qts)172 static void init_uart(QTestState *qts)
173 {
174 uint32_t cr1;
175
176 init_clocks(qts);
177
178 /*
179 * For 115200 bauds, see p.1349.
180 * The clock has a frequency of 80Mhz,
181 * for 115200, we have to put a divider of 695 = 0x2B7.
182 */
183 qtest_writel(qts, (USART1_BASE_ADDR + A_BRR), 0x2B7);
184
185 /*
186 * Set the oversampling by 16,
187 * disable the parity control and
188 * set the word length to 8. (cf p.1377)
189 */
190 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1));
191 cr1 &= ~(R_CR1_M1_MASK | R_CR1_M0_MASK | R_CR1_OVER8_MASK | R_CR1_PCE_MASK);
192 qtest_writel(qts, (USART1_BASE_ADDR + A_CR1), cr1);
193
194 /* Enable the transmitter, the receiver and the USART. */
195 qtest_writel(qts, (USART1_BASE_ADDR + A_CR1),
196 cr1 | R_CR1_UE_MASK | R_CR1_RE_MASK | R_CR1_TE_MASK);
197 }
198
test_write_read(void)199 static void test_write_read(void)
200 {
201 QTestState *qts = qtest_init("-M b-l475e-iot01a");
202
203 /* Test that we can write and retrieve a value from the device */
204 qtest_writel(qts, USART1_BASE_ADDR + A_TDR, 0xFFFFFFFF);
205 const uint32_t tdr = qtest_readl(qts, USART1_BASE_ADDR + A_TDR);
206 g_assert_cmpuint(tdr, ==, 0x000001FF);
207 }
208
test_receive_char(void)209 static void test_receive_char(void)
210 {
211 int sock_fd;
212 uint32_t cr1;
213 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd);
214
215 init_uart(qts);
216
217 /* Try without initializing IRQ */
218 g_assert_true(send(sock_fd, "a", 1, 0) == 1);
219 usart_wait_for_flag(qts, USART1_BASE_ADDR + A_ISR, R_ISR_RXNE_MASK);
220 g_assert_cmphex(qtest_readl(qts, USART1_BASE_ADDR + A_RDR), ==, 'a');
221 g_assert_false(check_nvic_pending(qts, USART1_IRQ));
222
223 /* Now with the IRQ */
224 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1));
225 cr1 |= R_CR1_RXNEIE_MASK;
226 qtest_writel(qts, USART1_BASE_ADDR + A_CR1, cr1);
227 g_assert_true(send(sock_fd, "b", 1, 0) == 1);
228 usart_wait_for_flag(qts, USART1_BASE_ADDR + A_ISR, R_ISR_RXNE_MASK);
229 g_assert_cmphex(qtest_readl(qts, USART1_BASE_ADDR + A_RDR), ==, 'b');
230 g_assert_true(check_nvic_pending(qts, USART1_IRQ));
231 clear_nvic_pending(qts, USART1_IRQ);
232
233 close(sock_fd);
234
235 qtest_quit(qts);
236 }
237
test_send_char(void)238 static void test_send_char(void)
239 {
240 int sock_fd;
241 char s[1];
242 uint32_t cr1;
243 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd);
244
245 init_uart(qts);
246
247 /* Try without initializing IRQ */
248 qtest_writel(qts, USART1_BASE_ADDR + A_TDR, 'c');
249 g_assert_true(recv(sock_fd, s, 1, 0) == 1);
250 g_assert_cmphex(s[0], ==, 'c');
251 g_assert_false(check_nvic_pending(qts, USART1_IRQ));
252
253 /* Now with the IRQ */
254 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1));
255 cr1 |= R_CR1_TXEIE_MASK;
256 qtest_writel(qts, USART1_BASE_ADDR + A_CR1, cr1);
257 qtest_writel(qts, USART1_BASE_ADDR + A_TDR, 'd');
258 g_assert_true(recv(sock_fd, s, 1, 0) == 1);
259 g_assert_cmphex(s[0], ==, 'd');
260 g_assert_true(check_nvic_pending(qts, USART1_IRQ));
261 clear_nvic_pending(qts, USART1_IRQ);
262
263 close(sock_fd);
264
265 qtest_quit(qts);
266 }
267
test_receive_str(void)268 static void test_receive_str(void)
269 {
270 int sock_fd;
271 char s[10];
272 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd);
273
274 init_uart(qts);
275
276 usart_receive_string(qts, sock_fd, "hello", s);
277 g_assert_true(memcmp(s, "hello", 5) == 0);
278
279 close(sock_fd);
280
281 qtest_quit(qts);
282 }
283
test_send_str(void)284 static void test_send_str(void)
285 {
286 int sock_fd;
287 char s[10];
288 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd);
289
290 init_uart(qts);
291
292 usart_send_string(qts, "world");
293 g_assert_true(recv(sock_fd, s, 10, 0) == 5);
294 g_assert_true(memcmp(s, "world", 5) == 0);
295
296 close(sock_fd);
297
298 qtest_quit(qts);
299 }
300
test_ack(void)301 static void test_ack(void)
302 {
303 uint32_t cr1;
304 uint32_t isr;
305 QTestState *qts = qtest_init("-M b-l475e-iot01a");
306
307 init_uart(qts);
308
309 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1));
310
311 /* Disable the transmitter and receiver. */
312 qtest_writel(qts, (USART1_BASE_ADDR + A_CR1),
313 cr1 & ~(R_CR1_RE_MASK | R_CR1_TE_MASK));
314
315 /* Test ISR ACK for transmitter and receiver disabled */
316 isr = qtest_readl(qts, (USART1_BASE_ADDR + A_ISR));
317 g_assert_false(isr & R_ISR_TEACK_MASK);
318 g_assert_false(isr & R_ISR_REACK_MASK);
319
320 /* Enable the transmitter and receiver. */
321 qtest_writel(qts, (USART1_BASE_ADDR + A_CR1),
322 cr1 | (R_CR1_RE_MASK | R_CR1_TE_MASK));
323
324 /* Test ISR ACK for transmitter and receiver disabled */
325 isr = qtest_readl(qts, (USART1_BASE_ADDR + A_ISR));
326 g_assert_true(isr & R_ISR_TEACK_MASK);
327 g_assert_true(isr & R_ISR_REACK_MASK);
328
329 qtest_quit(qts);
330 }
331
main(int argc,char ** argv)332 int main(int argc, char **argv)
333 {
334 int ret;
335
336 g_test_init(&argc, &argv, NULL);
337 g_test_set_nonfatal_assertions();
338
339 qtest_add_func("stm32l4x5/usart/write_read", test_write_read);
340 qtest_add_func("stm32l4x5/usart/receive_char", test_receive_char);
341 qtest_add_func("stm32l4x5/usart/send_char", test_send_char);
342 qtest_add_func("stm32l4x5/usart/receive_str", test_receive_str);
343 qtest_add_func("stm32l4x5/usart/send_str", test_send_str);
344 qtest_add_func("stm32l4x5/usart/ack", test_ack);
345 ret = g_test_run();
346
347 return ret;
348 }
349
350