diff options
| -rw-r--r-- | embassy-extras/src/peripheral.rs | 25 | ||||
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 12 | ||||
| -rw-r--r-- | embassy-nrf/src/spim.rs | 1 |
3 files changed, 23 insertions, 15 deletions
diff --git a/embassy-extras/src/peripheral.rs b/embassy-extras/src/peripheral.rs index aa23bc978..e2435d63f 100644 --- a/embassy-extras/src/peripheral.rs +++ b/embassy-extras/src/peripheral.rs | |||
| @@ -32,32 +32,33 @@ impl<S: PeripheralState> PeripheralMutex<S> { | |||
| 32 | } | 32 | } |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | /// safety: self must be pinned. | 35 | pub fn register_interrupt(self: Pin<&mut Self>) { |
| 36 | unsafe fn setup(&mut self) { | 36 | let this = unsafe { self.get_unchecked_mut() }; |
| 37 | self.irq.disable(); | 37 | if this.irq_setup_done { |
| 38 | return; | ||
| 39 | } | ||
| 40 | |||
| 41 | this.irq.disable(); | ||
| 38 | compiler_fence(Ordering::SeqCst); | 42 | compiler_fence(Ordering::SeqCst); |
| 39 | 43 | ||
| 40 | self.irq.set_handler(|p| { | 44 | this.irq.set_handler(|p| { |
| 41 | // Safety: it's OK to get a &mut to the state, since | 45 | // Safety: it's OK to get a &mut to the state, since |
| 42 | // - We're in the IRQ, no one else can't preempt us | 46 | // - We're in the IRQ, no one else can't preempt us |
| 43 | // - We can't have preempted a with() call because the irq is disabled during it. | 47 | // - We can't have preempted a with() call because the irq is disabled during it. |
| 44 | let state = &mut *(p as *mut S); | 48 | let state = unsafe { &mut *(p as *mut S) }; |
| 45 | state.on_interrupt(); | 49 | state.on_interrupt(); |
| 46 | }); | 50 | }); |
| 47 | self.irq | 51 | this.irq |
| 48 | .set_handler_context((&mut self.state) as *mut _ as *mut ()); | 52 | .set_handler_context((&mut this.state) as *mut _ as *mut ()); |
| 49 | 53 | ||
| 50 | compiler_fence(Ordering::SeqCst); | 54 | compiler_fence(Ordering::SeqCst); |
| 51 | self.irq.enable(); | 55 | this.irq.enable(); |
| 52 | 56 | ||
| 53 | self.irq_setup_done = true; | 57 | this.irq_setup_done = true; |
| 54 | } | 58 | } |
| 55 | 59 | ||
| 56 | pub fn with<R>(self: Pin<&mut Self>, f: impl FnOnce(&mut S, &mut S::Interrupt) -> R) -> R { | 60 | pub fn with<R>(self: Pin<&mut Self>, f: impl FnOnce(&mut S, &mut S::Interrupt) -> R) -> R { |
| 57 | let this = unsafe { self.get_unchecked_mut() }; | 61 | let this = unsafe { self.get_unchecked_mut() }; |
| 58 | if !this.irq_setup_done { | ||
| 59 | unsafe { this.setup() } | ||
| 60 | } | ||
| 61 | 62 | ||
| 62 | this.irq.disable(); | 63 | this.irq.disable(); |
| 63 | compiler_fence(Ordering::SeqCst); | 64 | compiler_fence(Ordering::SeqCst); |
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 9b4ec6061..6cc5f1322 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -207,7 +207,9 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi | |||
| 207 | for BufferedUarte<'a, U, T, P1, P2> | 207 | for BufferedUarte<'a, U, T, P1, P2> |
| 208 | { | 208 | { |
| 209 | fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { | 209 | fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { |
| 210 | self.inner().with(|state, _irq| { | 210 | let mut inner = self.inner(); |
| 211 | inner.as_mut().register_interrupt(); | ||
| 212 | inner.with(|state, _irq| { | ||
| 211 | // Conservative compiler fence to prevent optimizations that do not | 213 | // Conservative compiler fence to prevent optimizations that do not |
| 212 | // take in to account actions by DMA. The fence has been placed here, | 214 | // take in to account actions by DMA. The fence has been placed here, |
| 213 | // before any DMA action has started | 215 | // before any DMA action has started |
| @@ -230,7 +232,9 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi | |||
| 230 | } | 232 | } |
| 231 | 233 | ||
| 232 | fn consume(self: Pin<&mut Self>, amt: usize) { | 234 | fn consume(self: Pin<&mut Self>, amt: usize) { |
| 233 | self.inner().with(|state, irq| { | 235 | let mut inner = self.inner(); |
| 236 | inner.as_mut().register_interrupt(); | ||
| 237 | inner.with(|state, irq| { | ||
| 234 | trace!("consume {:?}", amt); | 238 | trace!("consume {:?}", amt); |
| 235 | state.rx.pop(amt); | 239 | state.rx.pop(amt); |
| 236 | irq.pend(); | 240 | irq.pend(); |
| @@ -242,7 +246,9 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi | |||
| 242 | for BufferedUarte<'a, U, T, P1, P2> | 246 | for BufferedUarte<'a, U, T, P1, P2> |
| 243 | { | 247 | { |
| 244 | fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> { | 248 | fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> { |
| 245 | self.inner().with(|state, irq| { | 249 | let mut inner = self.inner(); |
| 250 | inner.as_mut().register_interrupt(); | ||
| 251 | inner.with(|state, irq| { | ||
| 246 | trace!("poll_write: {:?}", buf.len()); | 252 | trace!("poll_write: {:?}", buf.len()); |
| 247 | 253 | ||
| 248 | let tx_buf = state.tx.push_buf(); | 254 | let tx_buf = state.tx.push_buf(); |
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 4a3adeb3d..ef89afbc6 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs | |||
| @@ -148,6 +148,7 @@ impl<T: Instance> FullDuplex<u8> for Spim<T> { | |||
| 148 | slice_in_ram_or(rx, Error::DMABufferNotInDataMemory)?; | 148 | slice_in_ram_or(rx, Error::DMABufferNotInDataMemory)?; |
| 149 | slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?; | 149 | slice_in_ram_or(tx, Error::DMABufferNotInDataMemory)?; |
| 150 | 150 | ||
| 151 | self.as_mut().inner().register_interrupt(); | ||
| 151 | self.as_mut().inner().with(|s, _irq| { | 152 | self.as_mut().inner().with(|s, _irq| { |
| 152 | // Conservative compiler fence to prevent optimizations that do not | 153 | // Conservative compiler fence to prevent optimizations that do not |
| 153 | // take in to account actions by DMA. The fence has been placed here, | 154 | // take in to account actions by DMA. The fence has been placed here, |
