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) 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; }