aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/pio.rs61
-rw-r--r--examples/rp/src/bin/pio_async.rs20
-rw-r--r--examples/rp/src/bin/ws2812-pio.rs11
3 files changed, 47 insertions, 45 deletions
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs
index 088944b66..b43244da2 100644
--- a/embassy-rp/src/pio.rs
+++ b/embassy-rp/src/pio.rs
@@ -677,26 +677,6 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin {
677 } 677 }
678 } 678 }
679 679
680 fn make_pio_pin(&self, pin: impl Pin) -> PioPin<Self::Pio> {
681 unsafe {
682 pin.io().ctrl().write(|w| {
683 w.set_funcsel(
684 if Self::Pio::PIO_NO == 1 {
685 pac::io::vals::Gpio0ctrlFuncsel::PIO1_0
686 } else {
687 // PIO == 0
688 pac::io::vals::Gpio0ctrlFuncsel::PIO0_0
689 }
690 .0,
691 );
692 });
693 }
694 PioPin {
695 pin_bank: pin.pin_bank(),
696 pio: PhantomData::default(),
697 }
698 }
699
700 fn set_sideset_base_pin(&mut self, base_pin: &PioPin<Self::Pio>) { 680 fn set_sideset_base_pin(&mut self, base_pin: &PioPin<Self::Pio>) {
701 unsafe { 681 unsafe {
702 Self::Pio::PIO 682 Self::Pio::PIO
@@ -815,19 +795,6 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin {
815 ); 795 );
816 } 796 }
817 797
818 fn is_irq_set(&self, irq_no: u8) -> bool {
819 assert!(irq_no < 8);
820 unsafe {
821 let irq_flags = Self::Pio::PIO.irq();
822 irq_flags.read().0 & (1 << irq_no) != 0
823 }
824 }
825
826 fn clear_irq(&mut self, irq_no: usize) {
827 assert!(irq_no < 8);
828 unsafe { Self::Pio::PIO.irq().write(|w| w.set_irq(1 << irq_no)) }
829 }
830
831 fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, Self::Pio, Self> { 798 fn wait_push<'a>(&'a mut self, value: u32) -> FifoOutFuture<'a, Self::Pio, Self> {
832 FifoOutFuture::new(self, value) 799 FifoOutFuture::new(self, value)
833 } 800 }
@@ -990,6 +957,14 @@ pub trait PioCommon: sealed::PioCommon + Sized {
990 write_instr(Self::Pio::PIO, Self::Pio::PIO_NO, start, instrs, MEM_USED_BY_COMMON); 957 write_instr(Self::Pio::PIO, Self::Pio::PIO_NO, start, instrs, MEM_USED_BY_COMMON);
991 } 958 }
992 959
960 fn is_irq_set(&self, irq_no: u8) -> bool {
961 assert!(irq_no < 8);
962 unsafe {
963 let irq_flags = Self::Pio::PIO.irq();
964 irq_flags.read().0 & (1 << irq_no) != 0
965 }
966 }
967
993 fn clear_irq(&mut self, irq_no: usize) { 968 fn clear_irq(&mut self, irq_no: usize) {
994 assert!(irq_no < 8); 969 assert!(irq_no < 8);
995 unsafe { Self::Pio::PIO.irq().write(|w| w.set_irq(1 << irq_no)) } 970 unsafe { Self::Pio::PIO.irq().write(|w| w.set_irq(1 << irq_no)) }
@@ -1015,6 +990,26 @@ pub trait PioCommon: sealed::PioCommon + Sized {
1015 fn get_input_sync_bypass(&self) -> u32 { 990 fn get_input_sync_bypass(&self) -> u32 {
1016 unsafe { Self::Pio::PIO.input_sync_bypass().read() } 991 unsafe { Self::Pio::PIO.input_sync_bypass().read() }
1017 } 992 }
993
994 fn make_pio_pin(&self, pin: impl Pin) -> PioPin<Self::Pio> {
995 unsafe {
996 pin.io().ctrl().write(|w| {
997 w.set_funcsel(
998 if Self::Pio::PIO_NO == 1 {
999 pac::io::vals::Gpio0ctrlFuncsel::PIO1_0
1000 } else {
1001 // PIO == 0
1002 pac::io::vals::Gpio0ctrlFuncsel::PIO0_0
1003 }
1004 .0,
1005 );
1006 });
1007 }
1008 PioPin {
1009 pin_bank: pin.pin_bank(),
1010 pio: PhantomData::default(),
1011 }
1012 }
1018} 1013}
1019 1014
1020// Identifies a specific state machine inside a PIO device 1015// Identifies a specific state machine inside a PIO device
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs
index e616d8c5a..3cfeec71f 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -4,13 +4,15 @@
4use defmt::info; 4use defmt::info;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_rp::gpio::{AnyPin, Pin}; 6use embassy_rp::gpio::{AnyPin, Pin};
7use embassy_rp::pio::{Pio0, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2}; 7use embassy_rp::pio::{
8 Pio0, PioCommon, PioCommonInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0,
9 Sm1, Sm2,
10};
8use embassy_rp::pio_instr_util; 11use embassy_rp::pio_instr_util;
9use embassy_rp::relocate::RelocatedProgram; 12use embassy_rp::relocate::RelocatedProgram;
10use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
11 14
12#[embassy_executor::task] 15fn setup_pio_task_sm0(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
13async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
14 // Setup sm0 16 // Setup sm0
15 17
16 // Send data serially to pin 18 // Send data serially to pin
@@ -23,11 +25,11 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
23 ); 25 );
24 26
25 let relocated = RelocatedProgram::new(&prg.program); 27 let relocated = RelocatedProgram::new(&prg.program);
26 let out_pin = sm.make_pio_pin(pin); 28 let out_pin = pio.make_pio_pin(pin);
27 let pio_pins = [&out_pin]; 29 let pio_pins = [&out_pin];
28 sm.set_out_pins(&pio_pins); 30 sm.set_out_pins(&pio_pins);
29 sm.write_instr(relocated.origin() as usize, relocated.code()); 31 sm.write_instr(relocated.origin() as usize, relocated.code());
30 pio_instr_util::exec_jmp(&mut sm, relocated.origin()); 32 pio_instr_util::exec_jmp(sm, relocated.origin());
31 sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); 33 sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32);
32 sm.set_set_range(0, 1); 34 sm.set_set_range(0, 1);
33 let pio::Wrap { source, target } = relocated.wrap(); 35 let pio::Wrap { source, target } = relocated.wrap();
@@ -35,7 +37,10 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
35 37
36 sm.set_autopull(true); 38 sm.set_autopull(true);
37 sm.set_out_shift_dir(ShiftDirection::Left); 39 sm.set_out_shift_dir(ShiftDirection::Left);
40}
38 41
42#[embassy_executor::task]
43async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>) {
39 sm.set_enable(true); 44 sm.set_enable(true);
40 45
41 let mut v = 0x0f0caffa; 46 let mut v = 0x0f0caffa;
@@ -104,9 +109,10 @@ async fn main(spawner: Spawner) {
104 let p = embassy_rp::init(Default::default()); 109 let p = embassy_rp::init(Default::default());
105 let pio = p.PIO0; 110 let pio = p.PIO0;
106 111
107 let (_, sm0, sm1, sm2, ..) = pio.split(); 112 let (mut pio0, mut sm0, sm1, sm2, ..) = pio.split();
108 113
109 spawner.spawn(pio_task_sm0(sm0, p.PIN_0.degrade())).unwrap(); 114 setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade());
115 spawner.spawn(pio_task_sm0(sm0)).unwrap();
110 spawner.spawn(pio_task_sm1(sm1)).unwrap(); 116 spawner.spawn(pio_task_sm1(sm1)).unwrap();
111 spawner.spawn(pio_task_sm2(sm2)).unwrap(); 117 spawner.spawn(pio_task_sm2(sm2)).unwrap();
112} 118}
diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs
index 5f8a3baee..211c60c49 100644
--- a/examples/rp/src/bin/ws2812-pio.rs
+++ b/examples/rp/src/bin/ws2812-pio.rs
@@ -6,7 +6,8 @@ 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, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstance, 9 FifoJoin, PioCommon, PioCommonInstance, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance,
10 ShiftDirection, SmInstance,
10}; 11};
11use embassy_rp::pio_instr_util; 12use embassy_rp::pio_instr_util;
12use embassy_rp::relocate::RelocatedProgram; 13use embassy_rp::relocate::RelocatedProgram;
@@ -18,7 +19,7 @@ pub struct Ws2812<P: PioInstance, S: SmInstance> {
18} 19}
19 20
20impl<P: PioInstance, S: SmInstance> Ws2812<P, S> { 21impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
21 pub fn new(mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self { 22 pub fn new(pio: PioCommonInstance<P>, mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self {
22 // Setup sm0 23 // Setup sm0
23 24
24 // prepare the PIO program 25 // prepare the PIO program
@@ -53,7 +54,7 @@ impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
53 pio_instr_util::exec_jmp(&mut sm, relocated.origin()); 54 pio_instr_util::exec_jmp(&mut sm, relocated.origin());
54 55
55 // Pin config 56 // Pin config
56 let out_pin = sm.make_pio_pin(pin); 57 let out_pin = pio.make_pio_pin(pin);
57 sm.set_set_pins(&[&out_pin]); 58 sm.set_set_pins(&[&out_pin]);
58 sm.set_sideset_base_pin(&out_pin); 59 sm.set_sideset_base_pin(&out_pin);
59 sm.set_sideset_count(1); 60 sm.set_sideset_count(1);
@@ -115,7 +116,7 @@ async fn main(_spawner: Spawner) {
115 info!("Start"); 116 info!("Start");
116 let p = embassy_rp::init(Default::default()); 117 let p = embassy_rp::init(Default::default());
117 118
118 let (_pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split(); 119 let (pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split();
119 120
120 // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit 121 // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit
121 // feather boards for the 2040 both have one built in. 122 // feather boards for the 2040 both have one built in.
@@ -124,7 +125,7 @@ async fn main(_spawner: Spawner) {
124 125
125 // For the thing plus, use pin 8 126 // For the thing plus, use pin 8
126 // For the feather, use pin 16 127 // For the feather, use pin 16
127 let mut ws2812 = Ws2812::new(sm0, p.PIN_8.degrade()); 128 let mut ws2812 = Ws2812::new(pio0, sm0, p.PIN_8.degrade());
128 129
129 // Loop forever making RGB values and pushing them out to the WS2812. 130 // Loop forever making RGB values and pushing them out to the WS2812.
130 loop { 131 loop {