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