nrf/buffered_uarte: stop on drop, add free()

This commit is contained in:
Dario Nieuwenhuis 2021-01-11 10:39:59 +01:00
parent c91882a72c
commit 2616467377
2 changed files with 50 additions and 8 deletions

View File

@ -14,13 +14,16 @@ use embassy::io::{AsyncBufRead, AsyncWrite, Result};
use embassy::util::WakerRegistration; use embassy::util::WakerRegistration;
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
use crate::fmt::{panic, todo, *};
use crate::hal::gpio::Port as GpioPort; use crate::hal::gpio::Port as GpioPort;
use crate::hal::ppi::ConfigurablePpi; use crate::hal::ppi::ConfigurablePpi;
use crate::interrupt::{self, OwnedInterrupt}; use crate::interrupt::{self, OwnedInterrupt};
use crate::pac; use crate::pac;
use crate::util::peripheral::{PeripheralMutex, PeripheralState}; use crate::util::peripheral::{PeripheralMutex, PeripheralState};
use crate::util::ring_buffer::RingBuffer; use crate::util::ring_buffer::RingBuffer;
use crate::{
fmt::{panic, todo, *},
util::low_power_wait_until,
};
// Re-export SVD variants to allow user to directly set values // Re-export SVD variants to allow user to directly set values
pub use crate::hal::uarte::Pins; pub use crate::hal::uarte::Pins;
@ -203,14 +206,28 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex<State<'a, U, T, P1, P2>>> { fn inner(self: Pin<&mut Self>) -> Pin<&mut PeripheralMutex<State<'a, U, T, P1, P2>>> {
unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }
} }
pub fn free(self: Pin<&mut Self>) -> (U, T, P1, P2, U::Interrupt) {
let (mut state, irq) = self.inner().free();
state.stop();
(
state.uarte,
state.timer,
state.ppi_channel_1,
state.ppi_channel_2,
irq,
)
}
} }
impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> Drop impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> Drop
for BufferedUarte<'a, U, T, P1, P2> for BufferedUarte<'a, U, T, P1, P2>
{ {
fn drop(&mut self) { fn drop(&mut self) {
// stop DMA before dropping, because DMA is using the buffer in `self`. let inner = unsafe { Pin::new_unchecked(&mut self.inner) };
todo!() if let Some((mut state, _irq)) = inner.try_free() {
state.stop();
}
} }
} }
@ -281,6 +298,26 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi
} }
} }
impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi>
State<'a, U, T, P1, P2>
{
fn stop(&mut self) {
self.timer.tasks_stop.write(|w| unsafe { w.bits(1) });
if let RxState::Receiving = self.rx_state {
self.uarte.tasks_stoprx.write(|w| unsafe { w.bits(1) });
}
if let TxState::Transmitting(_) = self.tx_state {
self.uarte.tasks_stoptx.write(|w| unsafe { w.bits(1) });
}
if let RxState::Receiving = self.rx_state {
low_power_wait_until(|| self.uarte.events_endrx.read().bits() == 0);
}
if let TxState::Transmitting(_) = self.tx_state {
low_power_wait_until(|| self.uarte.events_endtx.read().bits() == 0);
}
}
}
impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> PeripheralState impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi> PeripheralState
for State<'a, U, T, P1, P2> for State<'a, U, T, P1, P2>
{ {

View File

@ -52,12 +52,17 @@ impl<S: PeripheralState> PeripheralMutex<S> {
r r
} }
pub fn free(self: Pin<&mut Self>) -> (S, S::Interrupt) { pub fn try_free(self: Pin<&mut Self>) -> Option<(S, S::Interrupt)> {
let this = unsafe { self.get_unchecked_mut() }; let this = unsafe { self.get_unchecked_mut() };
let (state, irq) = unwrap!(this.inner.take()); this.inner.take().map(|(state, irq)| {
irq.disable(); irq.disable();
irq.remove_handler(); irq.remove_handler();
(state.into_inner(), irq) (state.into_inner(), irq)
})
}
pub fn free(self: Pin<&mut Self>) -> (S, S::Interrupt) {
unwrap!(self.try_free())
} }
} }