rp/pio: add PioPin trait
pio can only access pins in bank 0, so it doesn't make sense to even allow wrapping of other banks' pins.
This commit is contained in:
		@@ -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<PIO> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct PioPin<PIO: PioInstance> {
 | 
			
		||||
pub struct Pin<PIO: PioInstance> {
 | 
			
		||||
    pin_bank: u8,
 | 
			
		||||
    pio: PhantomData<PIO>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<PIO: PioInstance> PioPin<PIO> {
 | 
			
		||||
impl<PIO: PioInstance> Pin<PIO> {
 | 
			
		||||
    /// Set the pin's drive strength.
 | 
			
		||||
    #[inline]
 | 
			
		||||
    pub fn set_drive_strength(&mut self, strength: Drive) {
 | 
			
		||||
@@ -312,7 +312,7 @@ impl<PIO: PioInstance> PioPin<PIO> {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<PIO: PioInstance> SealedPin for PioPin<PIO> {
 | 
			
		||||
impl<PIO: PioInstance> SealedPin for Pin<PIO> {
 | 
			
		||||
    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<Self::Pio>) {
 | 
			
		||||
    fn set_sideset_base_pin(&mut self, base_pin: &Pin<Self::Pio>) {
 | 
			
		||||
        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<Self::Pio>) {
 | 
			
		||||
    fn set_in_base_pin(&mut self, base: &Pin<Self::Pio>) {
 | 
			
		||||
        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<Self::Pio>]) {
 | 
			
		||||
    fn set_out_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin<Self::Pio>]) {
 | 
			
		||||
        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<Self::Pio>]) {
 | 
			
		||||
    fn set_set_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin<Self::Pio>]) {
 | 
			
		||||
        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<PIO> {
 | 
			
		||||
    pub fn make_pio_pin(&mut self, pin: impl PioPin) -> Pin<PIO> {
 | 
			
		||||
        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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<PIO0>, sm: &mut PioStateMachineInstance<PIO0, 0>, pin: AnyPin) {
 | 
			
		||||
fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachineInstance<PIO0, 0>, 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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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<P = PIO0> + 'l,
 | 
			
		||||
        dma: impl Peripheral<P = impl Channel> + '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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user