commit
db3cb02032
2 changed files with 48 additions and 13 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
25
examples/nrf/src/bin/saadc.rs
Normal file
25
examples/nrf/src/bin/saadc.rs
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue