From a81b96356191be59f91b7fa641a97f78d0d1cd25 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 1 Sep 2021 23:54:26 +0200 Subject: [PATCH 1/2] nrf/saadc: don't use wake_on_interrupt. --- embassy-nrf/src/saadc.rs | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 7bc38f1d..bc7f3471 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -2,17 +2,14 @@ use core::future::Future; use core::marker::PhantomData; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; -use embassy::util::{wake_on_interrupt, Unborrow}; +use embassy::interrupt::InterruptExt; +use embassy::util::{AtomicWaker, Unborrow}; use embassy_hal_common::unborrow; use futures::future::poll_fn; use crate::interrupt; use crate::{pac, peripherals}; -#[cfg(feature = "9160")] -use pac::{saadc_ns as saadc, SAADC_NS as SAADC}; - -#[cfg(not(feature = "9160"))] use pac::{saadc, SAADC}; pub use saadc::{ @@ -31,10 +28,11 @@ pub enum Error {} /// One-shot saadc. Continuous sample mode TODO. pub struct OneShot<'d> { - irq: interrupt::SAADC, phantom: PhantomData<&'d mut peripherals::SAADC>, } +static WAKER: AtomicWaker = AtomicWaker::new(); + /// Used to configure the SAADC peripheral. /// /// See the `Default` impl for suitable default values. @@ -108,18 +106,30 @@ impl<'d> OneShot<'d> { // Disable all events interrupts r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); + irq.set_handler(Self::on_interrupt); + irq.unpend(); + irq.enable(); + Self { - irq, phantom: PhantomData, } } - fn regs(&self) -> &saadc::RegisterBlock { + fn on_interrupt(_ctx: *mut ()) { + let r = Self::regs(); + + if r.events_end.read().bits() != 0 { + r.intenclr.write(|w| w.end().clear()); + WAKER.wake(); + } + } + + fn regs() -> &'static saadc::RegisterBlock { unsafe { &*SAADC::ptr() } } async fn sample_inner(&mut self, pin: PositiveChannel) -> i16 { - let r = self.regs(); + let r = Self::regs(); // Set positive channel r.ch[0].pselp.write(|w| w.pselp().variant(pin)); @@ -144,15 +154,15 @@ impl<'d> OneShot<'d> { // Wait for 'end' event. poll_fn(|cx| { - let r = self.regs(); + let r = Self::regs(); + + WAKER.register(cx.waker()); if r.events_end.read().bits() != 0 { r.events_end.reset(); return Poll::Ready(()); } - wake_on_interrupt(&mut self.irq, cx.waker()); - Poll::Pending }) .await; @@ -164,7 +174,7 @@ impl<'d> OneShot<'d> { impl<'d> Drop for OneShot<'d> { fn drop(&mut self) { - let r = self.regs(); + let r = Self::regs(); r.enable.write(|w| w.enable().disabled()); } } From 6b158ba94aa096619e218f0302eec35baeebaf12 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 1 Sep 2021 23:55:20 +0200 Subject: [PATCH 2/2] nrf/saadc: add example --- examples/nrf/src/bin/saadc.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 examples/nrf/src/bin/saadc.rs diff --git a/examples/nrf/src/bin/saadc.rs b/examples/nrf/src/bin/saadc.rs new file mode 100644 index 00000000..f96cf290 --- /dev/null +++ b/examples/nrf/src/bin/saadc.rs @@ -0,0 +1,25 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] +#![allow(incomplete_features)] + +#[path = "../example_common.rs"] +mod example_common; +use defmt::panic; +use embassy::executor::Spawner; +use embassy::time::{Duration, Timer}; +use embassy_nrf::saadc::{Config, OneShot, Sample}; +use embassy_nrf::{interrupt, Peripherals}; +use example_common::*; + +#[embassy::main] +async fn main(_spawner: Spawner, mut p: Peripherals) { + let config = Config::default(); + let mut saadc = OneShot::new(p.SAADC, interrupt::take!(SAADC), config); + + loop { + let sample = saadc.sample(&mut p.P0_02).await; + info!("sample: {=i16}", sample); + Timer::after(Duration::from_millis(100)).await; + } +}