aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-07-07 14:31:09 +0000
committerGitHub <[email protected]>2023-07-07 14:31:09 +0000
commit7d68ca1f3b126ed0337eb32991858ad0c6ccc375 (patch)
treecf45eb607ae5aaee38c1d221bb2bd83ac6d5e7ef
parente196387e695da96b44609079a84ede77ef9ba7af (diff)
parent4b63829110b8ef314d22d78c160f54e6ae98634c (diff)
Merge pull request #1627 from pennae/rp-pio-irq
rp/pio: use bind_interrupts for irqs
-rw-r--r--embassy-rp/src/lib.rs1
-rw-r--r--embassy-rp/src/pio.rs78
-rw-r--r--examples/rp/src/bin/pio_async.rs9
-rw-r--r--examples/rp/src/bin/pio_dma.rs11
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs15
-rw-r--r--examples/rp/src/bin/pio_ws2812.rs13
-rw-r--r--examples/rp/src/bin/wifi_ap_tcp_server.rs9
-rw-r--r--examples/rp/src/bin/wifi_blinky.rs9
-rw-r--r--examples/rp/src/bin/wifi_scan.rs9
-rw-r--r--examples/rp/src/bin/wifi_tcp_server.rs9
-rw-r--r--tests/rp/Cargo.toml2
-rw-r--r--tests/rp/src/bin/cyw43-perf.rs10
-rw-r--r--tests/rp/src/bin/pio_irq.rs55
13 files changed, 160 insertions, 70 deletions
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 4fd3cb46a..4f205a16e 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -252,7 +252,6 @@ pub fn init(config: config::Config) -> Peripherals {
252 #[cfg(feature = "time-driver")] 252 #[cfg(feature = "time-driver")]
253 timer::init(); 253 timer::init();
254 dma::init(); 254 dma::init();
255 pio::init();
256 gpio::init(); 255 gpio::init();
257 } 256 }
258 257
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs
index 30648e8ea..72a2f44ed 100644
--- a/embassy-rp/src/pio.rs
+++ b/embassy-rp/src/pio.rs
@@ -16,12 +16,12 @@ use pio::{SideSet, Wrap};
16use crate::dma::{Channel, Transfer, Word}; 16use crate::dma::{Channel, Transfer, Word};
17use crate::gpio::sealed::Pin as SealedPin; 17use crate::gpio::sealed::Pin as SealedPin;
18use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate}; 18use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate};
19use crate::interrupt::InterruptExt; 19use crate::interrupt::typelevel::{Binding, Handler, Interrupt};
20use crate::pac::dma::vals::TreqSel; 20use crate::pac::dma::vals::TreqSel;
21use crate::relocate::RelocatedProgram; 21use crate::relocate::RelocatedProgram;
22use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt}; 22use crate::{pac, peripherals, pio_instr_util, RegExt};
23 23
24struct Wakers([AtomicWaker; 12]); 24pub struct Wakers([AtomicWaker; 12]);
25 25
26impl Wakers { 26impl Wakers {
27 #[inline(always)] 27 #[inline(always)]
@@ -38,10 +38,6 @@ impl Wakers {
38 } 38 }
39} 39}
40 40
41const NEW_AW: AtomicWaker = AtomicWaker::new();
42const PIO_WAKERS_INIT: Wakers = Wakers([NEW_AW; 12]);
43static WAKERS: [Wakers; 2] = [PIO_WAKERS_INIT; 2];
44
45#[derive(Clone, Copy, PartialEq, Eq, Default, Debug)] 41#[derive(Clone, Copy, PartialEq, Eq, Default, Debug)]
46#[cfg_attr(feature = "defmt", derive(defmt::Format))] 42#[cfg_attr(feature = "defmt", derive(defmt::Format))]
47#[repr(u8)] 43#[repr(u8)]
@@ -85,42 +81,20 @@ const RXNEMPTY_MASK: u32 = 1 << 0;
85const TXNFULL_MASK: u32 = 1 << 4; 81const TXNFULL_MASK: u32 = 1 << 4;
86const SMIRQ_MASK: u32 = 1 << 8; 82const SMIRQ_MASK: u32 = 1 << 8;
87 83
88#[cfg(feature = "rt")] 84pub struct InterruptHandler<PIO: Instance> {
89#[interrupt] 85 _pio: PhantomData<PIO>,
90fn PIO0_IRQ_0() {
91 use crate::pac;
92 let ints = pac::PIO0.irqs(0).ints().read().0;
93 for bit in 0..12 {
94 if ints & (1 << bit) != 0 {
95 WAKERS[0].0[bit].wake();
96 }
97 }
98 pac::PIO0.irqs(0).inte().write_clear(|m| m.0 = ints);
99} 86}
100 87
101#[cfg(feature = "rt")] 88impl<PIO: Instance> Handler<PIO::Interrupt> for InterruptHandler<PIO> {
102#[interrupt] 89 unsafe fn on_interrupt() {
103fn PIO1_IRQ_0() { 90 let ints = PIO::PIO.irqs(0).ints().read().0;
104 use crate::pac; 91 for bit in 0..12 {
105 let ints = pac::PIO1.irqs(0).ints().read().0; 92 if ints & (1 << bit) != 0 {
106 for bit in 0..12 { 93 PIO::wakers().0[bit].wake();
107 if ints & (1 << bit) != 0 { 94 }
108 WAKERS[1].0[bit].wake();
109 } 95 }
96 PIO::PIO.irqs(0).inte().write_clear(|m| m.0 = ints);
110 } 97 }
111 pac::PIO1.irqs(0).inte().write_clear(|m| m.0 = ints);
112}
113
114pub(crate) unsafe fn init() {
115 interrupt::PIO0_IRQ_0.disable();
116 interrupt::PIO0_IRQ_0.set_priority(interrupt::Priority::P3);
117 pac::PIO0.irqs(0).inte().write(|m| m.0 = 0);
118 interrupt::PIO0_IRQ_0.enable();
119
120 interrupt::PIO1_IRQ_0.disable();
121 interrupt::PIO1_IRQ_0.set_priority(interrupt::Priority::P3);
122 pac::PIO1.irqs(0).inte().write(|m| m.0 = 0);
123 interrupt::PIO1_IRQ_0.enable();
124} 98}
125 99
126/// Future that waits for TX-FIFO to become writable 100/// Future that waits for TX-FIFO to become writable
@@ -144,7 +118,7 @@ impl<'a, 'd, PIO: Instance, const SM: usize> Future for FifoOutFuture<'a, 'd, PI
144 if self.get_mut().sm_tx.try_push(value) { 118 if self.get_mut().sm_tx.try_push(value) {
145 Poll::Ready(()) 119 Poll::Ready(())
146 } else { 120 } else {
147 WAKERS[PIO::PIO_NO as usize].fifo_out()[SM].register(cx.waker()); 121 PIO::wakers().fifo_out()[SM].register(cx.waker());
148 PIO::PIO.irqs(0).inte().write_set(|m| { 122 PIO::PIO.irqs(0).inte().write_set(|m| {
149 m.0 = TXNFULL_MASK << SM; 123 m.0 = TXNFULL_MASK << SM;
150 }); 124 });
@@ -181,7 +155,7 @@ impl<'a, 'd, PIO: Instance, const SM: usize> Future for FifoInFuture<'a, 'd, PIO
181 if let Some(v) = self.sm_rx.try_pull() { 155 if let Some(v) = self.sm_rx.try_pull() {
182 Poll::Ready(v) 156 Poll::Ready(v)
183 } else { 157 } else {
184 WAKERS[PIO::PIO_NO as usize].fifo_in()[SM].register(cx.waker()); 158 PIO::wakers().fifo_in()[SM].register(cx.waker());
185 PIO::PIO.irqs(0).inte().write_set(|m| { 159 PIO::PIO.irqs(0).inte().write_set(|m| {
186 m.0 = RXNEMPTY_MASK << SM; 160 m.0 = RXNEMPTY_MASK << SM;
187 }); 161 });
@@ -217,7 +191,7 @@ impl<'a, 'd, PIO: Instance> Future for IrqFuture<'a, 'd, PIO> {
217 return Poll::Ready(()); 191 return Poll::Ready(());
218 } 192 }
219 193
220 WAKERS[PIO::PIO_NO as usize].irq()[self.irq_no as usize].register(cx.waker()); 194 PIO::wakers().irq()[self.irq_no as usize].register(cx.waker());
221 PIO::PIO.irqs(0).inte().write_set(|m| { 195 PIO::PIO.irqs(0).inte().write_set(|m| {
222 m.0 = SMIRQ_MASK << self.irq_no; 196 m.0 = SMIRQ_MASK << self.irq_no;
223 }); 197 });
@@ -949,9 +923,11 @@ pub struct Pio<'d, PIO: Instance> {
949} 923}
950 924
951impl<'d, PIO: Instance> Pio<'d, PIO> { 925impl<'d, PIO: Instance> Pio<'d, PIO> {
952 pub fn new(_pio: impl Peripheral<P = PIO> + 'd) -> Self { 926 pub fn new(_pio: impl Peripheral<P = PIO> + 'd, _irq: impl Binding<PIO::Interrupt, InterruptHandler<PIO>>) -> Self {
953 PIO::state().users.store(5, Ordering::Release); 927 PIO::state().users.store(5, Ordering::Release);
954 PIO::state().used_pins.store(0, Ordering::Release); 928 PIO::state().used_pins.store(0, Ordering::Release);
929 PIO::Interrupt::unpend();
930 unsafe { PIO::Interrupt::enable() };
955 Self { 931 Self {
956 common: Common { 932 common: Common {
957 instructions_used: 0, 933 instructions_used: 0,
@@ -1017,6 +993,15 @@ mod sealed {
1017 const PIO_NO: u8; 993 const PIO_NO: u8;
1018 const PIO: &'static crate::pac::pio::Pio; 994 const PIO: &'static crate::pac::pio::Pio;
1019 const FUNCSEL: crate::pac::io::vals::Gpio0ctrlFuncsel; 995 const FUNCSEL: crate::pac::io::vals::Gpio0ctrlFuncsel;
996 type Interrupt: crate::interrupt::typelevel::Interrupt;
997
998 #[inline]
999 fn wakers() -> &'static Wakers {
1000 const NEW_AW: AtomicWaker = AtomicWaker::new();
1001 static WAKERS: Wakers = Wakers([NEW_AW; 12]);
1002
1003 &WAKERS
1004 }
1020 1005
1021 #[inline] 1006 #[inline]
1022 fn state() -> &'static State { 1007 fn state() -> &'static State {
@@ -1033,18 +1018,19 @@ mod sealed {
1033pub trait Instance: sealed::Instance + Sized + Unpin {} 1018pub trait Instance: sealed::Instance + Sized + Unpin {}
1034 1019
1035macro_rules! impl_pio { 1020macro_rules! impl_pio {
1036 ($name:ident, $pio:expr, $pac:ident, $funcsel:ident) => { 1021 ($name:ident, $pio:expr, $pac:ident, $funcsel:ident, $irq:ident) => {
1037 impl sealed::Instance for peripherals::$name { 1022 impl sealed::Instance for peripherals::$name {
1038 const PIO_NO: u8 = $pio; 1023 const PIO_NO: u8 = $pio;
1039 const PIO: &'static pac::pio::Pio = &pac::$pac; 1024 const PIO: &'static pac::pio::Pio = &pac::$pac;
1040 const FUNCSEL: pac::io::vals::Gpio0ctrlFuncsel = pac::io::vals::Gpio0ctrlFuncsel::$funcsel; 1025 const FUNCSEL: pac::io::vals::Gpio0ctrlFuncsel = pac::io::vals::Gpio0ctrlFuncsel::$funcsel;
1026 type Interrupt = crate::interrupt::typelevel::$irq;
1041 } 1027 }
1042 impl Instance for peripherals::$name {} 1028 impl Instance for peripherals::$name {}
1043 }; 1029 };
1044} 1030}
1045 1031
1046impl_pio!(PIO0, 0, PIO0, PIO0_0); 1032impl_pio!(PIO0, 0, PIO0, PIO0_0, PIO0_IRQ_0);
1047impl_pio!(PIO1, 1, PIO1, PIO1_0); 1033impl_pio!(PIO1, 1, PIO1, PIO1_0, PIO1_IRQ_0);
1048 1034
1049pub trait PioPin: sealed::PioPin + gpio::Pin {} 1035pub trait PioPin: sealed::PioPin + gpio::Pin {}
1050 1036
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs
index 79eda1a09..69034c92a 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -3,13 +3,18 @@
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::bind_interrupts;
6use embassy_rp::peripherals::PIO0; 7use embassy_rp::peripherals::PIO0;
7use embassy_rp::pio::{Common, Config, Irq, Pio, PioPin, ShiftDirection, StateMachine}; 8use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine};
8use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
9use fixed::traits::ToFixed; 10use fixed::traits::ToFixed;
10use fixed_macro::types::U56F8; 11use fixed_macro::types::U56F8;
11use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
12 13
14bind_interrupts!(struct Irqs {
15 PIO0_IRQ_0 => InterruptHandler<PIO0>;
16});
17
13fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { 18fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) {
14 // Setup sm0 19 // Setup sm0
15 20
@@ -110,7 +115,7 @@ async fn main(spawner: Spawner) {
110 mut sm1, 115 mut sm1,
111 mut sm2, 116 mut sm2,
112 .. 117 ..
113 } = Pio::new(pio); 118 } = Pio::new(pio, Irqs);
114 119
115 setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0); 120 setup_pio_task_sm0(&mut common, &mut sm0, p.PIN_0);
116 setup_pio_task_sm1(&mut common, &mut sm1); 121 setup_pio_task_sm1(&mut common, &mut sm1);
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs
index 05c0ebb16..80c963556 100644
--- a/examples/rp/src/bin/pio_dma.rs
+++ b/examples/rp/src/bin/pio_dma.rs
@@ -4,13 +4,18 @@
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::{Config, Pio, ShiftConfig, ShiftDirection}; 7use embassy_rp::peripherals::PIO0;
8use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
8use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
9use embassy_rp::Peripheral; 10use embassy_rp::{bind_interrupts, Peripheral};
10use fixed::traits::ToFixed; 11use fixed::traits::ToFixed;
11use fixed_macro::types::U56F8; 12use fixed_macro::types::U56F8;
12use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
13 14
15bind_interrupts!(struct Irqs {
16 PIO0_IRQ_0 => InterruptHandler<PIO0>;
17});
18
14fn swap_nibbles(v: u32) -> u32 { 19fn swap_nibbles(v: u32) -> u32 {
15 let v = (v & 0x0f0f_0f0f) << 4 | (v & 0xf0f0_f0f0) >> 4; 20 let v = (v & 0x0f0f_0f0f) << 4 | (v & 0xf0f0_f0f0) >> 4;
16 let v = (v & 0x00ff_00ff) << 8 | (v & 0xff00_ff00) >> 8; 21 let v = (v & 0x00ff_00ff) << 8 | (v & 0xff00_ff00) >> 8;
@@ -25,7 +30,7 @@ async fn main(_spawner: Spawner) {
25 mut common, 30 mut common,
26 sm0: mut sm, 31 sm0: mut sm,
27 .. 32 ..
28 } = Pio::new(pio); 33 } = Pio::new(pio, Irqs);
29 34
30 let prg = pio_proc::pio_asm!( 35 let prg = pio_proc::pio_asm!(
31 ".origin 0", 36 ".origin 0",
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs
index bfc6c9908..0a4514a66 100644
--- a/examples/rp/src/bin/pio_hd44780.rs
+++ b/examples/rp/src/bin/pio_hd44780.rs
@@ -7,13 +7,19 @@ use core::fmt::Write;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_rp::dma::{AnyChannel, Channel}; 8use embassy_rp::dma::{AnyChannel, Channel};
9use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
10use embassy_rp::pio::{Config, Direction, FifoJoin, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine}; 10use embassy_rp::pio::{
11 Config, Direction, FifoJoin, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
12};
11use embassy_rp::pwm::{self, Pwm}; 13use embassy_rp::pwm::{self, Pwm};
12use embassy_rp::relocate::RelocatedProgram; 14use embassy_rp::relocate::RelocatedProgram;
13use embassy_rp::{into_ref, Peripheral, PeripheralRef}; 15use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef};
14use embassy_time::{Duration, Instant, Timer}; 16use embassy_time::{Duration, Instant, Timer};
15use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
16 18
19bind_interrupts!(pub struct Irqs {
20 PIO0_IRQ_0 => InterruptHandler<PIO0>;
21});
22
17#[embassy_executor::main] 23#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 24async fn main(_spawner: Spawner) {
19 // this test assumes a 2x16 HD44780 display attached as follow: 25 // this test assumes a 2x16 HD44780 display attached as follow:
@@ -37,7 +43,7 @@ async fn main(_spawner: Spawner) {
37 }); 43 });
38 44
39 let mut hd = HD44780::new( 45 let mut hd = HD44780::new(
40 p.PIO0, p.DMA_CH3, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, p.PIN_4, p.PIN_5, p.PIN_6, 46 p.PIO0, Irqs, p.DMA_CH3, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, p.PIN_4, p.PIN_5, p.PIN_6,
41 ) 47 )
42 .await; 48 .await;
43 49
@@ -72,6 +78,7 @@ pub struct HD44780<'l> {
72impl<'l> HD44780<'l> { 78impl<'l> HD44780<'l> {
73 pub async fn new( 79 pub async fn new(
74 pio: impl Peripheral<P = PIO0> + 'l, 80 pio: impl Peripheral<P = PIO0> + 'l,
81 irq: Irqs,
75 dma: impl Peripheral<P = impl Channel> + 'l, 82 dma: impl Peripheral<P = impl Channel> + 'l,
76 rs: impl PioPin, 83 rs: impl PioPin,
77 rw: impl PioPin, 84 rw: impl PioPin,
@@ -88,7 +95,7 @@ impl<'l> HD44780<'l> {
88 mut irq0, 95 mut irq0,
89 mut sm0, 96 mut sm0,
90 .. 97 ..
91 } = Pio::new(pio); 98 } = Pio::new(pio, irq);
92 99
93 // takes command words (<wait:24> <command:4> <0:4>) 100 // takes command words (<wait:24> <command:4> <0:4>)
94 let prg = pio_proc::pio_asm!( 101 let prg = pio_proc::pio_asm!(
diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs
index 26422421f..4a111e7aa 100644
--- a/examples/rp/src/bin/pio_ws2812.rs
+++ b/examples/rp/src/bin/pio_ws2812.rs
@@ -5,15 +5,22 @@
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::dma::{AnyChannel, Channel}; 7use embassy_rp::dma::{AnyChannel, Channel};
8use embassy_rp::pio::{Common, Config, FifoJoin, Instance, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine}; 8use embassy_rp::peripherals::PIO0;
9use embassy_rp::pio::{
10 Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
11};
9use embassy_rp::relocate::RelocatedProgram; 12use embassy_rp::relocate::RelocatedProgram;
10use embassy_rp::{clocks, into_ref, Peripheral, PeripheralRef}; 13use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef};
11use embassy_time::{Duration, Timer}; 14use embassy_time::{Duration, Timer};
12use fixed::types::U24F8; 15use fixed::types::U24F8;
13use fixed_macro::fixed; 16use fixed_macro::fixed;
14use smart_leds::RGB8; 17use smart_leds::RGB8;
15use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
16 19
20bind_interrupts!(struct Irqs {
21 PIO0_IRQ_0 => InterruptHandler<PIO0>;
22});
23
17pub struct Ws2812<'d, P: Instance, const S: usize, const N: usize> { 24pub struct Ws2812<'d, P: Instance, const S: usize, const N: usize> {
18 dma: PeripheralRef<'d, AnyChannel>, 25 dma: PeripheralRef<'d, AnyChannel>,
19 sm: StateMachine<'d, P, S>, 26 sm: StateMachine<'d, P, S>,
@@ -123,7 +130,7 @@ async fn main(_spawner: Spawner) {
123 info!("Start"); 130 info!("Start");
124 let p = embassy_rp::init(Default::default()); 131 let p = embassy_rp::init(Default::default());
125 132
126 let Pio { mut common, sm0, .. } = Pio::new(p.PIO0); 133 let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs);
127 134
128 // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit 135 // This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit
129 // feather boards for the 2040 both have one built in. 136 // feather boards for the 2040 both have one built in.
diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs
index 310e84d92..3e41f83be 100644
--- a/examples/rp/src/bin/wifi_ap_tcp_server.rs
+++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs
@@ -11,14 +11,19 @@ use defmt::*;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_net::tcp::TcpSocket; 12use embassy_net::tcp::TcpSocket;
13use embassy_net::{Config, Stack, StackResources}; 13use embassy_net::{Config, Stack, StackResources};
14use embassy_rp::bind_interrupts;
14use embassy_rp::gpio::{Level, Output}; 15use embassy_rp::gpio::{Level, Output};
15use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 16use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0};
16use embassy_rp::pio::Pio; 17use embassy_rp::pio::{InterruptHandler, Pio};
17use embassy_time::Duration; 18use embassy_time::Duration;
18use embedded_io::asynch::Write; 19use embedded_io::asynch::Write;
19use static_cell::make_static; 20use static_cell::make_static;
20use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
21 22
23bind_interrupts!(struct Irqs {
24 PIO0_IRQ_0 => InterruptHandler<PIO0>;
25});
26
22#[embassy_executor::task] 27#[embassy_executor::task]
23async fn wifi_task( 28async fn wifi_task(
24 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, 29 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
@@ -49,7 +54,7 @@ async fn main(spawner: Spawner) {
49 54
50 let pwr = Output::new(p.PIN_23, Level::Low); 55 let pwr = Output::new(p.PIN_23, Level::Low);
51 let cs = Output::new(p.PIN_25, Level::High); 56 let cs = Output::new(p.PIN_25, Level::High);
52 let mut pio = Pio::new(p.PIO0); 57 let mut pio = Pio::new(p.PIO0, Irqs);
53 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 58 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
54 59
55 let state = make_static!(cyw43::State::new()); 60 let state = make_static!(cyw43::State::new());
diff --git a/examples/rp/src/bin/wifi_blinky.rs b/examples/rp/src/bin/wifi_blinky.rs
index bbcb1b5ec..6eb207af6 100644
--- a/examples/rp/src/bin/wifi_blinky.rs
+++ b/examples/rp/src/bin/wifi_blinky.rs
@@ -5,13 +5,18 @@
5use cyw43_pio::PioSpi; 5use cyw43_pio::PioSpi;
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_rp::bind_interrupts;
8use embassy_rp::gpio::{Level, Output}; 9use embassy_rp::gpio::{Level, Output};
9use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 10use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0};
10use embassy_rp::pio::Pio; 11use embassy_rp::pio::{InterruptHandler, Pio};
11use embassy_time::{Duration, Timer}; 12use embassy_time::{Duration, Timer};
12use static_cell::make_static; 13use static_cell::make_static;
13use {defmt_rtt as _, panic_probe as _}; 14use {defmt_rtt as _, panic_probe as _};
14 15
16bind_interrupts!(struct Irqs {
17 PIO0_IRQ_0 => InterruptHandler<PIO0>;
18});
19
15#[embassy_executor::task] 20#[embassy_executor::task]
16async fn wifi_task( 21async fn wifi_task(
17 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, 22 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
@@ -34,7 +39,7 @@ async fn main(spawner: Spawner) {
34 39
35 let pwr = Output::new(p.PIN_23, Level::Low); 40 let pwr = Output::new(p.PIN_23, Level::Low);
36 let cs = Output::new(p.PIN_25, Level::High); 41 let cs = Output::new(p.PIN_25, Level::High);
37 let mut pio = Pio::new(p.PIO0); 42 let mut pio = Pio::new(p.PIO0, Irqs);
38 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 43 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
39 44
40 let state = make_static!(cyw43::State::new()); 45 let state = make_static!(cyw43::State::new());
diff --git a/examples/rp/src/bin/wifi_scan.rs b/examples/rp/src/bin/wifi_scan.rs
index 391e12282..aef18aa24 100644
--- a/examples/rp/src/bin/wifi_scan.rs
+++ b/examples/rp/src/bin/wifi_scan.rs
@@ -10,12 +10,17 @@ use cyw43_pio::PioSpi;
10use defmt::*; 10use defmt::*;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_net::Stack; 12use embassy_net::Stack;
13use embassy_rp::bind_interrupts;
13use embassy_rp::gpio::{Level, Output}; 14use embassy_rp::gpio::{Level, Output};
14use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 15use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0};
15use embassy_rp::pio::Pio; 16use embassy_rp::pio::{InterruptHandler, Pio};
16use static_cell::make_static; 17use static_cell::make_static;
17use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
18 19
20bind_interrupts!(struct Irqs {
21 PIO0_IRQ_0 => InterruptHandler<PIO0>;
22});
23
19#[embassy_executor::task] 24#[embassy_executor::task]
20async fn wifi_task( 25async fn wifi_task(
21 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, 26 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
@@ -46,7 +51,7 @@ async fn main(spawner: Spawner) {
46 51
47 let pwr = Output::new(p.PIN_23, Level::Low); 52 let pwr = Output::new(p.PIN_23, Level::Low);
48 let cs = Output::new(p.PIN_25, Level::High); 53 let cs = Output::new(p.PIN_25, Level::High);
49 let mut pio = Pio::new(p.PIO0); 54 let mut pio = Pio::new(p.PIO0, Irqs);
50 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 55 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
51 56
52 let state = make_static!(cyw43::State::new()); 57 let state = make_static!(cyw43::State::new());
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs
index 197535f45..4fce74a66 100644
--- a/examples/rp/src/bin/wifi_tcp_server.rs
+++ b/examples/rp/src/bin/wifi_tcp_server.rs
@@ -11,14 +11,19 @@ use defmt::*;
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_net::tcp::TcpSocket; 12use embassy_net::tcp::TcpSocket;
13use embassy_net::{Config, Stack, StackResources}; 13use embassy_net::{Config, Stack, StackResources};
14use embassy_rp::bind_interrupts;
14use embassy_rp::gpio::{Level, Output}; 15use embassy_rp::gpio::{Level, Output};
15use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 16use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0};
16use embassy_rp::pio::Pio; 17use embassy_rp::pio::{InterruptHandler, Pio};
17use embassy_time::Duration; 18use embassy_time::Duration;
18use embedded_io::asynch::Write; 19use embedded_io::asynch::Write;
19use static_cell::make_static; 20use static_cell::make_static;
20use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
21 22
23bind_interrupts!(struct Irqs {
24 PIO0_IRQ_0 => InterruptHandler<PIO0>;
25});
26
22const WIFI_NETWORK: &str = "EmbassyTest"; 27const WIFI_NETWORK: &str = "EmbassyTest";
23const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; 28const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
24 29
@@ -52,7 +57,7 @@ async fn main(spawner: Spawner) {
52 57
53 let pwr = Output::new(p.PIN_23, Level::Low); 58 let pwr = Output::new(p.PIN_23, Level::Low);
54 let cs = Output::new(p.PIN_25, Level::High); 59 let cs = Output::new(p.PIN_25, Level::High);
55 let mut pio = Pio::new(p.PIO0); 60 let mut pio = Pio::new(p.PIO0, Irqs);
56 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 61 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
57 62
58 let state = make_static!(cyw43::State::new()); 63 let state = make_static!(cyw43::State::new());
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index 368d4acf9..f2c902787 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -29,6 +29,8 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
29embedded-io = { version = "0.4.0", features = ["async"] } 29embedded-io = { version = "0.4.0", features = ["async"] }
30embedded-storage = { version = "0.3" } 30embedded-storage = { version = "0.3" }
31static_cell = { version = "1.1", features = ["nightly"]} 31static_cell = { version = "1.1", features = ["nightly"]}
32pio = "0.2"
33pio-proc = "0.2"
32 34
33[profile.dev] 35[profile.dev]
34debug = 2 36debug = 2
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs
index 1ecaab266..bc127e2e5 100644
--- a/tests/rp/src/bin/cyw43-perf.rs
+++ b/tests/rp/src/bin/cyw43-perf.rs
@@ -12,12 +12,16 @@ use embassy_net::tcp::TcpSocket;
12use embassy_net::{Config, Ipv4Address, Stack, StackResources}; 12use embassy_net::{Config, Ipv4Address, Stack, StackResources};
13use embassy_rp::gpio::{Level, Output}; 13use embassy_rp::gpio::{Level, Output};
14use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 14use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0};
15use embassy_rp::pio::Pio; 15use embassy_rp::pio::{InterruptHandler, Pio};
16use embassy_rp::rom_data; 16use embassy_rp::{bind_interrupts, rom_data};
17use embassy_time::{with_timeout, Duration, Timer}; 17use embassy_time::{with_timeout, Duration, Timer};
18use static_cell::make_static; 18use static_cell::make_static;
19use {defmt_rtt as _, panic_probe as _}; 19use {defmt_rtt as _, panic_probe as _};
20 20
21bind_interrupts!(struct Irqs {
22 PIO0_IRQ_0 => InterruptHandler<PIO0>;
23});
24
21teleprobe_meta::timeout!(120); 25teleprobe_meta::timeout!(120);
22 26
23#[embassy_executor::task] 27#[embassy_executor::task]
@@ -51,7 +55,7 @@ async fn main(spawner: Spawner) {
51 55
52 let pwr = Output::new(p.PIN_23, Level::Low); 56 let pwr = Output::new(p.PIN_23, Level::Low);
53 let cs = Output::new(p.PIN_25, Level::High); 57 let cs = Output::new(p.PIN_25, Level::High);
54 let mut pio = Pio::new(p.PIO0); 58 let mut pio = Pio::new(p.PIO0, Irqs);
55 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); 59 let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
56 60
57 let state = make_static!(cyw43::State::new()); 61 let state = make_static!(cyw43::State::new());
diff --git a/tests/rp/src/bin/pio_irq.rs b/tests/rp/src/bin/pio_irq.rs
new file mode 100644
index 000000000..45004424a
--- /dev/null
+++ b/tests/rp/src/bin/pio_irq.rs
@@ -0,0 +1,55 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4#[path = "../common.rs"]
5mod common;
6
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_rp::bind_interrupts;
10use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::{Config, InterruptHandler, Pio};
12use embassy_rp::relocate::RelocatedProgram;
13use {defmt_rtt as _, panic_probe as _};
14
15bind_interrupts!(struct Irqs {
16 PIO0_IRQ_0 => InterruptHandler<PIO0>;
17});
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) {
21 let p = embassy_rp::init(Default::default());
22 let pio = p.PIO0;
23 let Pio {
24 mut common,
25 sm0: mut sm,
26 irq_flags,
27 ..
28 } = Pio::new(pio, Irqs);
29
30 let prg = pio_proc::pio_asm!(
31 "irq set 0",
32 "irq wait 0",
33 "irq set 1",
34 // pause execution here
35 "irq wait 1",
36 );
37
38 let relocated = RelocatedProgram::new(&prg.program);
39 let mut cfg = Config::default();
40 cfg.use_program(&common.load_program(&relocated), &[]);
41 sm.set_config(&cfg);
42 sm.set_enable(true);
43
44 // not using the wait futures on purpose because they clear the irq bits,
45 // and we want to see in which order they are set.
46 while !irq_flags.check(0) {}
47 cortex_m::asm::nop();
48 assert!(!irq_flags.check(1));
49 irq_flags.clear(0);
50 cortex_m::asm::nop();
51 assert!(irq_flags.check(1));
52
53 info!("Test OK");
54 cortex_m::asm::bkpt();
55}