diff options
| author | huntc <[email protected]> | 2022-08-30 20:56:56 +1000 |
|---|---|---|
| committer | huntc <[email protected]> | 2022-08-30 20:56:56 +1000 |
| commit | dcd8c62169fc92224e2672c621b7d0b846b59cdf (patch) | |
| tree | e43aef2d3b39ce4ce96cba053fd4df514fda3fcb | |
| parent | c0b7fd910e5663242d9320dd9893dbc1844b2729 (diff) | |
Permits the future to be cancelled
Includes documentation
| -rw-r--r-- | embassy-nrf/src/saadc.rs | 33 |
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 @@ | |||
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | 5 | ||
| 6 | use embassy_hal_common::drop::OnDrop; | ||
| 6 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 7 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; |
| 7 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 8 | use futures::future::poll_fn; | 9 | use 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 | ||
