1 /* 2 * QTest testcase for STM32L4x5_GPIO 3 * 4 * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr> 5 * Copyright (c) 2024 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-single.h" 13 14 #define GPIO_BASE_ADDR 0x48000000 15 #define GPIO_SIZE 0x400 16 #define NUM_GPIOS 8 17 #define NUM_GPIO_PINS 16 18 19 #define GPIO_A 0x48000000 20 #define GPIO_B 0x48000400 21 #define GPIO_C 0x48000800 22 #define GPIO_D 0x48000C00 23 #define GPIO_E 0x48001000 24 #define GPIO_F 0x48001400 25 #define GPIO_G 0x48001800 26 #define GPIO_H 0x48001C00 27 28 #define MODER 0x00 29 #define OTYPER 0x04 30 #define PUPDR 0x0C 31 #define IDR 0x10 32 #define ODR 0x14 33 #define BSRR 0x18 34 #define BRR 0x28 35 36 #define MODER_INPUT 0 37 #define MODER_OUTPUT 1 38 39 #define PUPDR_NONE 0 40 #define PUPDR_PULLUP 1 41 #define PUPDR_PULLDOWN 2 42 43 #define OTYPER_PUSH_PULL 0 44 #define OTYPER_OPEN_DRAIN 1 45 46 /* SoC forwards GPIOs to SysCfg */ 47 #define SYSCFG "/machine/soc" 48 49 const uint32_t moder_reset[NUM_GPIOS] = { 50 0xABFFFFFF, 51 0xFFFFFEBF, 52 0xFFFFFFFF, 53 0xFFFFFFFF, 54 0xFFFFFFFF, 55 0xFFFFFFFF, 56 0xFFFFFFFF, 57 0x0000000F 58 }; 59 60 const uint32_t pupdr_reset[NUM_GPIOS] = { 61 0x64000000, 62 0x00000100, 63 0x00000000, 64 0x00000000, 65 0x00000000, 66 0x00000000, 67 0x00000000, 68 0x00000000 69 }; 70 71 const uint32_t idr_reset[NUM_GPIOS] = { 72 0x0000A000, 73 0x00000010, 74 0x00000000, 75 0x00000000, 76 0x00000000, 77 0x00000000, 78 0x00000000, 79 0x00000000 80 }; 81 82 #define PIN_MASK 0xF 83 #define GPIO_ADDR_MASK (~(GPIO_SIZE - 1)) 84 85 static inline void *test_data(uint32_t gpio_addr, uint8_t pin) 86 { 87 return (void *)(uintptr_t)((gpio_addr & GPIO_ADDR_MASK) | (pin & PIN_MASK)); 88 } 89 90 #define test_gpio_addr(data) ((uintptr_t)(data) & GPIO_ADDR_MASK) 91 #define test_pin(data) ((uintptr_t)(data) & PIN_MASK) 92 93 static uint32_t gpio_readl(unsigned int gpio, unsigned int offset) 94 { 95 return readl(gpio + offset); 96 } 97 98 static void gpio_writel(unsigned int gpio, unsigned int offset, uint32_t value) 99 { 100 writel(gpio + offset, value); 101 } 102 103 static void gpio_set_bit(unsigned int gpio, unsigned int reg, 104 unsigned int pin, uint32_t value) 105 { 106 uint32_t mask = 0xFFFFFFFF & ~(0x1 << pin); 107 gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << pin); 108 } 109 110 static void gpio_set_2bits(unsigned int gpio, unsigned int reg, 111 unsigned int pin, uint32_t value) 112 { 113 uint32_t offset = 2 * pin; 114 uint32_t mask = 0xFFFFFFFF & ~(0x3 << offset); 115 gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << offset); 116 } 117 118 static unsigned int get_gpio_id(uint32_t gpio_addr) 119 { 120 return (gpio_addr - GPIO_BASE_ADDR) / GPIO_SIZE; 121 } 122 123 static void gpio_set_irq(unsigned int gpio, int num, int level) 124 { 125 g_autofree char *name = g_strdup_printf("/machine/soc/gpio%c", 126 get_gpio_id(gpio) + 'a'); 127 qtest_set_irq_in(global_qtest, name, NULL, num, level); 128 } 129 130 static void disconnect_all_pins(unsigned int gpio) 131 { 132 g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c", 133 get_gpio_id(gpio) + 'a'); 134 QDict *r; 135 136 r = qtest_qmp(global_qtest, "{ 'execute': 'qom-set', 'arguments': " 137 "{ 'path': %s, 'property': 'disconnected-pins', 'value': %d } }", 138 path, 0xFFFF); 139 g_assert_false(qdict_haskey(r, "error")); 140 qobject_unref(r); 141 } 142 143 static uint32_t get_disconnected_pins(unsigned int gpio) 144 { 145 g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c", 146 get_gpio_id(gpio) + 'a'); 147 uint32_t disconnected_pins = 0; 148 QDict *r; 149 150 r = qtest_qmp(global_qtest, "{ 'execute': 'qom-get', 'arguments':" 151 " { 'path': %s, 'property': 'disconnected-pins'} }", path); 152 g_assert_false(qdict_haskey(r, "error")); 153 disconnected_pins = qdict_get_int(r, "return"); 154 qobject_unref(r); 155 return disconnected_pins; 156 } 157 158 static uint32_t reset(uint32_t gpio, unsigned int offset) 159 { 160 switch (offset) { 161 case MODER: 162 return moder_reset[get_gpio_id(gpio)]; 163 case PUPDR: 164 return pupdr_reset[get_gpio_id(gpio)]; 165 case IDR: 166 return idr_reset[get_gpio_id(gpio)]; 167 } 168 return 0x0; 169 } 170 171 static void system_reset(void) 172 { 173 QDict *r; 174 r = qtest_qmp(global_qtest, "{'execute': 'system_reset'}"); 175 g_assert_false(qdict_haskey(r, "error")); 176 qobject_unref(r); 177 } 178 179 static void test_idr_reset_value(void) 180 { 181 /* 182 * Checks that the values in MODER, OTYPER, PUPDR and ODR 183 * after reset are correct, and that the value in IDR is 184 * coherent. 185 * Since AF and analog modes aren't implemented, IDR reset 186 * values aren't the same as with a real board. 187 * 188 * Register IDR contains the actual values of all GPIO pins. 189 * Its value depends on the pins' configuration 190 * (intput/output/analog : register MODER, push-pull/open-drain : 191 * register OTYPER, pull-up/pull-down/none : register PUPDR) 192 * and on the values stored in register ODR 193 * (in case the pin is in output mode). 194 */ 195 196 gpio_writel(GPIO_A, MODER, 0xDEADBEEF); 197 gpio_writel(GPIO_A, ODR, 0xDEADBEEF); 198 gpio_writel(GPIO_A, OTYPER, 0xDEADBEEF); 199 gpio_writel(GPIO_A, PUPDR, 0xDEADBEEF); 200 201 gpio_writel(GPIO_B, MODER, 0xDEADBEEF); 202 gpio_writel(GPIO_B, ODR, 0xDEADBEEF); 203 gpio_writel(GPIO_B, OTYPER, 0xDEADBEEF); 204 gpio_writel(GPIO_B, PUPDR, 0xDEADBEEF); 205 206 gpio_writel(GPIO_C, MODER, 0xDEADBEEF); 207 gpio_writel(GPIO_C, ODR, 0xDEADBEEF); 208 gpio_writel(GPIO_C, OTYPER, 0xDEADBEEF); 209 gpio_writel(GPIO_C, PUPDR, 0xDEADBEEF); 210 211 gpio_writel(GPIO_H, MODER, 0xDEADBEEF); 212 gpio_writel(GPIO_H, ODR, 0xDEADBEEF); 213 gpio_writel(GPIO_H, OTYPER, 0xDEADBEEF); 214 gpio_writel(GPIO_H, PUPDR, 0xDEADBEEF); 215 216 system_reset(); 217 218 uint32_t moder = gpio_readl(GPIO_A, MODER); 219 uint32_t odr = gpio_readl(GPIO_A, ODR); 220 uint32_t otyper = gpio_readl(GPIO_A, OTYPER); 221 uint32_t pupdr = gpio_readl(GPIO_A, PUPDR); 222 uint32_t idr = gpio_readl(GPIO_A, IDR); 223 /* 15: AF, 14: AF, 13: AF, 12: Analog ... */ 224 /* here AF is the same as Analog and Input mode */ 225 g_assert_cmphex(moder, ==, reset(GPIO_A, MODER)); 226 g_assert_cmphex(odr, ==, reset(GPIO_A, ODR)); 227 g_assert_cmphex(otyper, ==, reset(GPIO_A, OTYPER)); 228 /* 15: pull-up, 14: pull-down, 13: pull-up, 12: neither ... */ 229 g_assert_cmphex(pupdr, ==, reset(GPIO_A, PUPDR)); 230 /* 15 : 1, 14: 0, 13: 1, 12 : reset value ... */ 231 g_assert_cmphex(idr, ==, reset(GPIO_A, IDR)); 232 233 moder = gpio_readl(GPIO_B, MODER); 234 odr = gpio_readl(GPIO_B, ODR); 235 otyper = gpio_readl(GPIO_B, OTYPER); 236 pupdr = gpio_readl(GPIO_B, PUPDR); 237 idr = gpio_readl(GPIO_B, IDR); 238 /* ... 5: Analog, 4: AF, 3: AF, 2: Analog ... */ 239 /* here AF is the same as Analog and Input mode */ 240 g_assert_cmphex(moder, ==, reset(GPIO_B, MODER)); 241 g_assert_cmphex(odr, ==, reset(GPIO_B, ODR)); 242 g_assert_cmphex(otyper, ==, reset(GPIO_B, OTYPER)); 243 /* ... 5: neither, 4: pull-up, 3: neither ... */ 244 g_assert_cmphex(pupdr, ==, reset(GPIO_B, PUPDR)); 245 /* ... 5 : reset value, 4 : 1, 3 : reset value ... */ 246 g_assert_cmphex(idr, ==, reset(GPIO_B, IDR)); 247 248 moder = gpio_readl(GPIO_C, MODER); 249 odr = gpio_readl(GPIO_C, ODR); 250 otyper = gpio_readl(GPIO_C, OTYPER); 251 pupdr = gpio_readl(GPIO_C, PUPDR); 252 idr = gpio_readl(GPIO_C, IDR); 253 /* Analog, same as Input mode*/ 254 g_assert_cmphex(moder, ==, reset(GPIO_C, MODER)); 255 g_assert_cmphex(odr, ==, reset(GPIO_C, ODR)); 256 g_assert_cmphex(otyper, ==, reset(GPIO_C, OTYPER)); 257 /* no pull-up or pull-down */ 258 g_assert_cmphex(pupdr, ==, reset(GPIO_C, PUPDR)); 259 /* reset value */ 260 g_assert_cmphex(idr, ==, reset(GPIO_C, IDR)); 261 262 moder = gpio_readl(GPIO_H, MODER); 263 odr = gpio_readl(GPIO_H, ODR); 264 otyper = gpio_readl(GPIO_H, OTYPER); 265 pupdr = gpio_readl(GPIO_H, PUPDR); 266 idr = gpio_readl(GPIO_H, IDR); 267 /* Analog, same as Input mode */ 268 g_assert_cmphex(moder, ==, reset(GPIO_H, MODER)); 269 g_assert_cmphex(odr, ==, reset(GPIO_H, ODR)); 270 g_assert_cmphex(otyper, ==, reset(GPIO_H, OTYPER)); 271 /* no pull-up or pull-down */ 272 g_assert_cmphex(pupdr, ==, reset(GPIO_H, PUPDR)); 273 /* reset value */ 274 g_assert_cmphex(idr, ==, reset(GPIO_H, IDR)); 275 } 276 277 static void test_gpio_output_mode(const void *data) 278 { 279 /* 280 * Checks that setting a bit in ODR sets the corresponding 281 * GPIO line high : it should set the right bit in IDR 282 * and send an irq to syscfg. 283 * Additionally, it checks that values written to ODR 284 * when not in output mode are stored and not discarded. 285 */ 286 unsigned int pin = test_pin(data); 287 uint32_t gpio = test_gpio_addr(data); 288 unsigned int gpio_id = get_gpio_id(gpio); 289 290 qtest_irq_intercept_in(global_qtest, SYSCFG); 291 292 /* Set a bit in ODR and check nothing happens */ 293 gpio_set_bit(gpio, ODR, pin, 1); 294 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 295 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 296 297 /* Configure the relevant line as output and check the pin is high */ 298 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); 299 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); 300 g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 301 302 /* Reset the bit in ODR and check the pin is low */ 303 gpio_set_bit(gpio, ODR, pin, 0); 304 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 305 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 306 307 /* Clean the test */ 308 gpio_writel(gpio, ODR, reset(gpio, ODR)); 309 gpio_writel(gpio, MODER, reset(gpio, MODER)); 310 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 311 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 312 } 313 314 static void test_gpio_input_mode(const void *data) 315 { 316 /* 317 * Test that setting a line high/low externally sets the 318 * corresponding GPIO line high/low : it should set the 319 * right bit in IDR and send an irq to syscfg. 320 */ 321 unsigned int pin = test_pin(data); 322 uint32_t gpio = test_gpio_addr(data); 323 unsigned int gpio_id = get_gpio_id(gpio); 324 325 qtest_irq_intercept_in(global_qtest, SYSCFG); 326 327 /* Configure a line as input, raise it, and check that the pin is high */ 328 gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); 329 gpio_set_irq(gpio, pin, 1); 330 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); 331 g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 332 333 /* Lower the line and check that the pin is low */ 334 gpio_set_irq(gpio, pin, 0); 335 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 336 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 337 338 /* Clean the test */ 339 gpio_writel(gpio, MODER, reset(gpio, MODER)); 340 disconnect_all_pins(gpio); 341 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 342 } 343 344 static void test_pull_up_pull_down(const void *data) 345 { 346 /* 347 * Test that a floating pin with pull-up sets the pin 348 * high and vice-versa. 349 */ 350 unsigned int pin = test_pin(data); 351 uint32_t gpio = test_gpio_addr(data); 352 unsigned int gpio_id = get_gpio_id(gpio); 353 354 qtest_irq_intercept_in(global_qtest, SYSCFG); 355 356 /* Configure a line as input with pull-up, check the line is set high */ 357 gpio_set_2bits(gpio, MODER, pin, MODER_INPUT); 358 gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLUP); 359 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin)); 360 g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 361 362 /* Configure the line with pull-down, check the line is low */ 363 gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLDOWN); 364 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 365 g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin)); 366 367 /* Clean the test */ 368 gpio_writel(gpio, MODER, reset(gpio, MODER)); 369 gpio_writel(gpio, PUPDR, reset(gpio, PUPDR)); 370 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 371 } 372 373 static void test_push_pull(const void *data) 374 { 375 /* 376 * Test that configuring a line in push-pull output mode 377 * disconnects the pin, that the pin can't be set or reset 378 * externally afterwards. 379 */ 380 unsigned int pin = test_pin(data); 381 uint32_t gpio = test_gpio_addr(data); 382 uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); 383 384 qtest_irq_intercept_in(global_qtest, SYSCFG); 385 386 /* Setting a line high externally, configuring it in push-pull output */ 387 /* And checking the pin was disconnected */ 388 gpio_set_irq(gpio, pin, 1); 389 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); 390 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 391 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 392 393 /* Setting a line low externally, configuring it in push-pull output */ 394 /* And checking the pin was disconnected */ 395 gpio_set_irq(gpio2, pin, 0); 396 gpio_set_bit(gpio2, ODR, pin, 1); 397 gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT); 398 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF); 399 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin)); 400 401 /* Trying to set a push-pull output pin, checking it doesn't work */ 402 gpio_set_irq(gpio, pin, 1); 403 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 404 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 405 406 /* Trying to reset a push-pull output pin, checking it doesn't work */ 407 gpio_set_irq(gpio2, pin, 0); 408 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF); 409 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin)); 410 411 /* Clean the test */ 412 gpio_writel(gpio, MODER, reset(gpio, MODER)); 413 gpio_writel(gpio2, ODR, reset(gpio2, ODR)); 414 gpio_writel(gpio2, MODER, reset(gpio2, MODER)); 415 } 416 417 static void test_open_drain(const void *data) 418 { 419 /* 420 * Test that configuring a line in open-drain output mode 421 * disconnects a pin set high externally and that the pin 422 * can't be set high externally while configured in open-drain. 423 * 424 * However a pin set low externally shouldn't be disconnected, 425 * and it can be set low externally when in open-drain mode. 426 */ 427 unsigned int pin = test_pin(data); 428 uint32_t gpio = test_gpio_addr(data); 429 uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio); 430 431 qtest_irq_intercept_in(global_qtest, SYSCFG); 432 433 /* Setting a line high externally, configuring it in open-drain output */ 434 /* And checking the pin was disconnected */ 435 gpio_set_irq(gpio, pin, 1); 436 gpio_set_bit(gpio, OTYPER, pin, OTYPER_OPEN_DRAIN); 437 gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT); 438 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 439 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 440 441 /* Setting a line low externally, configuring it in open-drain output */ 442 /* And checking the pin wasn't disconnected */ 443 gpio_set_irq(gpio2, pin, 0); 444 gpio_set_bit(gpio2, ODR, pin, 1); 445 gpio_set_bit(gpio2, OTYPER, pin, OTYPER_OPEN_DRAIN); 446 gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT); 447 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin)); 448 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, 449 reset(gpio2, IDR) & ~(1 << pin)); 450 451 /* Trying to set a open-drain output pin, checking it doesn't work */ 452 gpio_set_irq(gpio, pin, 1); 453 g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF); 454 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin)); 455 456 /* Trying to reset a open-drain output pin, checking it works */ 457 gpio_set_bit(gpio, ODR, pin, 1); 458 gpio_set_irq(gpio, pin, 0); 459 g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin)); 460 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, 461 reset(gpio2, IDR) & ~(1 << pin)); 462 463 /* Clean the test */ 464 disconnect_all_pins(gpio2); 465 gpio_writel(gpio2, OTYPER, reset(gpio2, OTYPER)); 466 gpio_writel(gpio2, ODR, reset(gpio2, ODR)); 467 gpio_writel(gpio2, MODER, reset(gpio2, MODER)); 468 g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR)); 469 disconnect_all_pins(gpio); 470 gpio_writel(gpio, OTYPER, reset(gpio, OTYPER)); 471 gpio_writel(gpio, ODR, reset(gpio, ODR)); 472 gpio_writel(gpio, MODER, reset(gpio, MODER)); 473 g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR)); 474 } 475 476 static void test_bsrr_brr(const void *data) 477 { 478 /* 479 * Test that writing a '1' in BSS and BSRR 480 * has the desired effect on ODR. 481 * In BSRR, BSx has priority over BRx. 482 */ 483 unsigned int pin = test_pin(data); 484 uint32_t gpio = test_gpio_addr(data); 485 486 gpio_writel(gpio, BSRR, (1 << pin)); 487 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); 488 489 gpio_writel(gpio, BSRR, (1 << (pin + NUM_GPIO_PINS))); 490 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); 491 492 gpio_writel(gpio, BSRR, (1 << pin)); 493 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); 494 495 gpio_writel(gpio, BRR, (1 << pin)); 496 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); 497 498 /* BSx should have priority over BRx */ 499 gpio_writel(gpio, BSRR, (1 << pin) | (1 << (pin + NUM_GPIO_PINS))); 500 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin)); 501 502 gpio_writel(gpio, BRR, (1 << pin)); 503 g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR)); 504 505 gpio_writel(gpio, ODR, reset(gpio, ODR)); 506 } 507 508 int main(int argc, char **argv) 509 { 510 int ret; 511 512 g_test_init(&argc, &argv, NULL); 513 g_test_set_nonfatal_assertions(); 514 qtest_add_func("stm32l4x5/gpio/test_idr_reset_value", 515 test_idr_reset_value); 516 /* 517 * The inputs for the tests (gpio and pin) can be changed, 518 * but the tests don't work for pins that are high at reset 519 * (GPIOA15, GPIO13 and GPIOB5). 520 * Specifically, rising the pin then checking `get_irq()` 521 * is problematic since the pin was already high. 522 */ 523 qtest_add_data_func("stm32l4x5/gpio/test_gpioc5_output_mode", 524 test_data(GPIO_C, 5), 525 test_gpio_output_mode); 526 qtest_add_data_func("stm32l4x5/gpio/test_gpioh3_output_mode", 527 test_data(GPIO_H, 3), 528 test_gpio_output_mode); 529 qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode1", 530 test_data(GPIO_D, 6), 531 test_gpio_input_mode); 532 qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode2", 533 test_data(GPIO_C, 10), 534 test_gpio_input_mode); 535 qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down1", 536 test_data(GPIO_B, 5), 537 test_pull_up_pull_down); 538 qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down2", 539 test_data(GPIO_F, 1), 540 test_pull_up_pull_down); 541 qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull1", 542 test_data(GPIO_G, 6), 543 test_push_pull); 544 qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull2", 545 test_data(GPIO_H, 3), 546 test_push_pull); 547 qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain1", 548 test_data(GPIO_C, 4), 549 test_open_drain); 550 qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain2", 551 test_data(GPIO_E, 11), 552 test_open_drain); 553 qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr1", 554 test_data(GPIO_A, 12), 555 test_bsrr_brr); 556 qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr2", 557 test_data(GPIO_D, 0), 558 test_bsrr_brr); 559 560 qtest_start("-machine b-l475e-iot01a"); 561 ret = g_test_run(); 562 qtest_end(); 563 564 return ret; 565 } 566