From 3a3e9fa2f14e6d0aa7403283d1600d1122c74a87 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 15 Dec 2025 21:10:51 -0500 Subject: [PATCH] rp2040: Support rp2350b extra gpios Add support for gpio31 through gpio47 on rp2350, as these pins are available on the rp2350b chips. Signed-off-by: Kevin O'Connor --- src/rp2040/gpio.c | 62 ++++++++++++++++++++++++++++++----------------- src/rp2040/gpio.h | 2 ++ 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/rp2040/gpio.c b/src/rp2040/gpio.c index 98e077897..a564d1282 100644 --- a/src/rp2040/gpio.c +++ b/src/rp2040/gpio.c @@ -1,6 +1,6 @@ // GPIO functions on rp2040 // -// Copyright (C) 2021 Kevin O'Connor +// Copyright (C) 2021-2025 Kevin O'Connor // // This file may be distributed under the terms of the GNU GPLv3 license. @@ -19,12 +19,16 @@ * Pin mappings ****************************************************************/ -DECL_ENUMERATION_RANGE("pin", "gpio0", 0, 30); +#define NUM_GPIO (CONFIG_MACH_RP2040 ? 30 : 48) + +DECL_ENUMERATION_RANGE("pin", "gpio0", 0, NUM_GPIO); // Set the mode and extended function of a pin void gpio_peripheral(uint32_t gpio, int func, int pull_up) { + if (gpio >= NUM_GPIO) + shutdown("Not a valid pin"); padsbank0_hw->io[gpio] = ( PADS_BANK0_GPIO0_IE_BITS | (PADS_BANK0_GPIO0_DRIVE_VALUE_4MA << PADS_BANK0_GPIO0_DRIVE_MSB) @@ -35,9 +39,12 @@ gpio_peripheral(uint32_t gpio, int func, int pull_up) // Convert a register and bit location back to an integer pin identifier static int -mask_to_pin(uint32_t mask) +mask_to_pin(void *sio, uint32_t mask) { - return ffs(mask)-1; + int pin = ffs(mask)-1; + if (CONFIG_MACH_RP2350 && sio != (void*)sio_hw) + pin += 32; + return pin; } @@ -48,22 +55,26 @@ mask_to_pin(uint32_t mask) struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val) { - if (pin >= 30) - goto fail; - struct gpio_out g = { .bit=1<= NUM_GPIO) + shutdown("Not a valid pin"); + void *sio = (void*)sio_hw; + if (CONFIG_MACH_RP2350 && pin >= 32) { + pin -= 32; + sio += 4; + } + struct gpio_out g = { .sio=sio, .bit=1<gpio_oe_set = g.bit; + sio_hw_t *sio = g.sio; + sio->gpio_oe_set = g.bit; gpio_peripheral(pin, 5, 0); irq_restore(flag); } @@ -71,7 +82,8 @@ gpio_out_reset(struct gpio_out g, uint8_t val) void gpio_out_toggle_noirq(struct gpio_out g) { - sio_hw->gpio_togl = g.bit; + sio_hw_t *sio = g.sio; + sio->gpio_togl = g.bit; } void @@ -83,37 +95,43 @@ gpio_out_toggle(struct gpio_out g) void gpio_out_write(struct gpio_out g, uint8_t val) { + sio_hw_t *sio = g.sio; if (val) - sio_hw->gpio_set = g.bit; + sio->gpio_set = g.bit; else - sio_hw->gpio_clr = g.bit; + sio->gpio_clr = g.bit; } struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up) { - if (pin >= 30) - goto fail; - struct gpio_in g = { .bit=1<= NUM_GPIO) + shutdown("Not a valid pin"); + void *sio = (void*)sio_hw; + if (CONFIG_MACH_RP2350 && pin >= 32) { + pin -= 32; + sio += 4; + } + struct gpio_in g = { .sio=sio, .bit=1<gpio_oe_clr = g.bit; + sio_hw_t *sio = g.sio; + sio->gpio_oe_clr = g.bit; irq_restore(flag); } uint8_t gpio_in_read(struct gpio_in g) { - return !!(sio_hw->gpio_in & g.bit); + sio_hw_t *sio = g.sio; + return !!(sio->gpio_in & g.bit); } diff --git a/src/rp2040/gpio.h b/src/rp2040/gpio.h index 0dd393bfe..23d432f63 100644 --- a/src/rp2040/gpio.h +++ b/src/rp2040/gpio.h @@ -4,6 +4,7 @@ #include // uint32_t struct gpio_out { + void *sio; uint32_t bit; }; struct gpio_out gpio_out_setup(uint8_t pin, uint8_t val); @@ -13,6 +14,7 @@ void gpio_out_toggle(struct gpio_out g); void gpio_out_write(struct gpio_out g, uint8_t val); struct gpio_in { + void *sio; uint32_t bit; }; struct gpio_in gpio_in_setup(uint8_t pin, int8_t pull_up);