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 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 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 */ 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 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 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 */ 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 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 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 qtest_quit(qts); 209 } 210 211 static void test_receive_char(void) 212 { 213 int sock_fd; 214 uint32_t cr1; 215 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 216 217 init_uart(qts); 218 219 /* Try without initializing IRQ */ 220 g_assert_true(send(sock_fd, "a", 1, 0) == 1); 221 usart_wait_for_flag(qts, USART1_BASE_ADDR + A_ISR, R_ISR_RXNE_MASK); 222 g_assert_cmphex(qtest_readl(qts, USART1_BASE_ADDR + A_RDR), ==, 'a'); 223 g_assert_false(check_nvic_pending(qts, USART1_IRQ)); 224 225 /* Now with the IRQ */ 226 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1)); 227 cr1 |= R_CR1_RXNEIE_MASK; 228 qtest_writel(qts, USART1_BASE_ADDR + A_CR1, cr1); 229 g_assert_true(send(sock_fd, "b", 1, 0) == 1); 230 usart_wait_for_flag(qts, USART1_BASE_ADDR + A_ISR, R_ISR_RXNE_MASK); 231 g_assert_cmphex(qtest_readl(qts, USART1_BASE_ADDR + A_RDR), ==, 'b'); 232 g_assert_true(check_nvic_pending(qts, USART1_IRQ)); 233 clear_nvic_pending(qts, USART1_IRQ); 234 235 close(sock_fd); 236 237 qtest_quit(qts); 238 } 239 240 static void test_send_char(void) 241 { 242 int sock_fd; 243 char s[1]; 244 uint32_t cr1; 245 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 246 247 init_uart(qts); 248 249 /* Try without initializing IRQ */ 250 qtest_writel(qts, USART1_BASE_ADDR + A_TDR, 'c'); 251 g_assert_true(recv(sock_fd, s, 1, 0) == 1); 252 g_assert_cmphex(s[0], ==, 'c'); 253 g_assert_false(check_nvic_pending(qts, USART1_IRQ)); 254 255 /* Now with the IRQ */ 256 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1)); 257 cr1 |= R_CR1_TXEIE_MASK; 258 qtest_writel(qts, USART1_BASE_ADDR + A_CR1, cr1); 259 qtest_writel(qts, USART1_BASE_ADDR + A_TDR, 'd'); 260 g_assert_true(recv(sock_fd, s, 1, 0) == 1); 261 g_assert_cmphex(s[0], ==, 'd'); 262 g_assert_true(check_nvic_pending(qts, USART1_IRQ)); 263 clear_nvic_pending(qts, USART1_IRQ); 264 265 close(sock_fd); 266 267 qtest_quit(qts); 268 } 269 270 static void test_receive_str(void) 271 { 272 int sock_fd; 273 char s[10]; 274 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 275 276 init_uart(qts); 277 278 usart_receive_string(qts, sock_fd, "hello", s); 279 g_assert_true(memcmp(s, "hello", 5) == 0); 280 281 close(sock_fd); 282 283 qtest_quit(qts); 284 } 285 286 static void test_send_str(void) 287 { 288 int sock_fd; 289 char s[10]; 290 QTestState *qts = qtest_init_with_serial("-M b-l475e-iot01a", &sock_fd); 291 292 init_uart(qts); 293 294 usart_send_string(qts, "world"); 295 g_assert_true(recv(sock_fd, s, 10, 0) == 5); 296 g_assert_true(memcmp(s, "world", 5) == 0); 297 298 close(sock_fd); 299 300 qtest_quit(qts); 301 } 302 303 static void test_ack(void) 304 { 305 uint32_t cr1; 306 uint32_t isr; 307 QTestState *qts = qtest_init("-M b-l475e-iot01a"); 308 309 init_uart(qts); 310 311 cr1 = qtest_readl(qts, (USART1_BASE_ADDR + A_CR1)); 312 313 /* Disable the transmitter and receiver. */ 314 qtest_writel(qts, (USART1_BASE_ADDR + A_CR1), 315 cr1 & ~(R_CR1_RE_MASK | R_CR1_TE_MASK)); 316 317 /* Test ISR ACK for transmitter and receiver disabled */ 318 isr = qtest_readl(qts, (USART1_BASE_ADDR + A_ISR)); 319 g_assert_false(isr & R_ISR_TEACK_MASK); 320 g_assert_false(isr & R_ISR_REACK_MASK); 321 322 /* Enable the transmitter and receiver. */ 323 qtest_writel(qts, (USART1_BASE_ADDR + A_CR1), 324 cr1 | (R_CR1_RE_MASK | R_CR1_TE_MASK)); 325 326 /* Test ISR ACK for transmitter and receiver disabled */ 327 isr = qtest_readl(qts, (USART1_BASE_ADDR + A_ISR)); 328 g_assert_true(isr & R_ISR_TEACK_MASK); 329 g_assert_true(isr & R_ISR_REACK_MASK); 330 331 qtest_quit(qts); 332 } 333 334 int main(int argc, char **argv) 335 { 336 int ret; 337 338 g_test_init(&argc, &argv, NULL); 339 g_test_set_nonfatal_assertions(); 340 341 qtest_add_func("stm32l4x5/usart/write_read", test_write_read); 342 qtest_add_func("stm32l4x5/usart/receive_char", test_receive_char); 343 qtest_add_func("stm32l4x5/usart/send_char", test_send_char); 344 qtest_add_func("stm32l4x5/usart/receive_str", test_receive_str); 345 qtest_add_func("stm32l4x5/usart/send_str", test_send_str); 346 qtest_add_func("stm32l4x5/usart/ack", test_ack); 347 ret = g_test_run(); 348 349 return ret; 350 } 351 352