diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 030fecf87..ceb52916f 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -61,7 +61,7 @@ struct State<'a, U: Instance> { /// - nrf52832: Section 15.2 /// - nrf52840: Section 6.1.2 pub struct BufferedUarte<'a, U: Instance> { - inner: PeripheralMutex>, + inner: PeripheralMutex>, } impl<'a, U: Instance> Unpin for BufferedUarte<'a, U> {} @@ -143,7 +143,6 @@ impl<'a, U: Instance> BufferedUarte<'a, U> { BufferedUarte { inner: PeripheralMutex::new( - irq, State { inner: uarte, @@ -155,11 +154,12 @@ impl<'a, U: Instance> BufferedUarte<'a, U> { tx_state: TxState::Idle, tx_waker: WakerRegistration::new(), }, + irq, ), } } - fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex>> { + fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex>> { unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } } } @@ -173,7 +173,7 @@ impl<'a, U: Instance> Drop for BufferedUarte<'a, U> { impl<'a, U: Instance> AsyncBufRead for BufferedUarte<'a, U> { fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - self.inner().with(|_irq, state| { + self.inner().with(|state, _irq| { // Conservative compiler fence to prevent optimizations that do not // take in to account actions by DMA. The fence has been placed here, // before any DMA action has started @@ -203,7 +203,7 @@ impl<'a, U: Instance> AsyncBufRead for BufferedUarte<'a, U> { } fn consume(self: Pin<&mut Self>, amt: usize) { - self.inner().with(|irq, state| { + self.inner().with(|state, irq| { trace!("consume {:?}", amt); state.rx.pop(amt); irq.pend(); @@ -213,7 +213,7 @@ impl<'a, U: Instance> AsyncBufRead for BufferedUarte<'a, U> { impl<'a, U: Instance> AsyncWrite for BufferedUarte<'a, U> { fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll> { - self.inner().with(|irq, state| { + self.inner().with(|state, irq| { trace!("poll_write: {:?}", buf.len()); let tx_buf = state.tx.push_buf(); @@ -242,6 +242,8 @@ impl<'a, U: Instance> AsyncWrite for BufferedUarte<'a, U> { } impl<'a, U: Instance> PeripheralState for State<'a, U> { + type Interrupt = U::Interrupt; + fn on_interrupt(&mut self) { trace!("irq: start"); let mut more_work = true; diff --git a/embassy-nrf/src/util/peripheral.rs b/embassy-nrf/src/util/peripheral.rs index 07dc4a7bc..e0edbf2b7 100644 --- a/embassy-nrf/src/util/peripheral.rs +++ b/embassy-nrf/src/util/peripheral.rs @@ -6,25 +6,26 @@ use crate::fmt::*; use crate::interrupt::OwnedInterrupt; pub trait PeripheralState { + type Interrupt: OwnedInterrupt; fn on_interrupt(&mut self); } -pub struct PeripheralMutex { - inner: Option<(I, UnsafeCell)>, +pub struct PeripheralMutex { + inner: Option<(UnsafeCell, S::Interrupt)>, not_send: PhantomData<*mut ()>, } -impl PeripheralMutex { - pub fn new(irq: I, state: S) -> Self { +impl PeripheralMutex { + pub fn new(state: S, irq: S::Interrupt) -> Self { Self { - inner: Some((irq, UnsafeCell::new(state))), + inner: Some((UnsafeCell::new(state), irq)), not_send: PhantomData, } } - pub fn with(self: Pin<&mut Self>, f: impl FnOnce(&mut I, &mut S) -> R) -> R { + pub fn with(self: Pin<&mut Self>, f: impl FnOnce(&mut S, &mut S::Interrupt) -> R) -> R { let this = unsafe { self.get_unchecked_mut() }; - let (irq, state) = unwrap!(this.inner.as_mut()); + let (state, irq) = unwrap!(this.inner.as_mut()); irq.disable(); compiler_fence(Ordering::SeqCst); @@ -43,7 +44,7 @@ impl PeripheralMutex { // Safety: it's OK to get a &mut to the state, since the irq is disabled. let state = unsafe { &mut *state.get() }; - let r = f(irq, state); + let r = f(state, irq); compiler_fence(Ordering::SeqCst); irq.enable(); @@ -51,18 +52,18 @@ impl PeripheralMutex { r } - pub fn free(self: Pin<&mut Self>) -> (I, S) { + pub fn free(self: Pin<&mut Self>) -> (S, S::Interrupt) { let this = unsafe { self.get_unchecked_mut() }; - let (irq, state) = unwrap!(this.inner.take()); + let (state, irq) = unwrap!(this.inner.take()); irq.disable(); irq.remove_handler(); - (irq, state.into_inner()) + (state.into_inner(), irq) } } -impl Drop for PeripheralMutex { +impl Drop for PeripheralMutex { fn drop(&mut self) { - if let Some((irq, state)) = &mut self.inner { + if let Some((state, irq)) = &mut self.inner { irq.disable(); irq.remove_handler(); }