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 #include "stm32l4x5.h" 16 17 #define RCC_BASE_ADDR 0x40021000 18 /* Use USART 1 ADDR, assume the others work the same */ 19 #define USART1_BASE_ADDR 0x40013800 20 21 /* See stm32l4x5_usart for definitions */ 22 REG32(CR1, 0x00) 23 FIELD(CR1, M1, 28, 1) 24 FIELD(CR1, OVER8, 15, 1) 25 FIELD(CR1, M0, 12, 1) 26 FIELD(CR1, PCE, 10, 1) 27 FIELD(CR1, TXEIE, 7, 1) 28 FIELD(CR1, RXNEIE, 5, 1) 29 FIELD(CR1, TE, 3, 1) 30 FIELD(CR1, RE, 2, 1) 31 FIELD(CR1, UE, 0, 1) 32 REG32(CR2, 0x04) 33 REG32(CR3, 0x08) 34 FIELD(CR3, OVRDIS, 12, 1) 35 REG32(BRR, 0x0C) 36 REG32(GTPR, 0x10) 37 REG32(RTOR, 0x14) 38 REG32(RQR, 0x18) 39 REG32(ISR, 0x1C) 40 FIELD(ISR, REACK, 22, 1) 41 FIELD(ISR, TEACK, 21, 1) 42 FIELD(ISR, TXE, 7, 1) 43 FIELD(ISR, RXNE, 5, 1) 44 FIELD(ISR, ORE, 3, 1) 45 REG32(ICR, 0x20) 46 REG32(RDR, 0x24) 47 REG32(TDR, 0x28) 48 49 #define NVIC_ISPR1 0XE000E204 50 #define NVIC_ICPR1 0xE000E284 51 #define USART1_IRQ 37 52 53 static bool check_nvic_pending(QTestState *qts, unsigned int n) 54 { 55 /* No USART interrupts are less than 32 */ 56 assert(n > 32); 57 n -= 32; 58 return qtest_readl(qts, NVIC_ISPR1) & (1 << n); 59 } 60 61 static bool clear_nvic_pending(QTestState *qts, unsigned int n) 62 { 63 /* No USART interrupts are less than 32 */ 64 assert(n > 32); 65 n -= 32; 66 qtest_writel(qts, NVIC_ICPR1, (1 << n)); 67 return true; 68 } 69 70 /* 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. 74 */ 75 static bool usart_wait_for_flag(QTestState *qts, uint32_t event_addr, 76 uint32_t flag) 77 { 78 while (true) { 79 if ((qtest_readl(qts, event_addr) & flag)) { 80 return true; 81 } 82 g_usleep(1000); 83 } 84 85 return false; 86 } 87 88 static void usart_receive_string(QTestState *qts, int sock_fd, const char *in, 89 char *out) 90 { 91 int i, in_len = strlen(in); 92 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); 98 } 99 out[i] = '\0'; 100 } 101 102 static void usart_send_string(QTestState *qts, const char *in) 103 { 104 int i, in_len = strlen(in); 105 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)); 110 } 111 } 112 113 /* Init the RCC clocks to run at 80 MHz */ 114 static void init_clocks(QTestState *qts) 115 { 116 uint32_t value; 117 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); 120 121 /* Clocking from MSI, in case MSI was not the default source */ 122 qtest_writel(qts, (RCC_BASE_ADDR + A_CFGR), 0); 123 124 /* 125 * Update PLL and set MSI as the source clock. 126 * PLLM = 1 --> 000 127 * PLLN = 40 --> 40 128 * PPLLR = 2 --> 00 129 * PLLDIV = unused, PLLP = unused (SAI3), PLLQ = unused (48M1) 130 * SRC = MSI --> 01 131 */ 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)); 135 136 /* PLL activation */ 137 138 value = qtest_readl(qts, (RCC_BASE_ADDR + A_CR)); 139 qtest_writel(qts, (RCC_BASE_ADDR + A_CR), value | R_CR_PLLON_MASK); 140 141 /* RCC_CFGR is OK by defaut */ 142 qtest_writel(qts, (RCC_BASE_ADDR + A_CFGR), 0); 143 144 /* CCIPR : no periph clock by default */ 145 qtest_writel(qts, (RCC_BASE_ADDR + A_CCIPR), 0); 146 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)); 151 152 /* Enable SYSCFG clock enabled */ 153 qtest_writel(qts, (RCC_BASE_ADDR + A_APB2ENR), R_APB2ENR_SYSCFGEN_MASK); 154 155 /* Enable the IO port B clock (See p.252) */ 156 qtest_writel(qts, (RCC_BASE_ADDR + A_AHB2ENR), R_AHB2ENR_GPIOBEN_MASK); 157 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); 162 163 /* TODO: Enable usart via gpio */ 164 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); 167 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); 171 } 172 173 static void init_uart(QTestState *qts) 174 { 175 uint32_t cr1; 176 177 init_clocks(qts); 178 179 /* 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. 183 */ 184 qtest_writel(qts, (USART1_BASE_ADDR + A_BRR), 0x2B7); 185 186 /* 187 * Set the oversampling by 16, 188 * disable the parity control and 189 * set the word length to 8. (cf p.1377) 190 */ 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); 194 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); 198 } 199 200 static void test_write_read(void) 201 { 202 QTestState *qts = qtest_init("-M b-l475e-iot01a"); 203 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); 208 209 qtest_quit(qts); 210 } 211 212 static void test_receive_char(void) 213 { 214 int sock_fd; 215 uint32_t cr1; 216 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 217 218 init_uart(qts); 219 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)); 225 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); 235 236 close(sock_fd); 237 238 qtest_quit(qts); 239 } 240 241 static void test_send_char(void) 242 { 243 int sock_fd; 244 char s[1]; 245 uint32_t cr1; 246 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 247 248 init_uart(qts); 249 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)); 255 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); 265 266 close(sock_fd); 267 268 qtest_quit(qts); 269 } 270 271 static void test_receive_str(void) 272 { 273 int sock_fd; 274 char s[10]; 275 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 276 277 init_uart(qts); 278 279 usart_receive_string(qts, sock_fd, "hello", s); 280 g_assert_true(memcmp(s, "hello", 5) == 0); 281 282 close(sock_fd); 283 284 qtest_quit(qts); 285 } 286 287 static void test_send_str(void) 288 { 289 int sock_fd; 290 char s[10]; 291 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 292 293 init_uart(qts); 294 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); 298 299 close(sock_fd); 300 301 qtest_quit(qts); 302 } 303 304 static void test_ack(void) 305 { 306 uint32_t cr1; 307 uint32_t isr; 308 QTestState *qts = qtest_init("-M b-l475e-iot01a"); 309 310 init_uart(qts); 311 312 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1)); 313 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)); 317 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); 322 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)); 326 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); 331 332 qtest_quit(qts); 333 } 334 335 static void check_clock(QTestState *qts, const char *path, uint32_t rcc_reg, 336 uint32_t reg_offset) 337 { 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); 341 } 342 343 static void test_clock_enable(void) 344 { 345 /* 346 * For each USART device, enable its clock in RCC 347 * and check that its clock frequency is SYSCLK_PERIOD 348 */ 349 QTestState *qts = qtest_init("-M b-l475e-iot01a"); 350 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); 357 358 qtest_quit(qts); 359 } 360 361 int main(int argc, char **argv) 362 { 363 int ret; 364 365 g_test_init(&argc, &argv, NULL); 366 g_test_set_nonfatal_assertions(); 367 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); 375 ret = g_test_run(); 376 377 return ret; 378 } 379 380