aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-05-03 08:15:46 +0200
committerpennae <[email protected]>2023-05-03 11:25:43 +0200
commit4ccb2bc95aab6202d6f53882a59265427cdd5655 (patch)
tree48f8f93043b276ad08a4d3fdea6e4fe2c9a2ca12
parent17e78175a69dc96ea8f71c41949cbc705d82b51a (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.rs41
-rw-r--r--examples/rp/src/bin/pio_async.rs7
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs17
-rw-r--r--examples/rp/src/bin/ws2812-pio.rs7
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
13use crate::dma::{Channel, Transfer, Word}; 13use crate::dma::{Channel, Transfer, Word};
14use crate::gpio::sealed::Pin as SealedPin; 14use crate::gpio::sealed::Pin as SealedPin;
15use crate::gpio::{Drive, Pin, Pull, SlewRate}; 15use crate::gpio::{self, Drive, Pull, SlewRate};
16use crate::pac::dma::vals::TreqSel; 16use crate::pac::dma::vals::TreqSel;
17use crate::pio::sealed::PioInstance as _; 17use crate::pio::sealed::PioInstance as _;
18use crate::{interrupt, pac, peripherals, RegExt}; 18use crate::{interrupt, pac, peripherals, RegExt};
@@ -244,12 +244,12 @@ impl<'d, PIO: PioInstance> Drop for IrqFuture<PIO> {
244 } 244 }
245} 245}
246 246
247pub struct PioPin<PIO: PioInstance> { 247pub struct Pin<PIO: PioInstance> {
248 pin_bank: u8, 248 pin_bank: u8,
249 pio: PhantomData<PIO>, 249 pio: PhantomData<PIO>,
250} 250}
251 251
252impl<PIO: PioInstance> PioPin<PIO> { 252impl<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
315impl<PIO: PioInstance> SealedPin for PioPin<PIO> { 315impl<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
1004impl_pio!(PIO0, 0, PIO0, PIO0_0); 1006impl_pio!(PIO0, 0, PIO0, PIO0_0);
1005impl_pio!(PIO1, 1, PIO1, PIO1_0); 1007impl_pio!(PIO1, 1, PIO1, PIO1_0);
1008
1009pub trait PioPin: sealed::PioPin + gpio::Pin {}
1010
1011macro_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
1022impl_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)]
4use defmt::info; 4use defmt::info;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_rp::gpio::{AnyPin, Pin};
7use embassy_rp::peripherals::PIO0; 6use embassy_rp::peripherals::PIO0;
8use embassy_rp::pio::{Pio, PioCommon, PioStateMachine, PioStateMachineInstance, ShiftDirection}; 7use embassy_rp::pio::{Pio, PioCommon, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection};
9use embassy_rp::pio_instr_util; 8use embassy_rp::pio_instr_util;
10use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
11use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
12 11
13fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachineInstance<PIO0, 0>, pin: AnyPin) { 12fn 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
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_rp::dma::{AnyChannel, Channel}; 8use embassy_rp::dma::{AnyChannel, Channel};
9use embassy_rp::gpio::Pin;
10use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::{FifoJoin, Pio, PioStateMachine, PioStateMachineInstance, ShiftDirection}; 10use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection};
12use embassy_rp::pwm::{Config, Pwm}; 11use embassy_rp::pwm::{Config, Pwm};
13use embassy_rp::relocate::RelocatedProgram; 12use embassy_rp::relocate::RelocatedProgram;
14use embassy_rp::{into_ref, Peripheral, PeripheralRef}; 13use 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
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::gpio::{self, Pin};
8use embassy_rp::pio::{ 7use embassy_rp::pio::{
9 FifoJoin, Pio, PioCommon, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, 8 FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, PioStateMachineInstance, ShiftDirection,
10}; 9};
11use embassy_rp::pio_instr_util; 10use embassy_rp::pio_instr_util;
12use embassy_rp::relocate::RelocatedProgram; 11use embassy_rp::relocate::RelocatedProgram;
@@ -18,7 +17,7 @@ pub struct Ws2812<'d, P: PioInstance, const S: usize> {
18} 17}
19 18
20impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { 19impl<'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 {