nrf/saadc: switch to new interrupt binding.
This commit is contained in:
parent
d113fcfe32
commit
2dc5608203
3 changed files with 46 additions and 32 deletions
|
@ -6,6 +6,7 @@ use core::future::poll_fn;
|
|||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
@ -17,7 +18,6 @@ use saadc::oversample::OVERSAMPLE_A;
|
|||
use saadc::resolution::VAL_A;
|
||||
|
||||
use self::sealed::Input as _;
|
||||
use crate::interrupt::InterruptExt;
|
||||
use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
|
||||
use crate::timer::{Frequency, Instance as TimerInstance, Timer};
|
||||
use crate::{interrupt, pac, peripherals, Peripheral};
|
||||
|
@ -28,9 +28,30 @@ use crate::{interrupt, pac, peripherals, Peripheral};
|
|||
#[non_exhaustive]
|
||||
pub enum Error {}
|
||||
|
||||
/// One-shot and continuous SAADC.
|
||||
pub struct Saadc<'d, const N: usize> {
|
||||
_p: PeripheralRef<'d, peripherals::SAADC>,
|
||||
/// Interrupt handler.
|
||||
pub struct InterruptHandler {
|
||||
_private: (),
|
||||
}
|
||||
|
||||
impl interrupt::Handler<interrupt::SAADC> for InterruptHandler {
|
||||
unsafe fn on_interrupt() {
|
||||
let r = unsafe { &*SAADC::ptr() };
|
||||
|
||||
if r.events_calibratedone.read().bits() != 0 {
|
||||
r.intenclr.write(|w| w.calibratedone().clear());
|
||||
WAKER.wake();
|
||||
}
|
||||
|
||||
if r.events_end.read().bits() != 0 {
|
||||
r.intenclr.write(|w| w.end().clear());
|
||||
WAKER.wake();
|
||||
}
|
||||
|
||||
if r.events_started.read().bits() != 0 {
|
||||
r.intenclr.write(|w| w.started().clear());
|
||||
WAKER.wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
@ -114,15 +135,20 @@ pub enum CallbackResult {
|
|||
Stop,
|
||||
}
|
||||
|
||||
/// One-shot and continuous SAADC.
|
||||
pub struct Saadc<'d, const N: usize> {
|
||||
_p: PeripheralRef<'d, peripherals::SAADC>,
|
||||
}
|
||||
|
||||
impl<'d, const N: usize> Saadc<'d, N> {
|
||||
/// Create a new SAADC driver.
|
||||
pub fn new(
|
||||
saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
|
||||
irq: impl Peripheral<P = interrupt::SAADC> + 'd,
|
||||
_irq: impl interrupt::Binding<interrupt::SAADC, InterruptHandler> + 'd,
|
||||
config: Config,
|
||||
channel_configs: [ChannelConfig; N],
|
||||
) -> Self {
|
||||
into_ref!(saadc, irq);
|
||||
into_ref!(saadc);
|
||||
|
||||
let r = unsafe { &*SAADC::ptr() };
|
||||
|
||||
|
@ -163,32 +189,12 @@ impl<'d, const N: usize> Saadc<'d, N> {
|
|||
// Disable all events interrupts
|
||||
r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) });
|
||||
|
||||
irq.set_handler(Self::on_interrupt);
|
||||
irq.unpend();
|
||||
irq.enable();
|
||||
unsafe { interrupt::SAADC::steal() }.unpend();
|
||||
unsafe { interrupt::SAADC::steal() }.enable();
|
||||
|
||||
Self { _p: saadc }
|
||||
}
|
||||
|
||||
fn on_interrupt(_ctx: *mut ()) {
|
||||
let r = Self::regs();
|
||||
|
||||
if r.events_calibratedone.read().bits() != 0 {
|
||||
r.intenclr.write(|w| w.calibratedone().clear());
|
||||
WAKER.wake();
|
||||
}
|
||||
|
||||
if r.events_end.read().bits() != 0 {
|
||||
r.intenclr.write(|w| w.end().clear());
|
||||
WAKER.wake();
|
||||
}
|
||||
|
||||
if r.events_started.read().bits() != 0 {
|
||||
r.intenclr.write(|w| w.started().clear());
|
||||
WAKER.wake();
|
||||
}
|
||||
}
|
||||
|
||||
fn regs() -> &'static saadc::RegisterBlock {
|
||||
unsafe { &*SAADC::ptr() }
|
||||
}
|
||||
|
|
|
@ -4,17 +4,21 @@
|
|||
|
||||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_nrf::interrupt;
|
||||
use embassy_nrf::saadc::{ChannelConfig, Config, Saadc};
|
||||
use embassy_nrf::{bind_interrupts, saadc};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
SAADC => saadc::InterruptHandler;
|
||||
});
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_p: Spawner) {
|
||||
let mut p = embassy_nrf::init(Default::default());
|
||||
let config = Config::default();
|
||||
let channel_config = ChannelConfig::single_ended(&mut p.P0_02);
|
||||
let mut saadc = Saadc::new(p.SAADC, interrupt::take!(SAADC), config, [channel_config]);
|
||||
let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]);
|
||||
|
||||
loop {
|
||||
let mut buf = [0; 1];
|
||||
|
|
|
@ -4,14 +4,18 @@
|
|||
|
||||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_nrf::interrupt;
|
||||
use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc};
|
||||
use embassy_nrf::timer::Frequency;
|
||||
use embassy_nrf::{bind_interrupts, saadc};
|
||||
use embassy_time::Duration;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
// Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer
|
||||
|
||||
bind_interrupts!(struct Irqs {
|
||||
SAADC => saadc::InterruptHandler;
|
||||
});
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_p: Spawner) {
|
||||
let mut p = embassy_nrf::init(Default::default());
|
||||
|
@ -21,7 +25,7 @@ async fn main(_p: Spawner) {
|
|||
let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04);
|
||||
let mut saadc = Saadc::new(
|
||||
p.SAADC,
|
||||
interrupt::take!(SAADC),
|
||||
Irqs,
|
||||
config,
|
||||
[channel_1_config, channel_2_config, channel_3_config],
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue