Skip to content

Commit eb16b23

Browse files
committed
Implement Drop trait to ensure DMA is stopped
1 parent 7f1989c commit eb16b23

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

nrf-hal-common/src/uarte.rs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,13 +449,19 @@ mod _uarte1 {
449449
}
450450

451451
/// Interface for the TX part of a UART instance that can be used independently of the RX part.
452-
pub struct UarteTx<'a, T> {
452+
pub struct UarteTx<'a, T>
453+
where
454+
T: Instance,
455+
{
453456
_marker: core::marker::PhantomData<T>,
454457
tx_buf: &'a mut [u8],
455458
}
456459

457460
/// Interface for the RX part of a UART instance that can be used independently of the TX part.
458-
pub struct UarteRx<'a, T> {
461+
pub struct UarteRx<'a, T>
462+
where
463+
T: Instance,
464+
{
459465
_marker: core::marker::PhantomData<T>,
460466
rx_buf: &'a mut [u8],
461467
}
@@ -494,6 +500,63 @@ where
494500
}
495501
}
496502

503+
impl<'a, T> Drop for UarteTx<'a, T>
504+
where
505+
T: Instance,
506+
{
507+
fn drop(&mut self) {
508+
let uarte = unsafe { &*T::ptr() };
509+
510+
let in_progress = uarte.events_txstarted.read().bits() == 1;
511+
// Stop any ongoing transmission
512+
if in_progress {
513+
uarte.tasks_stoptx.write(|w| unsafe { w.bits(1) });
514+
515+
// Wait for transmitter is stopped.
516+
while uarte.events_txstopped.read().bits() == 0 {}
517+
518+
// Reset events
519+
uarte.events_endtx.reset();
520+
uarte.events_txstopped.reset();
521+
522+
// Ensure the above is done
523+
compiler_fence(SeqCst);
524+
}
525+
}
526+
}
527+
528+
impl<'a, T> Drop for UarteRx<'a, T>
529+
where
530+
T: Instance,
531+
{
532+
fn drop(&mut self) {
533+
let uarte = unsafe { &*T::ptr() };
534+
535+
let in_progress = uarte.events_rxstarted.read().bits() == 1;
536+
// Stop any ongoing reception
537+
if in_progress {
538+
uarte.tasks_stoprx.write(|w| unsafe { w.bits(1) });
539+
540+
// Wait for receive to be done to ensure memory is untouched.
541+
while uarte.events_rxto.read().bits() == 0 {}
542+
543+
uarte.events_rxto.reset();
544+
545+
// Flush DMA
546+
uarte.tasks_flushrx.write(|w| unsafe { w.bits(1) });
547+
548+
// Wait for the flush to complete.
549+
while uarte.events_endrx.read().bits() == 0 {}
550+
551+
// Reset events
552+
uarte.events_endrx.reset();
553+
554+
// Ensure the above is done
555+
compiler_fence(SeqCst);
556+
}
557+
}
558+
}
559+
497560
pub mod serial {
498561

499562
///! Implementation of the embedded_hal::serial::* traits for UartTx and UartRx.

0 commit comments

Comments
 (0)