Stop PDM sampling when future is dropped
This commit is contained in:
parent
3d26573c6b
commit
029713eca0
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user