aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-04-25 18:47:51 +0200
committerpennae <[email protected]>2023-05-01 12:58:57 +0200
commita9074fd09bb2fa6265808f32e5cf303285fc0ec6 (patch)
tree1c21d3c5f068591522dc908e50bced5ba80894b3
parentf2469776f4f229dff23eb7f0bf59c00290620d9c (diff)
rp/pio: enable pio interrupts only once
since we never actually *disable* these interrupts for any length of time we can simply enable them globally. we also initialize all pio interrupt flags to not cause system interrupts since state machine irqa are not necessarily meant to cause a system interrupt when set. the fifo interrupts are sticky and can likewise only be cleared inside the handler by disabling them.
-rw-r--r--embassy-rp/src/lib.rs1
-rw-r--r--embassy-rp/src/pio.rs50
2 files changed, 15 insertions, 36 deletions
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index 697f4308b..d69d12a30 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -156,6 +156,7 @@ pub fn init(_config: config::Config) -> Peripherals {
156 #[cfg(feature = "time-driver")] 156 #[cfg(feature = "time-driver")]
157 timer::init(); 157 timer::init();
158 dma::init(); 158 dma::init();
159 pio::init();
159 } 160 }
160 161
161 peripherals 162 peripherals
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs
index f0d550d95..00a7aa372 100644
--- a/embassy-rp/src/pio.rs
+++ b/embassy-rp/src/pio.rs
@@ -79,6 +79,20 @@ unsafe fn PIO1_IRQ_0() {
79 pac::PIO1.irqs(0).inte().write_clear(|m| m.0 = ints); 79 pac::PIO1.irqs(0).inte().write_clear(|m| m.0 = ints);
80} 80}
81 81
82pub(crate) unsafe fn init() {
83 let irq = interrupt::PIO0_IRQ_0::steal();
84 irq.disable();
85 irq.set_priority(interrupt::Priority::P3);
86 pac::PIO0.irqs(0).inte().write(|m| m.0 = 0);
87 irq.enable();
88
89 let irq = interrupt::PIO1_IRQ_0::steal();
90 irq.disable();
91 irq.set_priority(interrupt::Priority::P3);
92 pac::PIO1.irqs(0).inte().write(|m| m.0 = 0);
93 irq.enable();
94}
95
82/// Future that waits for TX-FIFO to become writable 96/// Future that waits for TX-FIFO to become writable
83#[must_use = "futures do nothing unless you `.await` or poll them"] 97#[must_use = "futures do nothing unless you `.await` or poll them"]
84pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> { 98pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> {
@@ -89,14 +103,6 @@ pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> {
89 103
90impl<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> FifoOutFuture<'a, PIO, SM> { 104impl<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> FifoOutFuture<'a, PIO, SM> {
91 pub fn new(sm: &'a mut SM, value: u32) -> Self { 105 pub fn new(sm: &'a mut SM, value: u32) -> Self {
92 unsafe {
93 critical_section::with(|_| {
94 let irq = PIO::Irq::steal();
95 irq.set_priority(interrupt::Priority::P3);
96
97 irq.enable();
98 });
99 }
100 FifoOutFuture { 106 FifoOutFuture {
101 sm, 107 sm,
102 pio: PhantomData::default(), 108 pio: PhantomData::default(),
@@ -115,12 +121,9 @@ impl<'d, PIO: PioInstance, SM: PioStateMachine + Unpin> Future for FifoOutFuture
115 } else { 121 } else {
116 WAKERS[PIO::PIO_NO as usize].fifo_out()[SM::Sm::SM_NO as usize].register(cx.waker()); 122 WAKERS[PIO::PIO_NO as usize].fifo_out()[SM::Sm::SM_NO as usize].register(cx.waker());
117 unsafe { 123 unsafe {
118 let irq = PIO::Irq::steal();
119 irq.disable();
120 PIOS[PIO::PIO_NO as usize].irqs(0).inte().write_set(|m| { 124 PIOS[PIO::PIO_NO as usize].irqs(0).inte().write_set(|m| {
121 m.0 = TXNFULL_MASK << SM::Sm::SM_NO; 125 m.0 = TXNFULL_MASK << SM::Sm::SM_NO;
122 }); 126 });
123 irq.enable();
124 } 127 }
125 // debug!("Pending"); 128 // debug!("Pending");
126 Poll::Pending 129 Poll::Pending
@@ -147,14 +150,6 @@ pub struct FifoInFuture<'a, PIO: PioInstance, SM: PioStateMachine> {
147 150
148impl<'a, PIO: PioInstance, SM: PioStateMachine> FifoInFuture<'a, PIO, SM> { 151impl<'a, PIO: PioInstance, SM: PioStateMachine> FifoInFuture<'a, PIO, SM> {
149 pub fn new(sm: &'a mut SM) -> Self { 152 pub fn new(sm: &'a mut SM) -> Self {
150 unsafe {
151 critical_section::with(|_| {
152 let irq = PIO::Irq::steal();
153 irq.set_priority(interrupt::Priority::P3);
154
155 irq.enable();
156 });
157 }
158 FifoInFuture { 153 FifoInFuture {
159 sm, 154 sm,
160 pio: PhantomData::default(), 155 pio: PhantomData::default(),
@@ -171,12 +166,9 @@ impl<'d, PIO: PioInstance, SM: PioStateMachine> Future for FifoInFuture<'d, PIO,
171 } else { 166 } else {
172 WAKERS[PIO::PIO_NO as usize].fifo_in()[SM::Sm::SM_NO as usize].register(cx.waker()); 167 WAKERS[PIO::PIO_NO as usize].fifo_in()[SM::Sm::SM_NO as usize].register(cx.waker());
173 unsafe { 168 unsafe {
174 let irq = PIO::Irq::steal();
175 irq.disable();
176 PIOS[PIO::PIO_NO as usize].irqs(0).inte().write_set(|m| { 169 PIOS[PIO::PIO_NO as usize].irqs(0).inte().write_set(|m| {
177 m.0 = RXNEMPTY_MASK << SM::Sm::SM_NO; 170 m.0 = RXNEMPTY_MASK << SM::Sm::SM_NO;
178 }); 171 });
179 irq.enable();
180 } 172 }
181 //debug!("Pending"); 173 //debug!("Pending");
182 Poll::Pending 174 Poll::Pending
@@ -203,14 +195,6 @@ pub struct IrqFuture<PIO: PioInstance> {
203 195
204impl<'a, PIO: PioInstance> IrqFuture<PIO> { 196impl<'a, PIO: PioInstance> IrqFuture<PIO> {
205 pub fn new(irq_no: u8) -> Self { 197 pub fn new(irq_no: u8) -> Self {
206 unsafe {
207 critical_section::with(|_| {
208 let irq = PIO::Irq::steal();
209 irq.set_priority(interrupt::Priority::P3);
210
211 irq.enable();
212 });
213 }
214 IrqFuture { 198 IrqFuture {
215 pio: PhantomData::default(), 199 pio: PhantomData::default(),
216 irq_no, 200 irq_no,
@@ -240,12 +224,9 @@ impl<'d, PIO: PioInstance> Future for IrqFuture<PIO> {
240 224
241 WAKERS[PIO::PIO_NO as usize].irq()[self.irq_no as usize].register(cx.waker()); 225 WAKERS[PIO::PIO_NO as usize].irq()[self.irq_no as usize].register(cx.waker());
242 unsafe { 226 unsafe {
243 let irq = PIO::Irq::steal();
244 irq.disable();
245 PIOS[PIO::PIO_NO as usize].irqs(0).inte().write_set(|m| { 227 PIOS[PIO::PIO_NO as usize].irqs(0).inte().write_set(|m| {
246 m.0 = SMIRQ_MASK << self.irq_no; 228 m.0 = SMIRQ_MASK << self.irq_no;
247 }); 229 });
248 irq.enable();
249 } 230 }
250 Poll::Pending 231 Poll::Pending
251 } 232 }
@@ -1171,17 +1152,14 @@ pub struct PioInstanceBase<const PIO_NO: u8> {}
1171 1152
1172pub trait PioInstance: Unpin { 1153pub trait PioInstance: Unpin {
1173 const PIO_NO: u8; 1154 const PIO_NO: u8;
1174 type Irq: Interrupt;
1175} 1155}
1176 1156
1177impl PioInstance for PioInstanceBase<0> { 1157impl PioInstance for PioInstanceBase<0> {
1178 const PIO_NO: u8 = 0; 1158 const PIO_NO: u8 = 0;
1179 type Irq = interrupt::PIO0_IRQ_0;
1180} 1159}
1181 1160
1182impl PioInstance for PioInstanceBase<1> { 1161impl PioInstance for PioInstanceBase<1> {
1183 const PIO_NO: u8 = 1; 1162 const PIO_NO: u8 = 1;
1184 type Irq = interrupt::PIO1_IRQ_0;
1185} 1163}
1186 1164
1187pub type Pio0 = PioInstanceBase<0>; 1165pub type Pio0 = PioInstanceBase<0>;