diff options
| author | pennae <[email protected]> | 2023-05-03 08:15:46 +0200 |
|---|---|---|
| committer | pennae <[email protected]> | 2023-05-03 11:25:43 +0200 |
| commit | 4ccb2bc95aab6202d6f53882a59265427cdd5655 (patch) | |
| tree | 48f8f93043b276ad08a4d3fdea6e4fe2c9a2ca12 | |
| parent | 17e78175a69dc96ea8f71c41949cbc705d82b51a (diff) | |
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.
| -rw-r--r-- | embassy-rp/src/pio.rs | 41 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_async.rs | 7 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_hd44780.rs | 17 | ||||
| -rw-r--r-- | examples/rp/src/bin/ws2812-pio.rs | 7 |
4 files changed, 45 insertions, 27 deletions
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index d05eef04b..21223eafc 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs | |||
| @@ -12,7 +12,7 @@ use pac::io::vals::Gpio0ctrlFuncsel; | |||
| 12 | 12 | ||
| 13 | use crate::dma::{Channel, Transfer, Word}; | 13 | use crate::dma::{Channel, Transfer, Word}; |
| 14 | use crate::gpio::sealed::Pin as SealedPin; | 14 | use crate::gpio::sealed::Pin as SealedPin; |
| 15 | use crate::gpio::{Drive, Pin, Pull, SlewRate}; | 15 | use crate::gpio::{self, Drive, Pull, SlewRate}; |
| 16 | use crate::pac::dma::vals::TreqSel; | 16 | use crate::pac::dma::vals::TreqSel; |
| 17 | use crate::pio::sealed::PioInstance as _; | 17 | use crate::pio::sealed::PioInstance as _; |
| 18 | use crate::{interrupt, pac, peripherals, RegExt}; | 18 | use crate::{interrupt, pac, peripherals, RegExt}; |
| @@ -244,12 +244,12 @@ impl<'d, PIO: PioInstance> Drop for IrqFuture<PIO> { | |||
| 244 | } | 244 | } |
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | pub struct PioPin<PIO: PioInstance> { | 247 | pub struct Pin<PIO: PioInstance> { |
| 248 | pin_bank: u8, | 248 | pin_bank: u8, |
| 249 | pio: PhantomData<PIO>, | 249 | pio: PhantomData<PIO>, |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | impl<PIO: PioInstance> PioPin<PIO> { | 252 | impl<PIO: PioInstance> Pin<PIO> { |
| 253 | /// Set the pin's drive strength. | 253 | /// Set the pin's drive strength. |
| 254 | #[inline] | 254 | #[inline] |
| 255 | pub fn set_drive_strength(&mut self, strength: Drive) { | 255 | pub fn set_drive_strength(&mut self, strength: Drive) { |
| @@ -312,7 +312,7 @@ impl<PIO: PioInstance> PioPin<PIO> { | |||
| 312 | } | 312 | } |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | impl<PIO: PioInstance> SealedPin for PioPin<PIO> { | 315 | impl<PIO: PioInstance> SealedPin for Pin<PIO> { |
| 316 | fn pin_bank(&self) -> u8 { | 316 | fn pin_bank(&self) -> u8 { |
| 317 | self.pin_bank | 317 | self.pin_bank |
| 318 | } | 318 | } |
| @@ -610,7 +610,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { | |||
| 610 | unsafe { Self::this_sm().pinctrl().read().sideset_count() } | 610 | unsafe { Self::this_sm().pinctrl().read().sideset_count() } |
| 611 | } | 611 | } |
| 612 | 612 | ||
| 613 | fn set_sideset_base_pin(&mut self, base_pin: &PioPin<Self::Pio>) { | 613 | fn set_sideset_base_pin(&mut self, base_pin: &Pin<Self::Pio>) { |
| 614 | unsafe { | 614 | unsafe { |
| 615 | Self::this_sm().pinctrl().modify(|w| w.set_sideset_base(base_pin.pin())); | 615 | Self::this_sm().pinctrl().modify(|w| w.set_sideset_base(base_pin.pin())); |
| 616 | } | 616 | } |
| @@ -642,7 +642,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { | |||
| 642 | } | 642 | } |
| 643 | } | 643 | } |
| 644 | 644 | ||
| 645 | fn set_in_base_pin(&mut self, base: &PioPin<Self::Pio>) { | 645 | fn set_in_base_pin(&mut self, base: &Pin<Self::Pio>) { |
| 646 | unsafe { | 646 | unsafe { |
| 647 | Self::this_sm().pinctrl().modify(|w| w.set_in_base(base.pin())); | 647 | Self::this_sm().pinctrl().modify(|w| w.set_in_base(base.pin())); |
| 648 | } | 648 | } |
| @@ -673,7 +673,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { | |||
| 673 | } | 673 | } |
| 674 | } | 674 | } |
| 675 | 675 | ||
| 676 | fn set_out_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&PioPin<Self::Pio>]) { | 676 | fn set_out_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin<Self::Pio>]) { |
| 677 | let count = pins.len(); | 677 | let count = pins.len(); |
| 678 | assert!(count >= 1); | 678 | assert!(count >= 1); |
| 679 | let start = pins[0].pin() as usize; | 679 | let start = pins[0].pin() as usize; |
| @@ -684,7 +684,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { | |||
| 684 | self.set_out_range(start as u8, count as u8); | 684 | self.set_out_range(start as u8, count as u8); |
| 685 | } | 685 | } |
| 686 | 686 | ||
| 687 | fn set_set_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&PioPin<Self::Pio>]) { | 687 | fn set_set_pins<'a, 'b: 'a>(&'a mut self, pins: &'b [&Pin<Self::Pio>]) { |
| 688 | let count = pins.len(); | 688 | let count = pins.len(); |
| 689 | assert!(count >= 1); | 689 | assert!(count >= 1); |
| 690 | let start = pins[0].pin() as usize; | 690 | let start = pins[0].pin() as usize; |
| @@ -890,13 +890,13 @@ impl<'d, PIO: PioInstance> PioCommon<'d, PIO> { | |||
| 890 | /// Register a pin for PIO usage. Pins will be released from the PIO block | 890 | /// Register a pin for PIO usage. Pins will be released from the PIO block |
| 891 | /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`PioCommon`] *and* | 891 | /// (i.e., have their `FUNCSEL` reset to `NULL`) when the [`PioCommon`] *and* |
| 892 | /// all [`PioStateMachine`]s for this block have been dropped. | 892 | /// all [`PioStateMachine`]s for this block have been dropped. |
| 893 | pub fn make_pio_pin(&mut self, pin: impl Pin) -> PioPin<PIO> { | 893 | pub fn make_pio_pin(&mut self, pin: impl PioPin) -> Pin<PIO> { |
| 894 | unsafe { | 894 | unsafe { |
| 895 | pin.io().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL.0)); | 895 | pin.io().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL.0)); |
| 896 | } | 896 | } |
| 897 | // we can be relaxed about this because we're &mut here and nothing is cached | 897 | // we can be relaxed about this because we're &mut here and nothing is cached |
| 898 | PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); | 898 | PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); |
| 899 | PioPin { | 899 | Pin { |
| 900 | pin_bank: pin.pin_bank(), | 900 | pin_bank: pin.pin_bank(), |
| 901 | pio: PhantomData::default(), | 901 | pio: PhantomData::default(), |
| 902 | } | 902 | } |
| @@ -967,6 +967,8 @@ mod sealed { | |||
| 967 | } | 967 | } |
| 968 | } | 968 | } |
| 969 | 969 | ||
| 970 | pub trait PioPin {} | ||
| 971 | |||
| 970 | pub trait PioInstance { | 972 | pub trait PioInstance { |
| 971 | const PIO_NO: u8; | 973 | const PIO_NO: u8; |
| 972 | const PIO: &'static crate::pac::pio::Pio; | 974 | const PIO: &'static crate::pac::pio::Pio; |
| @@ -1003,3 +1005,22 @@ macro_rules! impl_pio { | |||
| 1003 | 1005 | ||
| 1004 | impl_pio!(PIO0, 0, PIO0, PIO0_0); | 1006 | impl_pio!(PIO0, 0, PIO0, PIO0_0); |
| 1005 | impl_pio!(PIO1, 1, PIO1, PIO1_0); | 1007 | impl_pio!(PIO1, 1, PIO1, PIO1_0); |
| 1008 | |||
| 1009 | pub trait PioPin: sealed::PioPin + gpio::Pin {} | ||
| 1010 | |||
| 1011 | macro_rules! impl_pio_pin { | ||
| 1012 | ($( $num:tt )*) => { | ||
| 1013 | $( | ||
| 1014 | paste::paste!{ | ||
| 1015 | impl sealed::PioPin for peripherals::[< PIN_ $num >] {} | ||
| 1016 | impl PioPin for peripherals::[< PIN_ $num >] {} | ||
| 1017 | } | ||
| 1018 | )* | ||
| 1019 | }; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | impl_pio_pin! { | ||
| 1023 | 0 1 2 3 4 5 6 7 8 9 | ||
| 1024 | 10 11 12 13 14 15 16 17 18 19 | ||
| 1025 | 20 21 22 23 24 25 26 27 28 29 | ||
| 1026 | } | ||
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 5fea7034b..154cc6b65 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs | |||
| @@ -3,14 +3,13 @@ | |||
| 3 | #![feature(type_alias_impl_trait)] | 3 | #![feature(type_alias_impl_trait)] |
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_rp::gpio::{AnyPin, Pin}; | ||
| 7 | use embassy_rp::peripherals::PIO0; | 6 | use embassy_rp::peripherals::PIO0; |
| 8 | use embassy_rp::pio::{Pio, PioCommon, PioStateMachine, PioStateMachineInstance, ShiftDirection}; | 7 | use embassy_rp::pio::{Pio, PioCommon, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection}; |
| 9 | use embassy_rp::pio_instr_util; | 8 | use embassy_rp::pio_instr_util; |
| 10 | use embassy_rp::relocate::RelocatedProgram; | 9 | use embassy_rp::relocate::RelocatedProgram; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 11 | ||
| 13 | fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachineInstance<PIO0, 0>, pin: AnyPin) { | 12 | fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachineInstance<PIO0, 0>, pin: impl PioPin) { |
| 14 | // Setup sm0 | 13 | // Setup sm0 |
| 15 | 14 | ||
| 16 | // Send data serially to pin | 15 | // Send data serially to pin |
| @@ -121,7 +120,7 @@ async fn main(spawner: Spawner) { | |||
| 121 | .. | 120 | .. |
| 122 | } = Pio::new(pio); | 121 | } = Pio::new(pio); |
| 123 | 122 | ||
| 124 | setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0.degrade()); | 123 | setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0); |
| 125 | setup_pio_task_sm1(&mut common, &mut sm1); | 124 | setup_pio_task_sm1(&mut common, &mut sm1); |
| 126 | setup_pio_task_sm2(&mut common, &mut sm2); | 125 | setup_pio_task_sm2(&mut common, &mut sm2); |
| 127 | spawner.spawn(pio_task_sm0(sm0)).unwrap(); | 126 | 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 59b4c1f52..6d56bc233 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; | |||
| 6 | 6 | ||
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_rp::dma::{AnyChannel, Channel}; | 8 | use embassy_rp::dma::{AnyChannel, Channel}; |
| 9 | use embassy_rp::gpio::Pin; | ||
| 10 | use embassy_rp::peripherals::PIO0; | 9 | use embassy_rp::peripherals::PIO0; |
| 11 | use embassy_rp::pio::{FifoJoin, Pio, PioStateMachine, PioStateMachineInstance, ShiftDirection}; | 10 | use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection}; |
| 12 | use embassy_rp::pwm::{Config, Pwm}; | 11 | use embassy_rp::pwm::{Config, Pwm}; |
| 13 | use embassy_rp::relocate::RelocatedProgram; | 12 | use embassy_rp::relocate::RelocatedProgram; |
| 14 | use embassy_rp::{into_ref, Peripheral, PeripheralRef}; | 13 | use embassy_rp::{into_ref, Peripheral, PeripheralRef}; |
| @@ -74,13 +73,13 @@ impl<'l> HD44780<'l> { | |||
| 74 | pub async fn new( | 73 | pub async fn new( |
| 75 | pio: impl Peripheral<P = PIO0> + 'l, | 74 | pio: impl Peripheral<P = PIO0> + 'l, |
| 76 | dma: impl Peripheral<P = impl Channel> + 'l, | 75 | dma: impl Peripheral<P = impl Channel> + 'l, |
| 77 | rs: impl Pin, | 76 | rs: impl PioPin, |
| 78 | rw: impl Pin, | 77 | rw: impl PioPin, |
| 79 | e: impl Pin, | 78 | e: impl PioPin, |
| 80 | db4: impl Pin, | 79 | db4: impl PioPin, |
| 81 | db5: impl Pin, | 80 | db5: impl PioPin, |
| 82 | db6: impl Pin, | 81 | db6: impl PioPin, |
| 83 | db7: impl Pin, | 82 | db7: impl PioPin, |
| 84 | ) -> HD44780<'l> { | 83 | ) -> HD44780<'l> { |
| 85 | into_ref!(dma); | 84 | into_ref!(dma); |
| 86 | 85 | ||
diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index 0975559d7..8276fad64 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs | |||
| @@ -4,9 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::gpio::{self, Pin}; | ||
| 8 | use embassy_rp::pio::{ | 7 | use embassy_rp::pio::{ |
| 9 | FifoJoin, Pio, PioCommon, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, | 8 | FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection, |
| 10 | }; | 9 | }; |
| 11 | use embassy_rp::pio_instr_util; | 10 | use embassy_rp::pio_instr_util; |
| 12 | use embassy_rp::relocate::RelocatedProgram; | 11 | use embassy_rp::relocate::RelocatedProgram; |
| @@ -18,7 +17,7 @@ pub struct Ws2812<'d, P: PioInstance, const S: usize> { | |||
| 18 | } | 17 | } |
| 19 | 18 | ||
| 20 | impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { | 19 | impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { |
| 21 | pub fn new(mut pio: PioCommon<'d, P>, mut sm: PioStateMachineInstance<'d, P, S>, pin: gpio::AnyPin) -> Self { | 20 | pub fn new(mut pio: PioCommon<'d, P>, mut sm: PioStateMachineInstance<'d, P, S>, pin: impl PioPin) -> Self { |
| 22 | // Setup sm0 | 21 | // Setup sm0 |
| 23 | 22 | ||
| 24 | // prepare the PIO program | 23 | // prepare the PIO program |
| @@ -124,7 +123,7 @@ async fn main(_spawner: Spawner) { | |||
| 124 | 123 | ||
| 125 | // For the thing plus, use pin 8 | 124 | // For the thing plus, use pin 8 |
| 126 | // For the feather, use pin 16 | 125 | // For the feather, use pin 16 |
| 127 | let mut ws2812 = Ws2812::new(common, sm0, p.PIN_8.degrade()); | 126 | let mut ws2812 = Ws2812::new(common, sm0, p.PIN_8); |
| 128 | 127 | ||
| 129 | // Loop forever making RGB values and pushing them out to the WS2812. | 128 | // Loop forever making RGB values and pushing them out to the WS2812. |
| 130 | loop { | 129 | loop { |
