embassy-rs/embassy · error

Invalid PIO_NO: , expected one of 0,1

Error message

Invalid PIO_NO: {}, expected one of 0,1

What it means

Same unreachable-arm panic as error 87 but this is the `#[cfg(not(feature = "_rp235x"))]` arm: on RP2040 only PIO_NO 0 and 1 are valid, so a `_` match arm panics with 'expected one of 0,1'. It indicates an invalid PIO instance number reached the state lookup, normally impossible for well-typed user code.

Solutions

  1. Remove or replace PIO2 usage when building for RP2040 — the chip only has PIO0/PIO1
  2. Align cargo features with your chip (rp2040 vs _rp235x) in embassy-rp dependencies
  3. Check cyw43-pio configuration for a PIO instance that exists on your target
  4. If triggered by valid PIO0/PIO1 code, file a bug — the arm should be unreachable

Example fix

// before (rp2040 build)
let pio = Pio::new(p.PIO2, Irqs);
// after
let pio = Pio::new(p.PIO0, Irqs); // PIO2 is RP235x-only
Defensive patterns

Strategy: validation

Validate before calling

#[cfg(not(feature = "_rp235x"))]
const _: () = assert!(PIO_NO <= 1, "PIO2 requires rp235x features");

Prevention

When it happens

Trigger: A PIO instance with PIO_NO >= 2 used in an RP2040 build — e.g. code written for RP235x (PIO2) compiled for RP2040, or a custom PIO trait implementation with a bad constant.

Common situations: Porting RP235x projects to RP2040 while still referencing PIO2; cargo feature flags not matching the actual chip; downstream crates (cyw43-pio) compiled against the wrong embassy-rp features.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/c6b9f24dff7fa4d4. Report an issue: GitHub.

Appendix: source

Thrown at embassy-rp/src/pio/mod.rs:1647

                    users: AtomicU8::new(0),
                    used_pins: AtomicU64::new(0),
                };

                &STATE_1
            }
            #[cfg(feature = "_rp235x")]
            2 => {
                static STATE_2: State = State {
                    users: AtomicU8::new(0),
                    used_pins: AtomicU64::new(0),
                };

                &STATE_2
            }
            #[cfg(feature = "_rp235x")]
            _ => panic!("Invalid PIO_NO: {}, expected one of 0,1,2", Self::PIO_NO),
            #[cfg(not(feature = "_rp235x"))]
            _ => panic!("Invalid PIO_NO: {}, expected one of 0,1", Self::PIO_NO),
        }
    }
}

/// PIO instance.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + PeripheralType + Sized + Unpin {
    /// Interrupt for this peripheral.
    type Interrupt: crate::interrupt::typelevel::Interrupt;
}

macro_rules! impl_pio {
    ($name:ident, $pio:expr, $pac:ident, $funcsel:ident, $irq:ident) => {
        impl SealedInstance for peripherals::$name {
            const PIO_NO: u8 = $pio;
            const PIO: &'static pac::pio::Pio = &pac::$pac;
            const FUNCSEL: pac::io::vals::Gpio0CtrlFuncsel = pac::io::vals::Gpio0CtrlFuncsel::$funcsel;
        }

View on GitHub (pinned to 463a07b963)