From 2dc56082033f650083355464c3106ccb57302338 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sun, 5 Mar 2023 21:56:22 +0100 Subject: [PATCH] nrf/saadc: switch to new interrupt binding. --- embassy-nrf/src/saadc.rs | 62 ++++++++++--------- examples/nrf52840/src/bin/saadc.rs | 8 ++- examples/nrf52840/src/bin/saadc_continuous.rs | 8 ++- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 2d01a3dd..af952f03 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -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 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

+ 'd, - irq: impl Peripheral

+ 'd, + _irq: impl interrupt::Binding + '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() } } diff --git a/examples/nrf52840/src/bin/saadc.rs b/examples/nrf52840/src/bin/saadc.rs index 7cf58809..ffd9a7f4 100644 --- a/examples/nrf52840/src/bin/saadc.rs +++ b/examples/nrf52840/src/bin/saadc.rs @@ -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]; diff --git a/examples/nrf52840/src/bin/saadc_continuous.rs b/examples/nrf52840/src/bin/saadc_continuous.rs index 2551d15f..a25e1746 100644 --- a/examples/nrf52840/src/bin/saadc_continuous.rs +++ b/examples/nrf52840/src/bin/saadc_continuous.rs @@ -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], );