Skip to content

rp2: Fix RP2350 and RP2350B pin alt functions. #17692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Gadgetoid
Copy link
Contributor

@Gadgetoid Gadgetoid commented Jul 16, 2025

RP2350 builds were using the incomplete rp2_af.csv alt function table which broke pins > 31 in RP2350B (48-pin QFN-80) builds:

>>> machine.Pin(31)
Pin(GPIO31, mode=IN, pull=PULL_DOWN)

>>> machine.Pin(32)
Pin(GPIO32, mode=ALT, pull=PULL_DOWN, alt=31)

UART_AUX (alt function 11) and PIO2 (alt function 8, directly conflicting the RP2040 function GPIO_FUNC_GPCK) were also missing.

Changes

boards/*._af.csv: Add separate alt-functions tables for RP2040,
RP2350 and RP2350B.

CMakeLists.txt: Pick correct _af.csv to pass into make-pins.py.

boards/make-pins.py: handle CORESIGHT and XIP_CS1 alt functions.

machine_pin.c: Add PIO2, CORESIGHT and XIP_CS1 alt functions.

Testing

UART_AUX

I tested UART_AUX on an RP2350B board with the following code and a Raspberry Pi Debug Probe:

from machine import Pin, UART

uart = UART(0, 115200, tx=34, rx=35)

print(Pin(34), Pin(35))

The pins are correctly configured as UART_AUX (presumably this always worked?) thanks to the use of UART_FUNCSEL_NUM, but configuring as UART AUX is now enabled in machine.Pin too.

To be totally sure this worked, I set up UART 0 on pins 0 and 1, then changed them with machine.Pin():

from machine import Pin, UART

uart = UART(0, 115200, tx=0, rx=1)

Pin(0, mode=Pin.IN)
Pin(1, mode=Pin.IN)

TX = Pin(34, mode=Pin.ALT, alt=Pin.ALT_UART_AUX)
RX = Pin(35, mode=Pin.ALT, alt=Pin.ALT_UART_AUX)

B-variant Build

I set up a generic B-variant for testing, built against the vanilla RPI_PICO2 board with:

make BOARD=RPI_PICO2 BOARD_VARIANT=B

And the following config:

ports/rp2/boards/RPI_PICO2/mpconfigvariant_B.cmake

set(PICO_BOARD "pico2b")
set(PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR})
set(PICO_NUM_GPIOS 48)
set(MICROPY_BOARD_PINS "${MICROPY_BOARD_DIR}/pins_b.csv")

ports/rp2/boards/RPI_PICO2/pico2b.h:

#include "boards/pico2.h"

// Required to enable 48-pin B variant
#undef PICO_RP2350A

ports/rp2/boards/RPI_PICO2/pins_b.csv:

GP0,GPIO0
GP1,GPIO1
GP2,GPIO2
GP3,GPIO3
GP4,GPIO4
GP5,GPIO5
GP6,GPIO6
GP7,GPIO7
GP8,GPIO8
GP9,GPIO9
GP10,GPIO10
GP11,GPIO11
GP12,GPIO12
GP13,GPIO13
GP14,GPIO14
GP15,GPIO15
GP16,GPIO16
GP17,GPIO17
GP18,GPIO18
GP19,GPIO19
GP20,GPIO20
GP21,GPIO21
GP22,GPIO22
GP25,GPIO25
GP26,GPIO26
GP27,GPIO27
GP28,GPIO28
GP29,GPIO29
GP30,GPIO30
GP31,GPIO31
GP32,GPIO32
GP33,GPIO33
GP34,GPIO34
GP35,GPIO35
GP36,GPIO36
GP37,GPIO37
GP38,GPIO38
GP39,GPIO39
GP40,GPIO40
GP41,GPIO41
GP42,GPIO42
GP43,GPIO43
GP44,GPIO44
GP45,GPIO45
GP46,GPIO46
GP47,GPIO47
LED,GPIO25

Trade-offs and Alternatives

I'm not sure we need CORESIGHT and XIP_CS1 alt functions but they are included for completeness. They needed fixups in make-pins.py because it naively chops the first portion of the signal name off and tries to use that as the GPIO function.

UART_AUX is more interesting, it gives some more UART options on alt-function 11, but also needs special casing to ensure GPIO_FUNC_UART_AUX is used in place of GPIO_FUNC_UART. eg:

const machine_pin_af_obj_t pin_GPIO14_af[] = {
    AF(1, SPI , 1), // SPI1_SCK
    AF(2, UART, 0), // UART0_CTS
    AF(3, I2C , 1), // I2C1_SDA
    AF(4, PWM , 7), // PWM7_A
    AF(5, SIO , 0), // SIO
    AF(6, PIO0, 0), // PIO0
    AF(7, PIO1, 1), // PIO1
    AF(8, PIO2, 2), // PIO2
    AF(9, GPCK, 0), // GPCK_GPIN1
    AF(10, USB , 0), // USB_VBUS_EN
    AF(11, UART_AUX, 0), // UART0_TX
};

The addition of a PIO2 alt function constant might be a separate and important fix for RP2350 variants in general (and may conflict, I need to check that but I've run out of day). Edit: I checked. I don't think anyone has caught this, though there are other outstanding issues with PIO2.

@Gadgetoid Gadgetoid force-pushed the patch-rpi-make-pins branch 3 times, most recently from 8b872c3 to 3848965 Compare July 16, 2025 17:17
@Gadgetoid
Copy link
Contributor Author

Would it be reasonable to include a new GENERIC board for RP2 which mirrors the Pico build, but includes a B variant- or would it be acceptable to hang this B variant off RPI_PICO2 as I've detailed above?

I feel a readily available, generic B variant would make it much easier to test for issues/regressions in this bringup. While I say this with two B-variant boards on my desk that could be added here, a vendor custom board might introduce unknowns.

There is not, and (afaik) will never be, a B-variant RPI_PICO2 so it might be the wrongest place to hang this, but it's very tidy 😆

Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@Gadgetoid
Copy link
Contributor Author

I've also completely overlooked RP2350's Alt Function 0 here, which is used for HSTX.

Right now make-pins.py assumes alt-functions start at 1. I'm not quite sure how to reconcile this.

RP2350 builds were using the incomplete rp2_af.csv alt function table
which broke pins > 31 in RP2350B (48-pin QFN-80) builds:

>>> machine.Pin(31)
Pin(GPIO31, mode=IN, pull=PULL_DOWN)

>>> machine.Pin(32)
Pin(GPIO32, mode=ALT, pull=PULL_DOWN, alt=31)

boards/*._af.csv: Add separate alt-functions tables for RP2040,
                  RP2350 and RP2350B.

CMakeLists.txt: Pick correct _af.csv to pass into make-pins.py.

boards/make-pins.py: handle CORESIGHT and XIP_CS1 alt functions.

machine_pin.c: Add PIO2, CORESIGHT and XIP_CS1 alt functions.

Signed-off-by: Phil Howard <github@gadgetoid.com>
@Gadgetoid Gadgetoid force-pushed the patch-rpi-make-pins branch from 3848965 to 25c09fa Compare July 17, 2025 09:54
@Gadgetoid
Copy link
Contributor Author

Gadgetoid commented Jul 17, 2025

Actually running the test build on an RP2350B doesn't seem to fix the problem I was seeing, but rather makes it worse:

>>> machine.Pin.board.GP3
Pin(GPIO3, mode=ALT, pull=PULL_DOWN, alt=31)

Looks like all pins now default to alt=31 which is GPIO_FUNC_NULL whereas before the first 29 would report as, presumably, SIO... I'm not actually sure which condition is the bug.

Edit: Okay I have fired up vanilla MicroPython on an o.g. Pico and, indeed, alt=31 (GPIO_FUNC_NULL) is the correct reset condition. I'm not sure why what I've changed has fixed that for the lower pins, but it's clear this issue affects RP2350 (non-B variant) boards (such as Pico 2 and Pico 2 W) in myriad ways.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants