diff options
| author | pennae <[email protected]> | 2023-04-25 18:47:51 +0200 |
|---|---|---|
| committer | pennae <[email protected]> | 2023-05-01 12:58:57 +0200 |
| commit | a9074fd09bb2fa6265808f32e5cf303285fc0ec6 (patch) | |
| tree | 1c21d3c5f068591522dc908e50bced5ba80894b3 | |
| parent | f2469776f4f229dff23eb7f0bf59c00290620d9c (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.rs | 1 | ||||
| -rw-r--r-- | embassy-rp/src/pio.rs | 50 |
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 | ||
| 82 | pub(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"] |
| 84 | pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> { | 98 | pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> { |
| @@ -89,14 +103,6 @@ pub struct FifoOutFuture<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> { | |||
| 89 | 103 | ||
| 90 | impl<'a, PIO: PioInstance, SM: PioStateMachine + Unpin> FifoOutFuture<'a, PIO, SM> { | 104 | impl<'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 | ||
| 148 | impl<'a, PIO: PioInstance, SM: PioStateMachine> FifoInFuture<'a, PIO, SM> { | 151 | impl<'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 | ||
| 204 | impl<'a, PIO: PioInstance> IrqFuture<PIO> { | 196 | impl<'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 | ||
| 1172 | pub trait PioInstance: Unpin { | 1153 | pub trait PioInstance: Unpin { |
| 1173 | const PIO_NO: u8; | 1154 | const PIO_NO: u8; |
| 1174 | type Irq: Interrupt; | ||
| 1175 | } | 1155 | } |
| 1176 | 1156 | ||
| 1177 | impl PioInstance for PioInstanceBase<0> { | 1157 | impl 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 | ||
| 1182 | impl PioInstance for PioInstanceBase<1> { | 1161 | impl 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 | ||
| 1187 | pub type Pio0 = PioInstanceBase<0>; | 1165 | pub type Pio0 = PioInstanceBase<0>; |
