diff --git a/src/rp2040/adc.c b/src/rp2040/adc.c index 2daf380a66..477858c542 100644 --- a/src/rp2040/adc.c +++ b/src/rp2040/adc.c @@ -1,6 +1,6 @@ // ADC 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. @@ -10,6 +10,7 @@ #include "hardware/structs/adc.h" // adc_hw #include "hardware/structs/padsbank0.h" // padsbank0_hw #include "hardware/structs/resets.h" // RESETS_RESET_ADC_BITS +#include "hardware/structs/sysinfo.h" // sysinfo_hw #include "internal.h" // enable_pclock #include "sched.h" // sched_shutdown @@ -21,7 +22,19 @@ DECL_ENUMERATION("pin", "ADC_TEMPERATURE", ADC_TEMPERATURE_PIN); struct gpio_adc gpio_adc_setup(uint32_t pin) { - if ((pin < 26 || pin > 29) && pin != ADC_TEMPERATURE_PIN) + uint32_t min_gpio = 26, max_gpio = 29, adc_temp_chan = 4; +#if CONFIG_MACH_RP2350 + // Check for rp2350b package + if (!is_enabled_pclock(RESETS_RESET_SYSINFO_BITS)) + enable_pclock(RESETS_RESET_SYSINFO_BITS); + if (!(sysinfo_hw->package_sel & SYSINFO_PACKAGE_SEL_BITS)) { + min_gpio = 40; + max_gpio = 47; + adc_temp_chan = 8; + } +#endif + + if ((pin < min_gpio || pin > max_gpio) && pin != ADC_TEMPERATURE_PIN) shutdown("Not a valid ADC pin"); // Enable the ADC @@ -32,10 +45,10 @@ gpio_adc_setup(uint32_t pin) uint8_t chan; if (pin == ADC_TEMPERATURE_PIN) { - chan = 4; + chan = adc_temp_chan; adc_hw->cs |= ADC_CS_TS_EN_BITS; } else { - chan = pin - 26; + chan = pin - min_gpio; padsbank0_hw->io[pin] = PADS_BANK0_GPIO0_OD_BITS; } diff --git a/src/rp2040/gpio.c b/src/rp2040/gpio.c index 98e0778971..a564d1282b 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 0dd393bfed..23d432f63c 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);