diff options
| author | huntc <[email protected]> | 2021-12-16 07:09:33 +1100 |
|---|---|---|
| committer | huntc <[email protected]> | 2021-12-16 07:09:33 +1100 |
| commit | 2493699fb339b835ad0f8ac403355eae468b73b1 (patch) | |
| tree | cdd41cca6fc90f2bdd988e7403be239eea0c665a | |
| parent | 1374ad2ab6a6f86a46c7c244568718a6bf8db041 (diff) | |
Ref count the peripheral drop
| -rw-r--r-- | embassy-nrf/src/uarte.rs | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index b0a28a5d6..b836395ec 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs | |||
| @@ -309,7 +309,9 @@ impl<'a, T: Instance> Drop for UarteTx<'a, T> { | |||
| 309 | // Wait for txstopped, if needed. | 309 | // Wait for txstopped, if needed. |
| 310 | while did_stoptx && r.events_txstopped.read().bits() == 0 {} | 310 | while did_stoptx && r.events_txstopped.read().bits() == 0 {} |
| 311 | 311 | ||
| 312 | info!("uarte txdrop: done"); | 312 | let s = T::state(); |
| 313 | |||
| 314 | drop_tx_rx(&r, &s); | ||
| 313 | } | 315 | } |
| 314 | } | 316 | } |
| 315 | 317 | ||
| @@ -442,16 +444,9 @@ impl<'a, T: Instance> Drop for UarteRx<'a, T> { | |||
| 442 | // Wait for rxto, if needed. | 444 | // Wait for rxto, if needed. |
| 443 | while did_stoprx && r.events_rxto.read().bits() == 0 {} | 445 | while did_stoprx && r.events_rxto.read().bits() == 0 {} |
| 444 | 446 | ||
| 445 | // Finally we can disable, and we do so for the peripheral | 447 | let s = T::state(); |
| 446 | // i.e. not just rx concerns. | ||
| 447 | r.enable.write(|w| w.enable().disabled()); | ||
| 448 | |||
| 449 | gpio::deconfigure_pin(r.psel.rxd.read().bits()); | ||
| 450 | gpio::deconfigure_pin(r.psel.txd.read().bits()); | ||
| 451 | gpio::deconfigure_pin(r.psel.rts.read().bits()); | ||
| 452 | gpio::deconfigure_pin(r.psel.cts.read().bits()); | ||
| 453 | 448 | ||
| 454 | info!("uarte drop: done"); | 449 | drop_tx_rx(&r, &s); |
| 455 | } | 450 | } |
| 456 | } | 451 | } |
| 457 | 452 | ||
| @@ -508,6 +503,21 @@ pub(in crate) fn apply_workaround_for_enable_anomaly(r: &crate::pac::uarte0::Reg | |||
| 508 | } | 503 | } |
| 509 | } | 504 | } |
| 510 | 505 | ||
| 506 | pub(in crate) fn drop_tx_rx(r: &pac::uarte0::RegisterBlock, s: &sealed::State) { | ||
| 507 | if s.tx_rx_refcount.fetch_sub(1, Ordering::Relaxed) == 1 { | ||
| 508 | // Finally we can disable, and we do so for the peripheral | ||
| 509 | // i.e. not just rx concerns. | ||
| 510 | r.enable.write(|w| w.enable().disabled()); | ||
| 511 | |||
| 512 | gpio::deconfigure_pin(r.psel.rxd.read().bits()); | ||
| 513 | gpio::deconfigure_pin(r.psel.txd.read().bits()); | ||
| 514 | gpio::deconfigure_pin(r.psel.rts.read().bits()); | ||
| 515 | gpio::deconfigure_pin(r.psel.cts.read().bits()); | ||
| 516 | |||
| 517 | info!("uarte tx and rx drop: done"); | ||
| 518 | } | ||
| 519 | } | ||
| 520 | |||
| 511 | /// Interface to an UARTE peripheral that uses an additional timer and two PPI channels, | 521 | /// Interface to an UARTE peripheral that uses an additional timer and two PPI channels, |
| 512 | /// allowing it to implement the ReadUntilIdle trait. | 522 | /// allowing it to implement the ReadUntilIdle trait. |
| 513 | pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { | 523 | pub struct UarteWithIdle<'d, U: Instance, T: TimerInstance> { |
| @@ -667,6 +677,8 @@ impl<'d, U: Instance, T: TimerInstance> Write for UarteWithIdle<'d, U, T> { | |||
| 667 | } | 677 | } |
| 668 | 678 | ||
| 669 | pub(crate) mod sealed { | 679 | pub(crate) mod sealed { |
| 680 | use core::sync::atomic::AtomicU8; | ||
| 681 | |||
| 670 | use embassy::waitqueue::AtomicWaker; | 682 | use embassy::waitqueue::AtomicWaker; |
| 671 | 683 | ||
| 672 | use super::*; | 684 | use super::*; |
| @@ -674,12 +686,14 @@ pub(crate) mod sealed { | |||
| 674 | pub struct State { | 686 | pub struct State { |
| 675 | pub endrx_waker: AtomicWaker, | 687 | pub endrx_waker: AtomicWaker, |
| 676 | pub endtx_waker: AtomicWaker, | 688 | pub endtx_waker: AtomicWaker, |
| 689 | pub tx_rx_refcount: AtomicU8, | ||
| 677 | } | 690 | } |
| 678 | impl State { | 691 | impl State { |
| 679 | pub const fn new() -> Self { | 692 | pub const fn new() -> Self { |
| 680 | Self { | 693 | Self { |
| 681 | endrx_waker: AtomicWaker::new(), | 694 | endrx_waker: AtomicWaker::new(), |
| 682 | endtx_waker: AtomicWaker::new(), | 695 | endtx_waker: AtomicWaker::new(), |
| 696 | tx_rx_refcount: AtomicU8::new(2), | ||
| 683 | } | 697 | } |
| 684 | } | 698 | } |
| 685 | } | 699 | } |
