diff --git a/src/host/hardware_gpio/gpio.c b/src/host/hardware_gpio/gpio.c index df87664c4..92ad478f8 100644 --- a/src/host/hardware_gpio/gpio.c +++ b/src/host/hardware_gpio/gpio.c @@ -209,7 +209,12 @@ 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) { + +} + +PICO_WEAK_FUNCTION_DEF(gpio_init_mask64) +void PICO_WEAK_FUNCTION_IMPL_NAME(gpio_init_mask64)(__unused uint64_t gpio_mask) { } diff --git a/src/host/hardware_gpio/include/hardware/gpio.h b/src/host/hardware_gpio/include/hardware/gpio.h index 154cf6394..0e288afd1 100644 --- a/src/host/hardware_gpio/include/hardware/gpio.h +++ b/src/host/hardware_gpio/include/hardware/gpio.h @@ -148,7 +148,8 @@ 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); // ---------------------------------------------------------------------------- // Input diff --git a/src/rp2_common/hardware_gpio/gpio.c b/src/rp2_common/hardware_gpio/gpio.c index bd5e0ff4c..26f261ccd 100644 --- a/src/rp2_common/hardware_gpio/gpio.c +++ b/src/rp2_common/hardware_gpio/gpio.c @@ -281,29 +281,66 @@ void gpio_deinit(uint gpio) { gpio_set_function(gpio, GPIO_FUNC_NULL); } -void gpio_init_mask(uint gpio_mask) { +void gpio_init_mask(uint32_t gpio_mask) { for(uint i=0;i>= 1; + if (!gpio_mask) break; } } +void gpio_init_mask64(uint64_t gpio_mask) { +#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_init(i); + } + gpio_mask32 >>= 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); } gpio_mask >>= 1; + if (!gpio_mask) break; } } 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 } diff --git a/src/rp2_common/hardware_gpio/include/hardware/gpio.h b/src/rp2_common/hardware_gpio/include/hardware/gpio.h index 62477423d..f7d28bb5a 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 - * 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 * 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 @@ -858,7 +858,17 @@ void gpio_deinit(uint gpio); * * \param gpio_mask Mask with 1 bit per GPIO number to initialize */ -void gpio_init_mask(uint gpio_mask); +void gpio_init_mask(uint32_t 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 // ----------------------------------------------------------------------------