Ref count the peripheral drop
This commit is contained in:
parent
1374ad2ab6
commit
2493699fb3
@ -309,7 +309,9 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> {
|
|||||||
// Wait for txstopped, if needed.
|
// Wait for txstopped, if needed.
|
||||||
while did_stoptx && r.events_txstopped.read().bits() == 0 {}
|
while did_stoptx && r.events_txstopped.read().bits() == 0 {}
|
||||||
|
|
||||||
info!("uarte txdrop: done");
|
let s = T::state();
|
||||||
|
|
||||||
|
drop_tx_rx(&r, &s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,16 +444,9 @@ impl<'a, T: Instance> Drop for UarteRx<'a, T> {
|
|||||||
// Wait for rxto, if needed.
|
// Wait for rxto, if needed.
|
||||||
while did_stoprx && r.events_rxto.read().bits() == 0 {}
|
while did_stoprx && r.events_rxto.read().bits() == 0 {}
|
||||||
|
|
||||||
// Finally we can disable, and we do so for the peripheral
|
let s = T::state();
|
||||||
// i.e. not just rx concerns.
|
|
||||||
r.enable.write(|w| w.enable().disabled());
|
|
||||||
|
|
||||||
gpio::deconfigure_pin(r.psel.rxd.read().bits());
|
drop_tx_rx(&r, &s);
|
||||||
gpio::deconfigure_pin(r.psel.txd.read().bits());
|
|
||||||
gpio::deconfigure_pin(r.psel.rts.read().bits());
|
|
||||||
gpio::deconfigure_pin(r.psel.cts.read().bits());
|
|
||||||
|
|
||||||
info!("uarte drop: done");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,6 +503,21 @@ pub(in crate) fn apply_workaround_for_enable_anomaly(r: &crate::pac::uarte0::Reg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(in crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &sealed::State) {
|
||||||
|
if s.tx_rx_refcount.fetch_sub(1, Ordering::Relaxed) == 1 {
|
||||||
|
// Finally we can disable, and we do so for the peripheral
|
||||||
|
// i.e. not just rx concerns.
|
||||||
|
r.enable.write(|w| w.enable().disabled());
|
||||||
|
|
||||||
|
gpio::deconfigure_pin(r.psel.rxd.read().bits());
|
||||||
|
gpio::deconfigure_pin(r.psel.txd.read().bits());
|
||||||
|
gpio::deconfigure_pin(r.psel.rts.read().bits());
|
||||||
|
gpio::deconfigure_pin(r.psel.cts.read().bits());
|
||||||
|
|
||||||
|
info!("uarte tx and rx drop: done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Interface to an UARTE peripheral that uses an additional timer and two PPI channels,
|
/// Interface to an UARTE peripheral that uses an additional timer and two PPI channels,
|
||||||
/// allowing it to implement the ReadUntilIdle trait.
|
/// allowing it to implement the ReadUntilIdle trait.
|
||||||
pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
|
pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> {
|
||||||
@ -667,6 +677,8 @@ impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
|
use core::sync::atomic::AtomicU8;
|
||||||
|
|
||||||
use embassy::waitqueue::AtomicWaker;
|
use embassy::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -674,12 +686,14 @@ pub(crate) mod sealed {
|
|||||||
pub struct State {
|
pub struct State {
|
||||||
pub endrx_waker: AtomicWaker,
|
pub endrx_waker: AtomicWaker,
|
||||||
pub endtx_waker: AtomicWaker,
|
pub endtx_waker: AtomicWaker,
|
||||||
|
pub tx_rx_refcount: AtomicU8,
|
||||||
}
|
}
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
endrx_waker: AtomicWaker::new(),
|
endrx_waker: AtomicWaker::new(),
|
||||||
endtx_waker: AtomicWaker::new(),
|
endtx_waker: AtomicWaker::new(),
|
||||||
|
tx_rx_refcount: AtomicU8::new(2),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user