diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2020-11-23 19:41:05 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2020-11-23 19:41:05 -0700 |
commit | 60b1e3055c179312eef809fe1d01f58042b64d5f (patch) | |
tree | c620b5ca1eab2d05c9396637db50d0a110328d29 /02-usart/tests/test_gpio.c | |
parent | 2a6ae24ba769892993ec7a173c564f59feb06495 (diff) | |
download | stm32l4-60b1e3055c179312eef809fe1d01f58042b64d5f.tar.gz stm32l4-60b1e3055c179312eef809fe1d01f58042b64d5f.tar.bz2 stm32l4-60b1e3055c179312eef809fe1d01f58042b64d5f.zip |
Add new GPIO subsystem.
This gpio subsystem keeps track of the GPIO pins which
have been reserved and takes care of the housekeeping
with keeping them running.
This gpio subsystem also knows which alternate functions
belong to which pins, so it can automatically configure
the pins for the alternate functions.
Diffstat (limited to '02-usart/tests/test_gpio.c')
-rw-r--r-- | 02-usart/tests/test_gpio.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/02-usart/tests/test_gpio.c b/02-usart/tests/test_gpio.c new file mode 100644 index 0000000..bcb953c --- /dev/null +++ b/02-usart/tests/test_gpio.c @@ -0,0 +1,194 @@ +#include "test_harness.h" + +#include "arch/stm32l4xxx/peripherals/rcc.h" +#include "kern/gpio/gpio_manager.h" + +TEST(gpio_manager, smell) +{ + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + int ec = 5; + gpio_reserved_pin_t some_pin = reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_TRUE(gpio_pin_in_use(GPIO_PIN_PA15)); + + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + release_gpio_pin(some_pin); + + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + return 0; +} + +TEST(gpio_manager, multiplereserve) +{ + int ec; + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_TRUE(ec == 0); + + reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_EQ(ec, GPIO_ERROR_IN_USE); + + return 0; +} + +TEST(gpio_manager, alternate) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_TX, GPIO_PIN_PA2, &ec); + + ASSERT_EQ(ec, 0); + + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_RX, GPIO_PIN_PA15, &ec); + + ASSERT_EQ(ec, 0); + + gpio_port_config_t* gpioa = (gpio_port_config_t*) GPIOA_BASE; + + ASSERT_EQ(regget(gpioa->mode_r, gpio_mode_n(15)), GPIO_MODE_ALTERNATE); + ASSERT_EQ(regget(gpioa->mode_r, gpio_mode_n(2)), GPIO_MODE_ALTERNATE); + + ASSERT_EQ(regget(gpioa->af_rl, gpio_afsel_n(2)), 7); + ASSERT_EQ(regget(gpioa->af_rh, gpio_afsel_n(7)), 3); + + return 0; +} + +TEST(gpio_manager, bad_alternate) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_RX, GPIO_PIN_PA2, &ec); + + ASSERT_EQ(ec, GPIO_ERROR_INVALID_PIN_FOR_ALTERNATE_FUNCTION); + + return 0; +} + +TEST(gpio_manager, bad_pin) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_RX, 99, &ec); + + ASSERT_EQ(ec, GPIO_ERROR_INVALID_PIN); + + return 0; +} + +TEST(gpio_manager, alternate_then_reserve_fail) +{ + int ec; + + /* Pretending to start the USART. */ + gpio_enable_alternate_function( + GPIO_ALTERNATE_FUNCTION_USART2_TX, GPIO_PIN_PA2, &ec); + + ASSERT_EQ(ec, 0); + + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + reserve_gpio_pin(GPIO_PIN_PA2, &opts, &ec); + + ASSERT_EQ(ec, GPIO_ERROR_IN_USE); + + return 0; +} + +TEST(gpio_manager, get_gpio_pin_port_off) +{ + + gpio_port_config_t* cfg; + int off; + get_gpio_pin_port_off(GPIO_PIN_PA5, &cfg, &off); + + ASSERT_EQ(cfg, (void*)(GPIOA_BASE)); + ASSERT_EQ(off, 5); + + return 0; +} + +TEST(gpio_manager, sets_gpio_settings) +{ + gpio_pin_opts_t opts; + int ec; + + opts.mode = GPIO_MODE_OUTPUT; + opts.pull_dir = GPIO_PULL_DIR_NONE; + opts.output_opts.speed = GPIO_OUTPUT_SPEED_VERY_HIGH; + opts.output_opts.type = GPIO_OUTPUT_TYPE_PUSH_PULL; + + reserve_gpio_pin(GPIO_PIN_PA2, &opts, &ec); + ASSERT_EQ(ec, 0); + + gpio_port_config_t* gpioa = (gpio_port_config_t*) GPIOA_BASE; + + ASSERT_EQ(regget(gpioa->mode_r, gpio_mode_n(2)), GPIO_MODE_OUTPUT); + ASSERT_EQ(regget(gpioa->pupd_r, gpio_pupd_n(2)), GPIO_PULL_DIR_NONE); + ASSERT_EQ(regget(gpioa->ospeed_r, gpio_ospeed_n(2)), GPIO_OUTPUT_SPEED_VERY_HIGH); + ASSERT_EQ(regget(gpioa->otype_r, gpio_otype_n(2)), GPIO_OUTPUT_TYPE_PUSH_PULL); + + return 0; +} + +TEST(gpio_manager, gc) +{ + int ec; + gpio_pin_opts_t opts = DEFAULT_GPIO_OPTS_OUTPUT; + + gpio_reserved_pin_t p1 = reserve_gpio_pin(GPIO_PIN_PA0, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + + gpio_reserved_pin_t p2 = reserve_gpio_pin(GPIO_PIN_PA1, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + + gpio_reserved_pin_t p3 = reserve_gpio_pin(GPIO_PIN_PA15, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + + gpio_reserved_pin_t p4 = reserve_gpio_pin(GPIO_PIN_PB3, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + gpio_reserved_pin_t p5 = reserve_gpio_pin(GPIO_PIN_PB1, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + gpio_reserved_pin_t p6 = reserve_gpio_pin(GPIO_PIN_PB0, &opts, &ec); + ASSERT_EQ(ec, 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p1); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p2); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 1); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p3); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p4); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p5); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 1); + + release_gpio_pin(p6); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_A)), 0); + ASSERT_EQ(regget(RCC.ahb2en_r, rcc_gpioen(GPIO_PORT_B)), 0); + + return 0; +} |