Skip to content

Conversation

@AJMansfield
Copy link
Contributor

@AJMansfield AJMansfield commented Oct 29, 2025

Summary

The existing public pico-sdk API methods for pio_sm_set_pins_with_mask/pio_sm_set_pindirs_with_mask, including the 64-bit variants, do not allow PIO "pin wrapping", i.e. using [30, 31, 0, 1] or [46, 47, 16, 17] as contiguous pin ranges for a PIO program, despite the documented support for this in the underlying hardware.

This patch exposes the internal method that the existing 32- and 64-bit versions of these functions call to in order to skip the way the wrappers "helpfully" perform truncated bit-shifts on their arguments, and uses it to also resolve the outstanding issue with using upper-bank RP2350B pins for PIO.

Resolves: #16199
Closes: #16985

Testing

This still needs to be tested with real RP2350B hardware, not just the more common RP2350A --- as this is a key area where these two chips are different. At the moment I do not have suitable hardware to test on.

@github-actions
Copy link

github-actions bot commented Oct 29, 2025

Code size report:

Reference:  rp2/rp2_dma: Properly close DMA channels. [b24c9cf]
Comparison: rp2/rp2_pio: Fix support for pin wrapping and RP2350B upper-bank pins. [merge of 2db2f53]
  mpy-cross:    +0 +0.000% 
   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

@AJMansfield
Copy link
Contributor Author

@Gadgetoid @sfe-SparkFro @maholli Are any of you able to test if this resolves the issue?

@sfe-SparkFro
Copy link
Contributor

Thanks!

Did rp2.PIO.gpio_base get removed at some point? My previous test code leveraged that. Will see about making a new test tomorrow, if no one else has by then.

@AJMansfield
Copy link
Contributor Author

Did rp2.PIO.gpio_base get removed at some point? My previous test code leveraged that. Will see about making a new test tomorrow, if no one else has by then.

It should be just as it was, only with upper-range GPIO pins now fully functional.

@sfe-SparkFro
Copy link
Contributor

Doh, my mistake! Was building for the Pico 2, which is not the RP2350B, so gpio_base gets #ifdef'd out 🤦

Can confirm that this works with the RP2350B!

@sfe-SparkFro
Copy link
Contributor

@dpgeorge Can this please be considered for v1.27? Or even #16985. We at SparkFun have an upcoming product that really needs #16199 to be resolved. We can of course include it in a release in our fork, though we strive to have minimal differences with our fork where possible. At least some indication of when #16199 will be resolved would be wonderful, thank you!

@dpgeorge dpgeorge added this to the release-1.27.0 milestone Nov 26, 2025
Copy link
Member

@dpgeorge dpgeorge left a comment

Choose a reason for hiding this comment

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

Thanks @AJMansfield for this, it's definitely good to support wrapping.

Some comments above, but overall this looks like a good approach.

@AJMansfield
Copy link
Contributor Author

@sfe-SparkFro I've pushed a new revision that should in theory behave identically, but I still lack means to test it directly. Could you test 198970c and report whether this still resolves the problem?

@dpgeorge
Copy link
Member

Thanks @AJMansfield for updating the PR. It looks really good now, good not to depend on internal APIs.

Copy link
Member

@dpgeorge dpgeorge left a comment

Choose a reason for hiding this comment

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

I tested this on a PIMORONI_PICO_PLUS2_RP2350 (thanks @Gadgetoid !) using the script from #16199 (comment) modified to test with out_base=Pin(20) and out_base=Pin(36). Without the fix in this PR it does not work when using gpio_base(16) (the pin doesn't toggle). But with this PR it does work.

On RP2350B where there are more than 32 pins, using
`pio_sm_set_pins_with_mask()` and `pio_sm_set_pindirs_with_mask()` is not
correct because their arguments are `uint32_t` and higher bits get lost
when `pio.gpio_base(16)` is used.

This commit fixes the issue by using the 64-bit API functions on RP2350B.
It also makes sure pin wrapping is supported, i.e. using [30, 31, 0, 1] or
[46, 47, 16, 17] as contiguous pin ranges for a PIO program.

Fixes issue micropython#16199.

Signed-off-by: Anson Mansfield <[email protected]>
@dpgeorge dpgeorge merged commit 2db2f53 into micropython:master Dec 1, 2025
8 checks passed
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.

PIO does not work on RP2350B with GPIO pin >=32

3 participants