Merge pull request #383 from embassy-rs/saadc-fixes

nrf: Saadc fixes
This commit is contained in:
Dario Nieuwenhuis 2021-09-01 23:59:56 +02:00 committed by GitHub
commit db3cb02032
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 13 deletions

View file

@ -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());
}
}

View file

@ -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;
}
}