aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-18 02:29:03 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-18 18:49:10 +0100
commitb57489eb5d27075e077b955b295cc97bf2fc312f (patch)
tree0fc17b38e80f0b2c9c1fd28ca916997a33dbca3a
parent0cd19a58c3dcaa689ba57da80c02af75866f7e09 (diff)
peripheralmutex: separate interrupt registration to own method.
-rw-r--r--embassy-extras/src/peripheral.rs25
-rw-r--r--embassy-nrf/src/buffered_uarte.rs12
-rw-r--r--embassy-nrf/src/spim.rs1
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,