diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index d05eef04..21223eaf 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs @@ -12,7 +12,7 @@ use pac::io::vals::Gpio0ctrlFuncsel; use crate::dma::{Channel, Transfer, Word}; use crate::gpio::sealed::Pin as SealedPin; -use crate::gpio::{Drive, Pin, Pull, SlewRate}; +use crate::gpio::{self, Drive, Pull, SlewRate}; use crate::pac::dma::vals::TreqSel; use crate::pio::sealed::PioInstance as _; use crate::{interrupt, pac, peripherals, RegExt}; @@ -244,12 +244,12 @@ impl<'d, PIO: PioInstance> Drop for IrqFuture { } } -pub struct PioPin { +pub struct Pin { pin_bank: u8, pio: PhantomData, } -impl PioPin { +impl Pin { /// Set the pin's drive strength. #[inline] pub fn set_drive_strength(&mut self, strength: Drive) { @@ -312,7 +312,7 @@ impl PioPin { } } -impl SealedPin for PioPin { +impl SealedPin for Pin { fn pin_bank(&self) -> u8 { self.pin_bank } @@ -610,7 +610,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { unsafe { Self::this_sm().pinctrl().read().sideset_count() } } - fn set_sideset_base_pin(&mut self, base_pin: &PioPin) { + fn set_sideset_base_pin(&mut self, base_pin: &Pin) { unsafe { Self::this_sm().pinctrl().modify(|w| w.set_sideset_base(base_pin.pin())); } @@ -642,7 +642,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { } } - fn set_in_base_pin(&mut self, base: &PioPin) { + fn set_in_base_pin(&mut self, base: &Pin) { unsafe { Self::this_sm().pinctrl().modify(|w| w.set_in_base(base.pin())); } @@ -673,7 +673,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { } } - fn set_out_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&PioPin]) { + fn set_out_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin]) { let count = pins.len(); assert!(count >= 1); let start = pins[0].pin() as usize; @@ -684,7 +684,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { self.set_out_range(start as u8, count as u8); } - fn set_set_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&PioPin]) { + fn set_set_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin]) { let count = pins.len(); assert!(count >= 1); let start = pins[0].pin() as usize; @@ -890,13 +890,13 @@ impl<'d, PIO: PioInstance> PioCommon<'d, PIO> { /// Register a pin for PIO usage. Pins will be released from the PIO block /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`PioCommon`] *and* /// all [`PioStateMachine`]s for this block have been dropped. - pub fn make_pio_pin(&mut self, pin: impl Pin) -> PioPin { + pub fn make_pio_pin(&mut self, pin: impl PioPin) -> Pin { unsafe { pin.io().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL.0)); } // we can be relaxed about this because we're &mut here and nothing is cached PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); - PioPin { + Pin { pin_bank: pin.pin_bank(), pio: PhantomData::default(), } @@ -967,6 +967,8 @@ mod sealed { } } + pub trait PioPin {} + pub trait PioInstance { const PIO_NO: u8; const PIO: &'static crate::pac::pio::Pio; @@ -1003,3 +1005,22 @@ macro_rules! impl_pio { impl_pio!(PIO0, 0, PIO0, PIO0_0); impl_pio!(PIO1, 1, PIO1, PIO1_0); + +pub trait PioPin: sealed::PioPin + gpio::Pin {} + +macro_rules! impl_pio_pin { + ($( $num:tt )*) => { + $( + paste::paste!{ + impl sealed::PioPin for peripherals::[< PIN_ $num >] {} + impl PioPin for peripherals::[< PIN_ $num >] {} + } + )* + }; +} + +impl_pio_pin! { + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 +} diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 5fea7034..154cc6b6 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs @@ -3,14 +3,13 @@ #![feature(type_alias_impl_trait)] use defmt::info; use embassy_executor::Spawner; -use embassy_rp::gpio::{AnyPin, Pin}; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{Pio, PioCommon, PioStateMachine, PioStateMachineInstance, ShiftDirection}; +use embassy_rp::pio::{Pio, PioCommon, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection}; use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; use {defmt_rtt as _, panic_probe as _}; -fn setup_pio_task_sm0(pio: &mut PioCommon, sm: &mut PioStateMachineInstance, pin: AnyPin) { +fn setup_pio_task_sm0(pio: &mut PioCommon, sm: &mut PioStateMachineInstance, pin: impl PioPin) { // Setup sm0 // Send data serially to pin @@ -121,7 +120,7 @@ async fn main(spawner: Spawner) { .. } = Pio::new(pio); - setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0.degrade()); + setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0); setup_pio_task_sm1(&mut common, &mut sm1); setup_pio_task_sm2(&mut common, &mut sm2); spawner.spawn(pio_task_sm0(sm0)).unwrap(); diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 59b4c1f5..6d56bc23 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -6,9 +6,8 @@ use core::fmt::Write; use embassy_executor::Spawner; use embassy_rp::dma::{AnyChannel, Channel}; -use embassy_rp::gpio::Pin; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{FifoJoin, Pio, PioStateMachine, PioStateMachineInstance, ShiftDirection}; +use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection}; use embassy_rp::pwm::{Config, Pwm}; use embassy_rp::relocate::RelocatedProgram; use embassy_rp::{into_ref, Peripheral, PeripheralRef}; @@ -74,13 +73,13 @@ impl<'l> HD44780<'l> { pub async fn new( pio: impl Peripheral

+ 'l, dma: impl Peripheral

+ 'l, - rs: impl Pin, - rw: impl Pin, - e: impl Pin, - db4: impl Pin, - db5: impl Pin, - db6: impl Pin, - db7: impl Pin, + rs: impl PioPin, + rw: impl PioPin, + e: impl PioPin, + db4: impl PioPin, + db5: impl PioPin, + db6: impl PioPin, + db7: impl PioPin, ) -> HD44780<'l> { into_ref!(dma); diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index 0975559d..8276fad6 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs @@ -4,9 +4,8 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_rp::gpio::{self, Pin}; use embassy_rp::pio::{ - FifoJoin, Pio, PioCommon, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, + FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection, }; use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; @@ -18,7 +17,7 @@ pub struct Ws2812<'d, P: PioInstance, const S: usize> { } impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { - pub fn new(mut pio: PioCommon<'d, P>, mut sm: PioStateMachineInstance<'d, P, S>, pin: gpio::AnyPin) -> Self { + pub fn new(mut pio: PioCommon<'d, P>, mut sm: PioStateMachineInstance<'d, P, S>, pin: impl PioPin) -> Self { // Setup sm0 // prepare the PIO program @@ -124,7 +123,7 @@ async fn main(_spawner: Spawner) { // For the thing plus, use pin 8 // For the feather, use pin 16 - let mut ws2812 = Ws2812::new(common, sm0, p.PIN_8.degrade()); + let mut ws2812 = Ws2812::new(common, sm0, p.PIN_8); // Loop forever making RGB values and pushing them out to the WS2812. loop {