aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-08-31 00:31:38 +0000
committerGitHub <[email protected]>2022-08-31 00:31:38 +0000
commit38900a7fb0723e5a6bef8a8cd201b11c1f095ac9 (patch)
tree8910d03d9f3d5b8d19f4e0dc4e1088d6cf2b349b
parentfe08bdf0d81e784c3af642128b91a53514b79a63 (diff)
parent30641d05640a7a3cd4d71c70c09694a3eef825e0 (diff)
Merge #928
928: Ensure that the sampling is stopped r=Dirbaio a=huntc Ensures that nRF saadc sampling is stopped and is awaited prior to exiting the two sampling methods. Not doing so causes a potential power drain and the potential for dropped buffer writes when having finished continuous sampling. Co-authored-by: huntc <[email protected]>
-rw-r--r--embassy-nrf/src/saadc.rs29
1 files changed, 29 insertions, 0 deletions
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 7dc66349e..9bc89eb38 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -3,6 +3,7 @@
3use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_hal_common::drop::OnDrop;
6use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 7use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
7use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
8use futures::future::poll_fn; 9use futures::future::poll_fn;
@@ -219,7 +220,13 @@ impl<'d, const N: usize> Saadc<'d, N> {
219 } 220 }
220 221
221 /// One shot sampling. The buffer must be the same size as the number of channels configured. 222 /// One shot sampling. The buffer must be the same size as the number of channels configured.
223 /// The sampling is stopped prior to returning in order to reduce power consumption (power
224 /// consumption remains higher if sampling is not stopped explicitly). Cancellation will
225 /// also cause the sampling to be stopped.
222 pub async fn sample(&mut self, buf: &mut [i16; N]) { 226 pub async fn sample(&mut self, buf: &mut [i16; N]) {
227 // In case the future is dropped, stop the task and wait for it to end.
228 OnDrop::new(Self::stop_sampling_immediately);
229
223 let r = Self::regs(); 230 let r = Self::regs();
224 231
225 // Set up the DMA 232 // Set up the DMA
@@ -270,6 +277,12 @@ impl<'d, const N: usize> Saadc<'d, N> {
270 /// taken to acquire the samples into a single buffer. You should measure the 277 /// taken to acquire the samples into a single buffer. You should measure the
271 /// time taken by the callback and set the sample buffer size accordingly. 278 /// time taken by the callback and set the sample buffer size accordingly.
272 /// Exceeding this time can lead to samples becoming dropped. 279 /// Exceeding this time can lead to samples becoming dropped.
280 ///
281 /// The sampling is stopped prior to returning in order to reduce power consumption (power
282 /// consumption remains higher if sampling is not stopped explicitly), and to
283 /// free the buffers from being used by the peripheral. Cancellation will
284 /// also cause the sampling to be stopped.
285
273 pub async fn run_task_sampler<S, T: TimerInstance, const N0: usize>( 286 pub async fn run_task_sampler<S, T: TimerInstance, const N0: usize>(
274 &mut self, 287 &mut self,
275 timer: &mut T, 288 timer: &mut T,
@@ -321,6 +334,9 @@ impl<'d, const N: usize> Saadc<'d, N> {
321 I: FnMut(), 334 I: FnMut(),
322 S: FnMut(&[[i16; N]]) -> SamplerState, 335 S: FnMut(&[[i16; N]]) -> SamplerState,
323 { 336 {
337 // In case the future is dropped, stop the task and wait for it to end.
338 OnDrop::new(Self::stop_sampling_immediately);
339
324 let r = Self::regs(); 340 let r = Self::regs();
325 341
326 // Establish mode and sample rate 342 // Establish mode and sample rate
@@ -404,6 +420,19 @@ impl<'d, const N: usize> Saadc<'d, N> {
404 }) 420 })
405 .await; 421 .await;
406 } 422 }
423
424 // Stop sampling and wait for it to stop in a blocking fashion
425 fn stop_sampling_immediately() {
426 let r = Self::regs();
427
428 compiler_fence(Ordering::SeqCst);
429
430 r.events_stopped.reset();
431 r.tasks_stop.write(|w| unsafe { w.bits(1) });
432
433 while r.events_stopped.read().bits() == 0 {}
434 r.events_stopped.reset();
435 }
407} 436}
408 437
409impl<'d> Saadc<'d, 1> { 438impl<'d> Saadc<'d, 1> {