2 * QTest testcase for STML4X5_USART
4 * Copyright (c) 2023 Arnaud Minier <arnaud.minier@telecom-paris.fr>
5 * Copyright (c) 2023 Inès Varhol <ines.varhol@telecom-paris.fr>
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.
11 #include "qemu/osdep.h"
13 #include "hw/misc/stm32l4x5_rcc_internals.h"
14 #include "hw/registerfields.h"
15 #include "stm32l4x5.h"
17 #define RCC_BASE_ADDR 0x40021000
18 /* Use USART 1 ADDR, assume the others work the same */
19 #define USART1_BASE_ADDR 0x40013800
21 /* See stm32l4x5_usart for definitions */
24 FIELD(CR1
, OVER8
, 15, 1)
26 FIELD(CR1
, PCE
, 10, 1)
27 FIELD(CR1
, TXEIE
, 7, 1)
28 FIELD(CR1
, RXNEIE
, 5, 1)
34 FIELD(CR3
, OVRDIS
, 12, 1)
40 FIELD(ISR
, REACK
, 22, 1)
41 FIELD(ISR
, TEACK
, 21, 1)
43 FIELD(ISR
, RXNE
, 5, 1)
49 #define NVIC_ISPR1 0XE000E204
50 #define NVIC_ICPR1 0xE000E284
53 static bool check_nvic_pending(QTestState
*qts
, unsigned int n
)
55 /* No USART interrupts are less than 32 */
58 return qtest_readl(qts
, NVIC_ISPR1
) & (1 << n
);
61 static bool clear_nvic_pending(QTestState
*qts
, unsigned int n
)
63 /* No USART interrupts are less than 32 */
66 qtest_writel(qts
, NVIC_ICPR1
, (1 << n
));
71 * Wait indefinitely for the flag to be updated.
72 * If this is run on a slow CI runner,
73 * the meson harness will timeout after 10 minutes for us.
75 static bool usart_wait_for_flag(QTestState
*qts
, uint32_t event_addr
,
79 if ((qtest_readl(qts
, event_addr
) & flag
)) {
88 static void usart_receive_string(QTestState
*qts
, int sock_fd
, const char *in
,
91 int i
, in_len
= strlen(in
);
93 g_assert_true(send(sock_fd
, in
, in_len
, 0) == in_len
);
94 for (i
= 0; i
< in_len
; i
++) {
95 g_assert_true(usart_wait_for_flag(qts
,
96 USART1_BASE_ADDR
+ A_ISR
, R_ISR_RXNE_MASK
));
97 out
[i
] = qtest_readl(qts
, USART1_BASE_ADDR
+ A_RDR
);
102 static void usart_send_string(QTestState
*qts
, const char *in
)
104 int i
, in_len
= strlen(in
);
106 for (i
= 0; i
< in_len
; i
++) {
107 qtest_writel(qts
, USART1_BASE_ADDR
+ A_TDR
, in
[i
]);
108 g_assert_true(usart_wait_for_flag(qts
,
109 USART1_BASE_ADDR
+ A_ISR
, R_ISR_TXE_MASK
));
113 /* Init the RCC clocks to run at 80 MHz */
114 static void init_clocks(QTestState
*qts
)
118 /* MSIRANGE can be set only when MSI is OFF or READY */
119 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_CR
), R_CR_MSION_MASK
);
121 /* Clocking from MSI, in case MSI was not the default source */
122 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_CFGR
), 0);
125 * Update PLL and set MSI as the source clock.
129 * PLLDIV = unused, PLLP = unused (SAI3), PLLQ = unused (48M1)
132 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_PLLCFGR
), R_PLLCFGR_PLLREN_MASK
|
133 (40 << R_PLLCFGR_PLLN_SHIFT
) |
134 (0b01 << R_PLLCFGR_PLLSRC_SHIFT
));
138 value
= qtest_readl(qts
, (RCC_BASE_ADDR
+ A_CR
));
139 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_CR
), value
| R_CR_PLLON_MASK
);
141 /* RCC_CFGR is OK by defaut */
142 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_CFGR
), 0);
144 /* CCIPR : no periph clock by default */
145 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_CCIPR
), 0);
147 /* Switches on the PLL clock source */
148 value
= qtest_readl(qts
, (RCC_BASE_ADDR
+ A_CFGR
));
149 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_CFGR
), (value
& ~R_CFGR_SW_MASK
) |
150 (0b11 << R_CFGR_SW_SHIFT
));
152 /* Enable SYSCFG clock enabled */
153 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_APB2ENR
), R_APB2ENR_SYSCFGEN_MASK
);
155 /* Enable the IO port B clock (See p.252) */
156 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_AHB2ENR
), R_AHB2ENR_GPIOBEN_MASK
);
158 /* Enable the clock for USART1 (cf p.259) */
159 /* We rewrite SYSCFGEN to not disable it */
160 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_APB2ENR
),
161 R_APB2ENR_SYSCFGEN_MASK
| R_APB2ENR_USART1EN_MASK
);
163 /* TODO: Enable usart via gpio */
165 /* Set PCLK as the clock for USART1(cf p.272) i.e. reset both bits */
166 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_CCIPR
), 0);
168 /* Reset USART1 (see p.249) */
169 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_APB2RSTR
), 1 << 14);
170 qtest_writel(qts
, (RCC_BASE_ADDR
+ A_APB2RSTR
), 0);
173 static void init_uart(QTestState
*qts
)
180 * For 115200 bauds, see p.1349.
181 * The clock has a frequency of 80Mhz,
182 * for 115200, we have to put a divider of 695 = 0x2B7.
184 qtest_writel(qts
, (USART1_BASE_ADDR
+ A_BRR
), 0x2B7);
187 * Set the oversampling by 16,
188 * disable the parity control and
189 * set the word length to 8. (cf p.1377)
191 cr1
= qtest_readl(qts
, (USART1_BASE_ADDR
+ A_CR1
));
192 cr1
&= ~(R_CR1_M1_MASK
| R_CR1_M0_MASK
| R_CR1_OVER8_MASK
| R_CR1_PCE_MASK
);
193 qtest_writel(qts
, (USART1_BASE_ADDR
+ A_CR1
), cr1
);
195 /* Enable the transmitter, the receiver and the USART. */
196 qtest_writel(qts
, (USART1_BASE_ADDR
+ A_CR1
),
197 cr1
| R_CR1_UE_MASK
| R_CR1_RE_MASK
| R_CR1_TE_MASK
);
200 static void test_write_read(void)
202 QTestState
*qts
= qtest_init("-M b-l475e-iot01a");
204 /* Test that we can write and retrieve a value from the device */
205 qtest_writel(qts
, USART1_BASE_ADDR
+ A_TDR
, 0xFFFFFFFF);
206 const uint32_t tdr
= qtest_readl(qts
, USART1_BASE_ADDR
+ A_TDR
);
207 g_assert_cmpuint(tdr
, ==, 0x000001FF);
212 static void test_receive_char(void)
216 QTestState
*qts
= qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd
);
220 /* Try without initializing IRQ */
221 g_assert_true(send(sock_fd
, "a", 1, 0) == 1);
222 usart_wait_for_flag(qts
, USART1_BASE_ADDR
+ A_ISR
, R_ISR_RXNE_MASK
);
223 g_assert_cmphex(qtest_readl(qts
, USART1_BASE_ADDR
+ A_RDR
), ==, 'a');
224 g_assert_false(check_nvic_pending(qts
, USART1_IRQ
));
226 /* Now with the IRQ */
227 cr1
= qtest_readl(qts
, (USART1_BASE_ADDR
+ A_CR1
));
228 cr1
|= R_CR1_RXNEIE_MASK
;
229 qtest_writel(qts
, USART1_BASE_ADDR
+ A_CR1
, cr1
);
230 g_assert_true(send(sock_fd
, "b", 1, 0) == 1);
231 usart_wait_for_flag(qts
, USART1_BASE_ADDR
+ A_ISR
, R_ISR_RXNE_MASK
);
232 g_assert_cmphex(qtest_readl(qts
, USART1_BASE_ADDR
+ A_RDR
), ==, 'b');
233 g_assert_true(check_nvic_pending(qts
, USART1_IRQ
));
234 clear_nvic_pending(qts
, USART1_IRQ
);
241 static void test_send_char(void)
246 QTestState
*qts
= qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd
);
250 /* Try without initializing IRQ */
251 qtest_writel(qts
, USART1_BASE_ADDR
+ A_TDR
, 'c');
252 g_assert_true(recv(sock_fd
, s
, 1, 0) == 1);
253 g_assert_cmphex(s
[0], ==, 'c');
254 g_assert_false(check_nvic_pending(qts
, USART1_IRQ
));
256 /* Now with the IRQ */
257 cr1
= qtest_readl(qts
, (USART1_BASE_ADDR
+ A_CR1
));
258 cr1
|= R_CR1_TXEIE_MASK
;
259 qtest_writel(qts
, USART1_BASE_ADDR
+ A_CR1
, cr1
);
260 qtest_writel(qts
, USART1_BASE_ADDR
+ A_TDR
, 'd');
261 g_assert_true(recv(sock_fd
, s
, 1, 0) == 1);
262 g_assert_cmphex(s
[0], ==, 'd');
263 g_assert_true(check_nvic_pending(qts
, USART1_IRQ
));
264 clear_nvic_pending(qts
, USART1_IRQ
);
271 static void test_receive_str(void)
275 QTestState
*qts
= qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd
);
279 usart_receive_string(qts
, sock_fd
, "hello", s
);
280 g_assert_true(memcmp(s
, "hello", 5) == 0);
287 static void test_send_str(void)
291 QTestState
*qts
= qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd
);
295 usart_send_string(qts
, "world");
296 g_assert_true(recv(sock_fd
, s
, 10, 0) == 5);
297 g_assert_true(memcmp(s
, "world", 5) == 0);
304 static void test_ack(void)
308 QTestState
*qts
= qtest_init("-M b-l475e-iot01a");
312 cr1
= qtest_readl(qts
, (USART1_BASE_ADDR
+ A_CR1
));
314 /* Disable the transmitter and receiver. */
315 qtest_writel(qts
, (USART1_BASE_ADDR
+ A_CR1
),
316 cr1
& ~(R_CR1_RE_MASK
| R_CR1_TE_MASK
));
318 /* Test ISR ACK for transmitter and receiver disabled */
319 isr
= qtest_readl(qts
, (USART1_BASE_ADDR
+ A_ISR
));
320 g_assert_false(isr
& R_ISR_TEACK_MASK
);
321 g_assert_false(isr
& R_ISR_REACK_MASK
);
323 /* Enable the transmitter and receiver. */
324 qtest_writel(qts
, (USART1_BASE_ADDR
+ A_CR1
),
325 cr1
| (R_CR1_RE_MASK
| R_CR1_TE_MASK
));
327 /* Test ISR ACK for transmitter and receiver disabled */
328 isr
= qtest_readl(qts
, (USART1_BASE_ADDR
+ A_ISR
));
329 g_assert_true(isr
& R_ISR_TEACK_MASK
);
330 g_assert_true(isr
& R_ISR_REACK_MASK
);
335 static void check_clock(QTestState
*qts
, const char *path
, uint32_t rcc_reg
,
338 g_assert_cmpuint(get_clock_period(qts
, path
), ==, 0);
339 qtest_writel(qts
, rcc_reg
, qtest_readl(qts
, rcc_reg
) | (0x1 << reg_offset
));
340 g_assert_cmpuint(get_clock_period(qts
, path
), ==, SYSCLK_PERIOD
);
343 static void test_clock_enable(void)
346 * For each USART device, enable its clock in RCC
347 * and check that its clock frequency is SYSCLK_PERIOD
349 QTestState
*qts
= qtest_init("-M b-l475e-iot01a");
351 check_clock(qts
, "machine/soc/usart[0]/clk", RCC_APB2ENR
, 14);
352 check_clock(qts
, "machine/soc/usart[1]/clk", RCC_APB1ENR1
, 17);
353 check_clock(qts
, "machine/soc/usart[2]/clk", RCC_APB1ENR1
, 18);
354 check_clock(qts
, "machine/soc/uart[0]/clk", RCC_APB1ENR1
, 19);
355 check_clock(qts
, "machine/soc/uart[1]/clk", RCC_APB1ENR1
, 20);
356 check_clock(qts
, "machine/soc/lpuart1/clk", RCC_APB1ENR2
, 0);
361 int main(int argc
, char **argv
)
365 g_test_init(&argc
, &argv
, NULL
);
366 g_test_set_nonfatal_assertions();
368 qtest_add_func("stm32l4x5/usart/write_read", test_write_read
);
369 qtest_add_func("stm32l4x5/usart/receive_char", test_receive_char
);
370 qtest_add_func("stm32l4x5/usart/send_char", test_send_char
);
371 qtest_add_func("stm32l4x5/usart/receive_str", test_receive_str
);
372 qtest_add_func("stm32l4x5/usart/send_str", test_send_str
);
373 qtest_add_func("stm32l4x5/usart/ack", test_ack
);
374 qtest_add_func("stm32l4x5/usart/clock_enable", test_clock_enable
);