From bb70158d4e5c5d791f75f82f9dcebb9e310fde8f Mon Sep 17 00:00:00 2001 From: FLyrfors-MI <202259867+FLyrfors-MI@users.noreply.github.com> Date: Thu, 23 Apr 2026 09:10:48 +0200 Subject: [PATCH 1/6] Add gpio_init_mask64 function Fixes #2643 --- src/host/hardware_gpio/gpio.c | 5 +++++ src/host/hardware_gpio/include/hardware/gpio.h | 1 + src/rp2_common/hardware_gpio/gpio.c | 9 +++++++++ src/rp2_common/hardware_gpio/include/hardware/gpio.h | 10 ++++++++++ 4 files changed, 25 insertions(+) diff --git a/src/host/hardware_gpio/gpio.c b/src/host/hardware_gpio/gpio.c index df87664c4..aaec2d812 100644 --- a/src/host/hardware_gpio/gpio.c +++ b/src/host/hardware_gpio/gpio.c @@ -213,6 +213,11 @@ void PICO_WEAK_FUNCTION_IMPL_NAME(gpio_init_mask)(__unused uint gpio_mask) { } +PICO_WEAK_FUNCTION_DEF(gpio_init_mask64) +void PICO_WEAK_FUNCTION_IMPL_NAME(gpio_init_mask64)(__unused uint64_t gpio_mask) { + +} + PICO_WEAK_FUNCTION_DEF(gpio_get) bool PICO_WEAK_FUNCTION_IMPL_NAME(gpio_get)(uint gpio) { check_gpio_param(gpio); diff --git a/src/host/hardware_gpio/include/hardware/gpio.h b/src/host/hardware_gpio/include/hardware/gpio.h index 154cf6394..fecdb1984 100644 --- a/src/host/hardware_gpio/include/hardware/gpio.h +++ b/src/host/hardware_gpio/include/hardware/gpio.h @@ -149,6 +149,7 @@ void gpio_init(uint gpio); void gpio_deinit(uint gpio); void gpio_init_mask(uint gpio_mask); +void gpio_init_mask64(uint64_t gpio_mask); // ---------------------------------------------------------------------------- // Input diff --git a/src/rp2_common/hardware_gpio/gpio.c b/src/rp2_common/hardware_gpio/gpio.c index bd5e0ff4c..8559a5b2f 100644 --- a/src/rp2_common/hardware_gpio/gpio.c +++ b/src/rp2_common/hardware_gpio/gpio.c @@ -290,6 +290,15 @@ void gpio_init_mask(uint gpio_mask) { } } +void gpio_init_mask64(uint64_t gpio_mask) { + for(uint64_t i=0;i>= 1; + } +} + void gpio_set_function_masked(uint32_t gpio_mask, gpio_function_t fn) { for (uint i = 0; i < MIN(NUM_BANK0_GPIOS, 32u); i++) { if (gpio_mask & 1u) { diff --git a/src/rp2_common/hardware_gpio/include/hardware/gpio.h b/src/rp2_common/hardware_gpio/include/hardware/gpio.h index 62477423d..db0e7dbe4 100644 --- a/src/rp2_common/hardware_gpio/include/hardware/gpio.h +++ b/src/rp2_common/hardware_gpio/include/hardware/gpio.h @@ -859,6 +859,16 @@ void gpio_deinit(uint gpio); * \param gpio_mask Mask with 1 bit per GPIO number to initialize */ void gpio_init_mask(uint gpio_mask); + +/*! \brief Initialise multiple GPIOs (enabled I/O and set func to GPIO_FUNC_SIO) + * \ingroup hardware_gpio + * + * Clear the output enable (i.e. set to input). + * Clear any output value. + * + * \param gpio_mask Mask with 1 bit per GPIO number to initialize + */ +void gpio_init_mask64(uint64_t gpio_mask); // ---------------------------------------------------------------------------- // Input // ---------------------------------------------------------------------------- From 90d9c2f7ff030446a4fb4e1ecfe27dc172f63b0a Mon Sep 17 00:00:00 2001 From: FLyrfors-MI <202259867+FLyrfors-MI@users.noreply.github.com> Date: Thu, 23 Apr 2026 09:13:35 +0200 Subject: [PATCH 2/6] Change gpio_init_mask parameter to uint32_t --- src/host/hardware_gpio/gpio.c | 2 +- src/host/hardware_gpio/include/hardware/gpio.h | 2 +- src/rp2_common/hardware_gpio/gpio.c | 4 ++-- src/rp2_common/hardware_gpio/include/hardware/gpio.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/host/hardware_gpio/gpio.c b/src/host/hardware_gpio/gpio.c index aaec2d812..92ad478f8 100644 --- a/src/host/hardware_gpio/gpio.c +++ b/src/host/hardware_gpio/gpio.c @@ -209,7 +209,7 @@ void PICO_WEAK_FUNCTION_IMPL_NAME(gpio_deinit)(uint gpio) { } PICO_WEAK_FUNCTION_DEF(gpio_init_mask) -void PICO_WEAK_FUNCTION_IMPL_NAME(gpio_init_mask)(__unused uint gpio_mask) { +void PICO_WEAK_FUNCTION_IMPL_NAME(gpio_init_mask)(__unused uint32_t gpio_mask) { } diff --git a/src/host/hardware_gpio/include/hardware/gpio.h b/src/host/hardware_gpio/include/hardware/gpio.h index fecdb1984..0e288afd1 100644 --- a/src/host/hardware_gpio/include/hardware/gpio.h +++ b/src/host/hardware_gpio/include/hardware/gpio.h @@ -148,7 +148,7 @@ void gpio_init(uint gpio); void gpio_deinit(uint gpio); -void gpio_init_mask(uint gpio_mask); +void gpio_init_mask(uint32_t gpio_mask); void gpio_init_mask64(uint64_t gpio_mask); // ---------------------------------------------------------------------------- diff --git a/src/rp2_common/hardware_gpio/gpio.c b/src/rp2_common/hardware_gpio/gpio.c index 8559a5b2f..9e5d57df3 100644 --- a/src/rp2_common/hardware_gpio/gpio.c +++ b/src/rp2_common/hardware_gpio/gpio.c @@ -281,8 +281,8 @@ void gpio_deinit(uint gpio) { gpio_set_function(gpio, GPIO_FUNC_NULL); } -void gpio_init_mask(uint gpio_mask) { - for(uint i=0;i Date: Thu, 23 Apr 2026 09:13:56 +0200 Subject: [PATCH 3/6] Clean up gpio.h trailing whitespaces --- .../hardware_gpio/include/hardware/gpio.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rp2_common/hardware_gpio/include/hardware/gpio.h b/src/rp2_common/hardware_gpio/include/hardware/gpio.h index d0c8f44d9..19ba8144e 100644 --- a/src/rp2_common/hardware_gpio/include/hardware/gpio.h +++ b/src/rp2_common/hardware_gpio/include/hardware/gpio.h @@ -41,23 +41,23 @@ extern "C" { * \brief General Purpose Input/Output (GPIO) API * * RP-series microcontrollers have two banks of General Purpose Input / Output (GPIO) pins, which are assigned as follows: - * + * * \if rp2040_specific - * RP2040 has 30 user GPIO pins in bank 0, and 6 QSPI pins in the QSPI bank 1 (QSPI_SS, QSPI_SCLK and QSPI_SD0 to QSPI_SD3). The QSPI - * pins are used to execute code from an external flash device, leaving the User bank (GPIO0 to GPIO29) for the programmer to use. + * RP2040 has 30 user GPIO pins in bank 0, and 6 QSPI pins in the QSPI bank 1 (QSPI_SS, QSPI_SCLK and QSPI_SD0 to QSPI_SD3). The QSPI + * pins are used to execute code from an external flash device, leaving the User bank (GPIO0 to GPIO29) for the programmer to use. * \endif - * + * * \if rp2350_specific - * The number of GPIO pins available depends on the package. There are 30 user GPIOs in bank 0 in the QFN-60 package (RP2350A), or 48 user GPIOs + * The number of GPIO pins available depends on the package. There are 30 user GPIOs in bank 0 in the QFN-60 package (RP2350A), or 48 user GPIOs * in the QFN-80 package. Bank 1 contains the 6 QSPI pins and the USB DP/DM pins. * \endif - * + * * All GPIOs support digital input and output, but a subset can also be used as inputs to the chip’s Analogue to Digital * Converter (ADC). The allocation of GPIO pins to the ADC depends on the packaging. - * + * * RP2040 and RP2350 QFN-60 GPIO, ADC pins are 26-29. * RP2350 QFN-80, ADC pins are 40-47. - * + * * Each GPIO can be controlled directly by software running on the processors, or by a number of other functional blocks. * * The function allocated to each GPIO is selected by calling the \ref gpio_set_function function. \note Not all functions From 969f9615680dfb957641235ab7023172a401e924 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Sat, 9 May 2026 13:45:35 -0500 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Andrew Scheller --- src/rp2_common/hardware_gpio/include/hardware/gpio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rp2_common/hardware_gpio/include/hardware/gpio.h b/src/rp2_common/hardware_gpio/include/hardware/gpio.h index 19ba8144e..f7d28bb5a 100644 --- a/src/rp2_common/hardware_gpio/include/hardware/gpio.h +++ b/src/rp2_common/hardware_gpio/include/hardware/gpio.h @@ -48,8 +48,8 @@ extern "C" { * \endif * * \if rp2350_specific - * The number of GPIO pins available depends on the package. There are 30 user GPIOs in bank 0 in the QFN-60 package (RP2350A), or 48 user GPIOs - * in the QFN-80 package. Bank 1 contains the 6 QSPI pins and the USB DP/DM pins. + * The number of GPIO pins available depends on the package. There are 30 user GPIOs in bank 0 in the QFN-60 package (RP2350A), or 48 user GPIOs + * in the QFN-80 package (RP2350B). Bank 1 contains the 6 QSPI pins and the USB DP/DM pins. * \endif * * All GPIOs support digital input and output, but a subset can also be used as inputs to the chip’s Analogue to Digital From cf64cf52387a8c8422be12cae14773b417a5c4df Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Sat, 9 May 2026 14:24:16 -0500 Subject: [PATCH 5/6] Improve masked function size/performance Early out on no remaining bits in mask for no code cost vs the MIN() version Also optimize the 64 bit methods for NUM_BANK0_GPIOS <= 32 --- src/rp2_common/hardware_gpio/gpio.c | 37 +++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/rp2_common/hardware_gpio/gpio.c b/src/rp2_common/hardware_gpio/gpio.c index 9e5d57df3..69d236898 100644 --- a/src/rp2_common/hardware_gpio/gpio.c +++ b/src/rp2_common/hardware_gpio/gpio.c @@ -282,25 +282,39 @@ void gpio_deinit(uint gpio) { } void gpio_init_mask(uint32_t gpio_mask) { - for(uint32_t i=0;i>= 1; + if (!gpio_mask) break; } } void gpio_init_mask64(uint64_t gpio_mask) { - for(uint64_t i=0;i>= 1; + if (!gpio_mask32) break; + } +#else + for (uint i = 0; i < NUM_BANK0_GPIOS; i++) { + if (gpio_mask & 1u) { gpio_init(i); } gpio_mask >>= 1; + if (!gpio_mask) break; } +#endif } void gpio_set_function_masked(uint32_t gpio_mask, gpio_function_t fn) { - for (uint i = 0; i < MIN(NUM_BANK0_GPIOS, 32u); i++) { + for (uint i = 0; i < NUM_BANK0_GPIOS; i++) { if (gpio_mask & 1u) { gpio_set_function(i, fn); } @@ -309,10 +323,23 @@ void gpio_set_function_masked(uint32_t gpio_mask, gpio_function_t fn) { } void gpio_set_function_masked64(uint64_t gpio_mask, gpio_function_t fn) { - for (uint i = 0; i < MIN(NUM_BANK0_GPIOS, 64u); i++) { +#if NUM_BANK0_GPIOS <= 32 + // code is much smaller in this case, especially for Cortex-M0+ which is convenient since RP2040 has < 32 pins + uint32_t gpio_mask32 = (uint32_t)gpio_mask; + for (uint i = 0; i < NUM_BANK0_GPIOS; i++) { + if (gpio_mask32 & 1u) { + gpio_set_function(i, fn); + } + gpio_mask32 >>= 1; + if (!gpio_mask32) break; + } +#else + for (uint i = 0; i < NUM_BANK0_GPIOS; i++) { if (gpio_mask & 1u) { gpio_set_function(i, fn); } gpio_mask >>= 1; + if (!gpio_mask) break; } +#endif } From b8084d22fb076300067539fe9327c65ad7a3231f Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Sat, 9 May 2026 14:26:53 -0500 Subject: [PATCH 6/6] oops; missed a check --- src/rp2_common/hardware_gpio/gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rp2_common/hardware_gpio/gpio.c b/src/rp2_common/hardware_gpio/gpio.c index 69d236898..26f261ccd 100644 --- a/src/rp2_common/hardware_gpio/gpio.c +++ b/src/rp2_common/hardware_gpio/gpio.c @@ -319,6 +319,7 @@ void gpio_set_function_masked(uint32_t gpio_mask, gpio_function_t fn) { gpio_set_function(i, fn); } gpio_mask >>= 1; + if (!gpio_mask) break; } }