Stop PDM sampling when future is dropped

This commit is contained in:
Quentin Smith 2022-08-21 02:04:11 -04:00
parent 3d26573c6b
commit 029713eca0

View File

@ -4,6 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use embassy_hal_common::drop::OnDrop;
use embassy_util::waitqueue::AtomicWaker; use embassy_util::waitqueue::AtomicWaker;
use futures::future::poll_fn; use futures::future::poll_fn;
use pac::{pdm, PDM}; use pac::{pdm, PDM};
@ -149,11 +150,9 @@ impl<'d> Pdm<'d> {
// Reset and enable the events // Reset and enable the events
r.events_end.reset(); r.events_end.reset();
r.events_started.reset();
r.events_stopped.reset(); r.events_stopped.reset();
r.intenset.write(|w| { r.intenset.write(|w| {
w.end().set(); w.end().set();
w.started().set();
w.stopped().set(); w.stopped().set();
w w
}); });
@ -164,6 +163,12 @@ impl<'d> Pdm<'d> {
r.tasks_start.write(|w| w.tasks_start().set_bit()); r.tasks_start.write(|w| w.tasks_start().set_bit());
let ondrop = OnDrop::new(|| {
r.tasks_stop.write(|w| w.tasks_stop().set_bit());
// N.B. It would be better if this were async, but Drop only support sync code.
while r.events_stopped.read().bits() != 0 {}
});
// Wait for 'end' event. // Wait for 'end' event.
poll_fn(|cx| { poll_fn(|cx| {
let r = Self::regs(); let r = Self::regs();
@ -183,21 +188,14 @@ impl<'d> Pdm<'d> {
r.tasks_stop.write(|w| w.tasks_stop().set_bit()); r.tasks_stop.write(|w| w.tasks_stop().set_bit());
} }
} }
if r.events_started.read().bits() != 0 {
compiler_fence(Ordering::SeqCst);
r.events_started.reset();
}
if r.events_stopped.read().bits() != 0 { if r.events_stopped.read().bits() != 0 {
compiler_fence(Ordering::SeqCst);
r.events_stopped.reset();
return Poll::Ready(()); return Poll::Ready(());
} }
Poll::Pending Poll::Pending
}) })
.await; .await;
ondrop.defuse();
} }
/// Continuous sampling with double buffers. /// Continuous sampling with double buffers.
@ -250,6 +248,12 @@ impl<'d> Pdm<'d> {
let mut done = false; let mut done = false;
let ondrop = OnDrop::new(|| {
r.tasks_stop.write(|w| w.tasks_stop().set_bit());
// N.B. It would be better if this were async, but Drop only support sync code.
while r.events_stopped.read().bits() != 0 {}
});
// Wait for events and complete when the sampler indicates it has had enough. // Wait for events and complete when the sampler indicates it has had enough.
poll_fn(|cx| { poll_fn(|cx| {
let r = Self::regs(); let r = Self::regs();
@ -284,15 +288,13 @@ impl<'d> Pdm<'d> {
} }
if r.events_stopped.read().bits() != 0 { if r.events_stopped.read().bits() != 0 {
r.events_stopped.reset();
r.intenset.write(|w| w.stopped().set());
return Poll::Ready(()); return Poll::Ready(());
} }
Poll::Pending Poll::Pending
}) })
.await; .await;
ondrop.defuse();
} }
} }