From cd84ea5ff2d8f897305f6546559c15f44b9e8982 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 18 Nov 2024 12:50:25 +0100 Subject: [PATCH 1/2] cpu/sam0_common/periph_gpio_ll: fix gpio_get_port() It turns out that the legacy GPIO API and GPIO LL may disagree on what the GPIO base address is: GPIO LL will use the IOBUS as base address no matter what, the legacy GPIO API will use the APB as base address unless `periph_gpio_fast_read` is used. If the APIs disagree, we need to do impedance matching. (cherry picked from commit 72d0b2b180ede7a2e483f9221d3efae7e7c264a9) --- cpu/sam0_common/include/gpio_ll_arch.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cpu/sam0_common/include/gpio_ll_arch.h b/cpu/sam0_common/include/gpio_ll_arch.h index c2fdb811b36c..0ec02b321dba 100644 --- a/cpu/sam0_common/include/gpio_ll_arch.h +++ b/cpu/sam0_common/include/gpio_ll_arch.h @@ -159,7 +159,15 @@ static inline void gpio_ll_switch_dir_input(gpio_port_t port, uword_t inputs) static inline gpio_port_t gpio_get_port(gpio_t pin) { - return (gpio_port_t)(pin & ~(0x1f)); + /* GPIO LL and legacy GPIO API may disagree on what is the GPIO base + * address if one is using the IOBUS and the other is using the APB for + * access. In this case, we need to do impedance matching by adding the + * offset. */ + const uintptr_t gpio_ll_base = GPIO_PORT_0; + const uintptr_t gpio_legacy_base = GPIO_PIN(0, 0) & ~(0x1f); + uintptr_t addr = (pin & ~(0x1f)); + + return addr + (gpio_ll_base - gpio_legacy_base); } static inline uint8_t gpio_get_pin_num(gpio_t pin) From 779aaedcc5f2cbe321d9b01b5f46b01571b1af54 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 18 Nov 2024 14:27:14 +0100 Subject: [PATCH 2/2] cpu/sam0_common/periph_gpio_ll: fix gpio_query_conf() For the other MCUs, we take the input register state instead of the output register state when the pin is configured as input. Let's do the same here, as this is a lot more useful and intuitive. (cherry picked from commit 0222b8c54cda20baec9a95d5357d18eb958efa1f) --- cpu/sam0_common/periph/gpio_ll.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cpu/sam0_common/periph/gpio_ll.c b/cpu/sam0_common/periph/gpio_ll.c index a8a7c137133a..d375faeda9db 100644 --- a/cpu/sam0_common/periph/gpio_ll.c +++ b/cpu/sam0_common/periph/gpio_ll.c @@ -204,7 +204,12 @@ gpio_conf_t gpio_ll_query_conf(gpio_port_t port, uint8_t pin) } } - result.initial_value = iobus->OUT.reg & pin_mask; + if (result.state == GPIO_INPUT) { + result.initial_value = (gpio_ll_read(port) >> pin) & 1UL; + } + else { + result.initial_value = (gpio_ll_read_output(port) >> pin) & 1UL; + } return result; }