aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-04-26 19:43:57 +0200
committerpennae <[email protected]>2023-05-02 15:52:50 +0200
commit8839f3f62ab85a1abd066fcbfa15693965e6fae8 (patch)
tree5f7d18370879bb63ead7164d8a6ace0304eace2f
parentac111f40d894dec12106638e47317d13728c52a1 (diff)
rp/pio: PioInstance::split -> Pio::new
not requiring a PioInstance for splitting lets us split from a PeripheralRef or borrowed PIO as well, mirroring every other peripheral in embassy_rp. pio pins still have to be constructed from owned pin instances for now.
-rw-r--r--embassy-rp/src/pio.rs84
-rw-r--r--examples/rp/src/bin/pio_async.rs24
-rw-r--r--examples/rp/src/bin/pio_dma.rs10
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs10
-rw-r--r--examples/rp/src/bin/ws2812-pio.rs18
5 files changed, 82 insertions, 64 deletions
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs
index 27a6068f9..97e97b749 100644
--- a/embassy-rp/src/pio.rs
+++ b/embassy-rp/src/pio.rs
@@ -5,7 +5,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::{Context, Poll}; 5use core::task::{Context, Poll};
6 6
7use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; 7use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
8use embassy_hal_common::PeripheralRef; 8use embassy_hal_common::{Peripheral, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::dma::{Channel, Transfer, Word}; 11use crate::dma::{Channel, Transfer, Word};
@@ -316,16 +316,16 @@ impl<PIO: PioInstance> SealedPin for PioPin<PIO> {
316 } 316 }
317} 317}
318 318
319pub struct PioStateMachineInstance<PIO: PioInstance, SM: SmInstance> { 319pub struct PioStateMachineInstance<'d, PIO: PioInstance, SM: SmInstance> {
320 pio: PhantomData<PIO>, 320 pio: PhantomData<&'d PIO>,
321 sm: PhantomData<SM>, 321 sm: PhantomData<SM>,
322} 322}
323 323
324impl<PIO: PioInstance, SM: SmInstance> sealed::PioStateMachine for PioStateMachineInstance<PIO, SM> { 324impl<'d, PIO: PioInstance, SM: SmInstance> sealed::PioStateMachine for PioStateMachineInstance<'d, PIO, SM> {
325 type Pio = PIO; 325 type Pio = PIO;
326 type Sm = SM; 326 type Sm = SM;
327} 327}
328impl<PIO: PioInstance, SM: SmInstance> PioStateMachine for PioStateMachineInstance<PIO, SM> {} 328impl<'d, PIO: PioInstance, SM: SmInstance> PioStateMachine for PioStateMachineInstance<'d, PIO, SM> {}
329 329
330pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin { 330pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin {
331 fn pio_no(&self) -> u8 { 331 fn pio_no(&self) -> u8 {
@@ -792,21 +792,21 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin {
792 } 792 }
793} 793}
794 794
795pub struct PioCommonInstance<PIO: PioInstance> { 795pub struct PioCommonInstance<'d, PIO: PioInstance> {
796 instructions_used: u32, 796 instructions_used: u32,
797 pio: PhantomData<PIO>, 797 pio: PhantomData<&'d PIO>,
798} 798}
799 799
800pub struct PioInstanceMemory<PIO: PioInstance> { 800pub struct PioInstanceMemory<'d, PIO: PioInstance> {
801 used_mask: u32, 801 used_mask: u32,
802 pio: PhantomData<PIO>, 802 pio: PhantomData<&'d PIO>,
803} 803}
804 804
805impl<PIO: PioInstance> sealed::PioCommon for PioCommonInstance<PIO> { 805impl<'d, PIO: PioInstance> sealed::PioCommon for PioCommonInstance<'d, PIO> {
806 type Pio = PIO; 806 type Pio = PIO;
807} 807}
808impl<PIO: PioInstance> PioCommon for PioCommonInstance<PIO> { 808impl<'d, PIO: PioInstance> PioCommon for PioCommonInstance<'d, PIO> {
809 fn write_instr<I>(&mut self, start: usize, instrs: I) -> PioInstanceMemory<Self::Pio> 809 fn write_instr<I>(&mut self, start: usize, instrs: I) -> PioInstanceMemory<'d, Self::Pio>
810 where 810 where
811 I: Iterator<Item = u16>, 811 I: Iterator<Item = u16>,
812 { 812 {
@@ -903,42 +903,44 @@ impl<const SM_NO: u8> sealed::SmInstance for SmInstanceBase<SM_NO> {
903} 903}
904impl<const SM_NO: u8> SmInstance for SmInstanceBase<SM_NO> {} 904impl<const SM_NO: u8> SmInstance for SmInstanceBase<SM_NO> {}
905 905
906pub trait PioInstance: sealed::PioInstance + Sized + Unpin { 906pub struct Pio<'d, PIO: PioInstance> {
907 fn pio(&self) -> u8 { 907 pub common: PioCommonInstance<'d, PIO>,
908 Self::PIO_NO 908 pub sm0: PioStateMachineInstance<'d, PIO, SmInstanceBase<0>>,
909 } 909 pub sm1: PioStateMachineInstance<'d, PIO, SmInstanceBase<1>>,
910 pub sm2: PioStateMachineInstance<'d, PIO, SmInstanceBase<2>>,
911 pub sm3: PioStateMachineInstance<'d, PIO, SmInstanceBase<3>>,
912}
910 913
911 fn split( 914impl<'d, PIO: PioInstance> Pio<'d, PIO> {
912 self, 915 pub fn new(_pio: impl Peripheral<P = PIO> + 'd) -> Self {
913 ) -> ( 916 Self {
914 PioCommonInstance<Self>, 917 common: PioCommonInstance {
915 PioStateMachineInstance<Self, SmInstanceBase<0>>,
916 PioStateMachineInstance<Self, SmInstanceBase<1>>,
917 PioStateMachineInstance<Self, SmInstanceBase<2>>,
918 PioStateMachineInstance<Self, SmInstanceBase<3>>,
919 ) {
920 (
921 PioCommonInstance {
922 instructions_used: 0, 918 instructions_used: 0,
923 pio: PhantomData::default(), 919 pio: PhantomData,
924 }, 920 },
925 PioStateMachineInstance { 921 sm0: PioStateMachineInstance {
926 sm: PhantomData::default(), 922 sm: PhantomData,
927 pio: PhantomData::default(), 923 pio: PhantomData,
928 }, 924 },
929 PioStateMachineInstance { 925 sm1: PioStateMachineInstance {
930 sm: PhantomData::default(), 926 sm: PhantomData,
931 pio: PhantomData::default(), 927 pio: PhantomData,
932 }, 928 },
933 PioStateMachineInstance { 929 sm2: PioStateMachineInstance {
934 sm: PhantomData::default(), 930 sm: PhantomData,
935 pio: PhantomData::default(), 931 pio: PhantomData,
936 }, 932 },
937 PioStateMachineInstance { 933 sm3: PioStateMachineInstance {
938 sm: PhantomData::default(), 934 sm: PhantomData,
939 pio: PhantomData::default(), 935 pio: PhantomData,
940 }, 936 },
941 ) 937 }
938 }
939}
940
941pub trait PioInstance: sealed::PioInstance + Sized + Unpin {
942 fn pio(&self) -> u8 {
943 Self::PIO_NO
942 } 944 }
943} 945}
944 946
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs
index 16a09327f..69a22f238 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -6,7 +6,7 @@ use embassy_executor::Spawner;
6use embassy_rp::gpio::{AnyPin, Pin}; 6use embassy_rp::gpio::{AnyPin, Pin};
7use embassy_rp::peripherals::PIO0; 7use embassy_rp::peripherals::PIO0;
8use embassy_rp::pio::{ 8use embassy_rp::pio::{
9 PioCommon, PioCommonInstance, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2, 9 Pio, PioCommon, PioCommonInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2,
10}; 10};
11use embassy_rp::pio_instr_util; 11use embassy_rp::pio_instr_util;
12use embassy_rp::relocate::RelocatedProgram; 12use embassy_rp::relocate::RelocatedProgram;
@@ -40,7 +40,7 @@ fn setup_pio_task_sm0(pio: &mut PioCommonInstance<PIO0>, sm: &mut PioStateMachin
40} 40}
41 41
42#[embassy_executor::task] 42#[embassy_executor::task]
43async fn pio_task_sm0(mut sm: PioStateMachineInstance<PIO0, Sm0>) { 43async fn pio_task_sm0(mut sm: PioStateMachineInstance<'static, PIO0, Sm0>) {
44 sm.set_enable(true); 44 sm.set_enable(true);
45 45
46 let mut v = 0x0f0caffa; 46 let mut v = 0x0f0caffa;
@@ -70,7 +70,7 @@ fn setup_pio_task_sm1(pio: &mut PioCommonInstance<PIO0>, sm: &mut PioStateMachin
70} 70}
71 71
72#[embassy_executor::task] 72#[embassy_executor::task]
73async fn pio_task_sm1(mut sm: PioStateMachineInstance<PIO0, Sm1>) { 73async fn pio_task_sm1(mut sm: PioStateMachineInstance<'static, PIO0, Sm1>) {
74 sm.set_enable(true); 74 sm.set_enable(true);
75 loop { 75 loop {
76 let rx = sm.wait_pull().await; 76 let rx = sm.wait_pull().await;
@@ -102,7 +102,7 @@ fn setup_pio_task_sm2(pio: &mut PioCommonInstance<PIO0>, sm: &mut PioStateMachin
102} 102}
103 103
104#[embassy_executor::task] 104#[embassy_executor::task]
105async fn pio_task_sm2(mut sm: PioStateMachineInstance<PIO0, Sm2>) { 105async fn pio_task_sm2(mut sm: PioStateMachineInstance<'static, PIO0, Sm2>) {
106 sm.set_enable(true); 106 sm.set_enable(true);
107 loop { 107 loop {
108 sm.wait_irq(3).await; 108 sm.wait_irq(3).await;
@@ -115,11 +115,17 @@ async fn main(spawner: Spawner) {
115 let p = embassy_rp::init(Default::default()); 115 let p = embassy_rp::init(Default::default());
116 let pio = p.PIO0; 116 let pio = p.PIO0;
117 117
118 let (mut pio0, mut sm0, mut sm1, mut sm2, ..) = pio.split(); 118 let Pio {
119 119 mut common,
120 setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade()); 120 mut sm0,
121 setup_pio_task_sm1(&mut pio0, &mut sm1); 121 mut sm1,
122 setup_pio_task_sm2(&mut pio0, &mut sm2); 122 mut sm2,
123 ..
124 } = Pio::new(pio);
125
126 setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0.degrade());
127 setup_pio_task_sm1(&mut common, &mut sm1);
128 setup_pio_task_sm2(&mut common, &mut sm2);
123 spawner.spawn(pio_task_sm0(sm0)).unwrap(); 129 spawner.spawn(pio_task_sm0(sm0)).unwrap();
124 spawner.spawn(pio_task_sm1(sm1)).unwrap(); 130 spawner.spawn(pio_task_sm1(sm1)).unwrap();
125 spawner.spawn(pio_task_sm2(sm2)).unwrap(); 131 spawner.spawn(pio_task_sm2(sm2)).unwrap();
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs
index ccbc70fe2..33c320b8f 100644
--- a/examples/rp/src/bin/pio_dma.rs
+++ b/examples/rp/src/bin/pio_dma.rs
@@ -4,7 +4,7 @@
4use defmt::info; 4use defmt::info;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_futures::join::join; 6use embassy_futures::join::join;
7use embassy_rp::pio::{PioCommon, PioInstance, PioStateMachine, ShiftDirection}; 7use embassy_rp::pio::{Pio, PioCommon, PioStateMachine, ShiftDirection};
8use embassy_rp::relocate::RelocatedProgram; 8use embassy_rp::relocate::RelocatedProgram;
9use embassy_rp::{pio_instr_util, Peripheral}; 9use embassy_rp::{pio_instr_util, Peripheral};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -19,7 +19,11 @@ fn swap_nibbles(v: u32) -> u32 {
19async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
20 let p = embassy_rp::init(Default::default()); 20 let p = embassy_rp::init(Default::default());
21 let pio = p.PIO0; 21 let pio = p.PIO0;
22 let (mut pio0, mut sm, ..) = pio.split(); 22 let Pio {
23 mut common,
24 sm0: mut sm,
25 ..
26 } = Pio::new(pio);
23 27
24 let prg = pio_proc::pio_asm!( 28 let prg = pio_proc::pio_asm!(
25 ".origin 0", 29 ".origin 0",
@@ -34,7 +38,7 @@ async fn main(_spawner: Spawner) {
34 ); 38 );
35 39
36 let relocated = RelocatedProgram::new(&prg.program); 40 let relocated = RelocatedProgram::new(&prg.program);
37 pio0.write_instr(relocated.origin() as usize, relocated.code()); 41 common.write_instr(relocated.origin() as usize, relocated.code());
38 pio_instr_util::exec_jmp(&mut sm, relocated.origin()); 42 pio_instr_util::exec_jmp(&mut sm, relocated.origin());
39 sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); 43 sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32);
40 let pio::Wrap { source, target } = relocated.wrap(); 44 let pio::Wrap { source, target } = relocated.wrap();
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs
index 1b24897b0..994d4600a 100644
--- a/examples/rp/src/bin/pio_hd44780.rs
+++ b/examples/rp/src/bin/pio_hd44780.rs
@@ -9,7 +9,7 @@ use embassy_rp::dma::{AnyChannel, Channel};
9use embassy_rp::gpio::Pin; 9use embassy_rp::gpio::Pin;
10use embassy_rp::peripherals::PIO0; 10use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::{ 11use embassy_rp::pio::{
12 FifoJoin, PioCommon, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstanceBase, 12 FifoJoin, Pio, PioCommon, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstanceBase,
13}; 13};
14use embassy_rp::pwm::{Config, Pwm}; 14use embassy_rp::pwm::{Config, Pwm};
15use embassy_rp::relocate::RelocatedProgram; 15use embassy_rp::relocate::RelocatedProgram;
@@ -67,14 +67,14 @@ async fn main(_spawner: Spawner) {
67 67
68pub struct HD44780<'l> { 68pub struct HD44780<'l> {
69 dma: PeripheralRef<'l, AnyChannel>, 69 dma: PeripheralRef<'l, AnyChannel>,
70 sm: PioStateMachineInstance<PIO0, SmInstanceBase<0>>, 70 sm: PioStateMachineInstance<'l, PIO0, SmInstanceBase<0>>,
71 71
72 buf: [u8; 40], 72 buf: [u8; 40],
73} 73}
74 74
75impl<'l> HD44780<'l> { 75impl<'l> HD44780<'l> {
76 pub async fn new( 76 pub async fn new(
77 pio: PIO0, 77 pio: impl Peripheral<P = PIO0> + 'l,
78 dma: impl Peripheral<P = impl Channel> + 'l, 78 dma: impl Peripheral<P = impl Channel> + 'l,
79 rs: impl Pin, 79 rs: impl Pin,
80 rw: impl Pin, 80 rw: impl Pin,
@@ -87,7 +87,9 @@ impl<'l> HD44780<'l> {
87 into_ref!(dma); 87 into_ref!(dma);
88 88
89 let db7pin = db7.pin(); 89 let db7pin = db7.pin();
90 let (mut common, mut sm0, ..) = pio.split(); 90 let Pio {
91 mut common, mut sm0, ..
92 } = Pio::new(pio);
91 93
92 // takes command words (<wait:24> <command:4> <0:4>) 94 // takes command words (<wait:24> <command:4> <0:4>)
93 let prg = pio_proc::pio_asm!( 95 let prg = pio_proc::pio_asm!(
diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs
index 592caf244..42c731bd7 100644
--- a/examples/rp/src/bin/ws2812-pio.rs
+++ b/examples/rp/src/bin/ws2812-pio.rs
@@ -6,7 +6,7 @@ use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::gpio::{self, Pin}; 7use embassy_rp::gpio::{self, Pin};
8use embassy_rp::pio::{ 8use embassy_rp::pio::{
9 FifoJoin, PioCommon, PioCommonInstance, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, 9 FifoJoin, Pio, PioCommon, PioCommonInstance, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection,
10 SmInstance, 10 SmInstance,
11}; 11};
12use embassy_rp::pio_instr_util; 12use embassy_rp::pio_instr_util;
@@ -14,12 +14,16 @@ use embassy_rp::relocate::RelocatedProgram;
14use embassy_time::{Duration, Timer}; 14use embassy_time::{Duration, Timer};
15use smart_leds::RGB8; 15use smart_leds::RGB8;
16use {defmt_rtt as _, panic_probe as _}; 16use {defmt_rtt as _, panic_probe as _};
17pub struct Ws2812<P: PioInstance, S: SmInstance> { 17pub struct Ws2812<'d, P: PioInstance, S: SmInstance> {
18 sm: PioStateMachineInstance<P, S>, 18 sm: PioStateMachineInstance<'d, P, S>,
19} 19}
20 20
21impl<P: PioInstance, S: SmInstance> Ws2812<P, S> { 21impl<'d, P: PioInstance, S: SmInstance> Ws2812<'d, P, S> {
22 pub fn new(mut pio: PioCommonInstance<P>, mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self { 22 pub fn new(
23 mut pio: PioCommonInstance<'d, P>,
24 mut sm: PioStateMachineInstance<'d, P, S>,
25 pin: gpio::AnyPin,
26 ) -> Self {
23 // Setup sm0 27 // Setup sm0
24 28
25 // prepare the PIO program 29 // prepare the PIO program
@@ -116,7 +120,7 @@ async fn main(_spawner: Spawner) {
116 info!("Start"); 120 info!("Start");
117 let p = embassy_rp::init(Default::default()); 121 let p = embassy_rp::init(Default::default());
118 122
119 let (pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split(); 123 let Pio { common, sm0, .. } = Pio::new(p.PIO0);
120 124
121 // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit 125 // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit
122 // feather boards for the 2040 both have one built in. 126 // feather boards for the 2040 both have one built in.
@@ -125,7 +129,7 @@ async fn main(_spawner: Spawner) {
125 129
126 // For the thing plus, use pin 8 130 // For the thing plus, use pin 8
127 // For the feather, use pin 16 131 // For the feather, use pin 16
128 let mut ws2812 = Ws2812::new(pio0, sm0, p.PIN_8.degrade()); 132 let mut ws2812 = Ws2812::new(common, sm0, p.PIN_8.degrade());
129 133
130 // Loop forever making RGB values and pushing them out to the WS2812. 134 // Loop forever making RGB values and pushing them out to the WS2812.
131 loop { 135 loop {