Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/host/hardware_gpio/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

}

Expand Down
3 changes: 2 additions & 1 deletion src/host/hardware_gpio/include/hardware/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
42 changes: 39 additions & 3 deletions src/rp2_common/hardware_gpio/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,17 +281,40 @@ 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<NUM_BANK0_GPIOS;i++) {
if (gpio_mask & 1) {
gpio_init(i);
}
gpio_mask >>= 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);
}
Expand All @@ -300,10 +323,23 @@ void gpio_set_function_masked(uint32_t gpio_mask, gpio_function_t fn) {
}
Comment on lines 316 to 324
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only a small optimisation, but is it worth doing:

void gpio_set_function_masked(uint32_t gpio_mask, gpio_function_t fn) {
    if (gpio_mask) {
        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;
        }
    }
}

(or is it better to assume that this function will never be called with an empty gpio_mask?)


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
}
30 changes: 20 additions & 10 deletions src/rp2_common/hardware_gpio/include/hardware/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
// ----------------------------------------------------------------------------
Expand Down