diff options
| -rw-r--r-- | embassy-rp/src/pio.rs | 61 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_async.rs | 20 | ||||
| -rw-r--r-- | examples/rp/src/bin/ws2812-pio.rs | 11 |
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 @@ | |||
| 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}; | 6 | use embassy_rp::gpio::{AnyPin, Pin}; |
| 7 | use embassy_rp::pio::{Pio0, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2}; | 7 | use embassy_rp::pio::{ |
| 8 | Pio0, PioCommon, PioCommonInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, | ||
| 9 | Sm1, Sm2, | ||
| 10 | }; | ||
| 8 | use embassy_rp::pio_instr_util; | 11 | use embassy_rp::pio_instr_util; |
| 9 | use embassy_rp::relocate::RelocatedProgram; | 12 | use embassy_rp::relocate::RelocatedProgram; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | #[embassy_executor::task] | 15 | fn setup_pio_task_sm0(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) { |
| 13 | async 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] | ||
| 43 | async 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::*; | |||
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::gpio::{self, Pin}; | 7 | use embassy_rp::gpio::{self, Pin}; |
| 8 | use embassy_rp::pio::{ | 8 | use embassy_rp::pio::{ |
| 9 | FifoJoin, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstance, | 9 | FifoJoin, PioCommon, PioCommonInstance, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, |
| 10 | ShiftDirection, SmInstance, | ||
| 10 | }; | 11 | }; |
| 11 | use embassy_rp::pio_instr_util; | 12 | use embassy_rp::pio_instr_util; |
| 12 | use embassy_rp::relocate::RelocatedProgram; | 13 | use embassy_rp::relocate::RelocatedProgram; |
| @@ -18,7 +19,7 @@ pub struct Ws2812<P: PioInstance, S: SmInstance> { | |||
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | impl<P: PioInstance, S: SmInstance> Ws2812<P, S> { | 21 | impl<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 { |
