aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhuntc <[email protected]>2022-08-30 20:56:56 +1000
committerhuntc <[email protected]>2022-08-30 20:56:56 +1000
commitdcd8c62169fc92224e2672c621b7d0b846b59cdf (patch)
treee43aef2d3b39ce4ce96cba053fd4df514fda3fcb
parentc0b7fd910e5663242d9320dd9893dbc1844b2729 (diff)
Permits the future to be cancelled
Includes documentation
-rw-r--r--embassy-nrf/src/saadc.rs33
1 files changed, 31 insertions, 2 deletions
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 69926ec03..5f2ac64ef 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;
@@ -225,8 +226,12 @@ impl<'d, const N: usize> Saadc<'d, N> {
225 226
226 /// One shot sampling. The buffer must be the same size as the number of channels configured. 227 /// One shot sampling. The buffer must be the same size as the number of channels configured.
227 /// The sampling is stopped prior to returning in order to reduce power consumption (power 228 /// The sampling is stopped prior to returning in order to reduce power consumption (power
228 /// consumption remains higher if sampling is not stopped explicitly). 229 /// consumption remains higher if sampling is not stopped explicitly). Cancellation will
230 /// also cause the sampling to be stopped.
229 pub async fn sample(&mut self, buf: &mut [i16; N]) { 231 pub async fn sample(&mut self, buf: &mut [i16; N]) {
232 // In case the future is dropped, stop the task and wait for it to end.
233 let on_drop = OnDrop::new(Self::stop_sampling_immediately);
234
230 let r = Self::regs(); 235 let r = Self::regs();
231 236
232 // Set up the DMA 237 // Set up the DMA
@@ -259,6 +264,7 @@ impl<'d, const N: usize> Saadc<'d, N> {
259 }) 264 })
260 .await; 265 .await;
261 266
267 on_drop.defuse();
262 Self::stop_sampling().await; 268 Self::stop_sampling().await;
263 } 269 }
264 270
@@ -279,6 +285,12 @@ impl<'d, const N: usize> Saadc<'d, N> {
279 /// taken to acquire the samples into a single buffer. You should measure the 285 /// taken to acquire the samples into a single buffer. You should measure the
280 /// time taken by the callback and set the sample buffer size accordingly. 286 /// time taken by the callback and set the sample buffer size accordingly.
281 /// Exceeding this time can lead to samples becoming dropped. 287 /// Exceeding this time can lead to samples becoming dropped.
288 ///
289 /// The sampling is stopped prior to returning in order to reduce power consumption (power
290 /// consumption remains higher if sampling is not stopped explicitly), and to
291 /// free the buffers from being used by the peripheral. Cancellation will
292 /// also cause the sampling to be stopped.
293
282 pub async fn run_task_sampler<S, T: TimerInstance, const N0: usize>( 294 pub async fn run_task_sampler<S, T: TimerInstance, const N0: usize>(
283 &mut self, 295 &mut self,
284 timer: &mut T, 296 timer: &mut T,
@@ -330,6 +342,9 @@ impl<'d, const N: usize> Saadc<'d, N> {
330 I: FnMut(), 342 I: FnMut(),
331 S: FnMut(&[[i16; N]]) -> SamplerState, 343 S: FnMut(&[[i16; N]]) -> SamplerState,
332 { 344 {
345 // In case the future is dropped, stop the task and wait for it to end.
346 let on_drop = OnDrop::new(Self::stop_sampling_immediately);
347
333 let r = Self::regs(); 348 let r = Self::regs();
334 349
335 // Establish mode and sample rate 350 // Establish mode and sample rate
@@ -413,10 +428,24 @@ impl<'d, const N: usize> Saadc<'d, N> {
413 }) 428 })
414 .await; 429 .await;
415 430
431 on_drop.defuse();
416 Self::stop_sampling().await; 432 Self::stop_sampling().await;
417 } 433 }
418 434
419 // Stop sampling and wait for it to stop 435 // Stop sampling and wait for it to stop in a blocking fashion
436 fn stop_sampling_immediately() {
437 let r = Self::regs();
438
439 compiler_fence(Ordering::SeqCst);
440
441 r.events_stopped.reset();
442 r.tasks_stop.write(|w| unsafe { w.bits(1) });
443
444 while r.events_stopped.read().bits() == 0 {}
445 r.events_stopped.reset();
446 }
447
448 // Stop sampling and wait for it to stop in a non-blocking fashino
420 async fn stop_sampling() { 449 async fn stop_sampling() {
421 let r = Self::regs(); 450 let r = Self::regs();
422 451