diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-03-05 21:56:22 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-03-06 00:17:51 +0100 |
| commit | 2dc56082033f650083355464c3106ccb57302338 (patch) | |
| tree | 43cb99d983053b6eb71f71ad78dcd1ab681ba297 | |
| parent | d113fcfe326bd338df2db7733fcf0ae9f230c594 (diff) | |
nrf/saadc: switch to new interrupt binding.
| -rw-r--r-- | embassy-nrf/src/saadc.rs | 62 | ||||
| -rw-r--r-- | examples/nrf52840/src/bin/saadc.rs | 8 | ||||
| -rw-r--r-- | 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 2d01a3dda..af952f03d 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs | |||
| @@ -6,6 +6,7 @@ use core::future::poll_fn; | |||
| 6 | use core::sync::atomic::{compiler_fence, Ordering}; | 6 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 7 | use core::task::Poll; | 7 | use core::task::Poll; |
| 8 | 8 | ||
| 9 | use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; | ||
| 9 | use embassy_hal_common::drop::OnDrop; | 10 | use embassy_hal_common::drop::OnDrop; |
| 10 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; | 11 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; |
| 11 | use embassy_sync::waitqueue::AtomicWaker; | 12 | use embassy_sync::waitqueue::AtomicWaker; |
| @@ -17,7 +18,6 @@ use saadc::oversample::OVERSAMPLE_A; | |||
| 17 | use saadc::resolution::VAL_A; | 18 | use saadc::resolution::VAL_A; |
| 18 | 19 | ||
| 19 | use self::sealed::Input as _; | 20 | use self::sealed::Input as _; |
| 20 | use crate::interrupt::InterruptExt; | ||
| 21 | use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; | 21 | use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; |
| 22 | use crate::timer::{Frequency, Instance as TimerInstance, Timer}; | 22 | use crate::timer::{Frequency, Instance as TimerInstance, Timer}; |
| 23 | use crate::{interrupt, pac, peripherals, Peripheral}; | 23 | use crate::{interrupt, pac, peripherals, Peripheral}; |
| @@ -28,9 +28,30 @@ use crate::{interrupt, pac, peripherals, Peripheral}; | |||
| 28 | #[non_exhaustive] | 28 | #[non_exhaustive] |
| 29 | pub enum Error {} | 29 | pub enum Error {} |
| 30 | 30 | ||
| 31 | /// One-shot and continuous SAADC. | 31 | /// Interrupt handler. |
| 32 | pub struct Saadc<'d, const N: usize> { | 32 | pub struct InterruptHandler { |
| 33 | _p: PeripheralRef<'d, peripherals::SAADC>, | 33 | _private: (), |
| 34 | } | ||
| 35 | |||
| 36 | impl interrupt::Handler<interrupt::SAADC> for InterruptHandler { | ||
| 37 | unsafe fn on_interrupt() { | ||
| 38 | let r = unsafe { &*SAADC::ptr() }; | ||
| 39 | |||
| 40 | if r.events_calibratedone.read().bits() != 0 { | ||
| 41 | r.intenclr.write(|w| w.calibratedone().clear()); | ||
| 42 | WAKER.wake(); | ||
| 43 | } | ||
| 44 | |||
| 45 | if r.events_end.read().bits() != 0 { | ||
| 46 | r.intenclr.write(|w| w.end().clear()); | ||
| 47 | WAKER.wake(); | ||
| 48 | } | ||
| 49 | |||
| 50 | if r.events_started.read().bits() != 0 { | ||
| 51 | r.intenclr.write(|w| w.started().clear()); | ||
| 52 | WAKER.wake(); | ||
| 53 | } | ||
| 54 | } | ||
| 34 | } | 55 | } |
| 35 | 56 | ||
| 36 | static WAKER: AtomicWaker = AtomicWaker::new(); | 57 | static WAKER: AtomicWaker = AtomicWaker::new(); |
| @@ -114,15 +135,20 @@ pub enum CallbackResult { | |||
| 114 | Stop, | 135 | Stop, |
| 115 | } | 136 | } |
| 116 | 137 | ||
| 138 | /// One-shot and continuous SAADC. | ||
| 139 | pub struct Saadc<'d, const N: usize> { | ||
| 140 | _p: PeripheralRef<'d, peripherals::SAADC>, | ||
| 141 | } | ||
| 142 | |||
| 117 | impl<'d, const N: usize> Saadc<'d, N> { | 143 | impl<'d, const N: usize> Saadc<'d, N> { |
| 118 | /// Create a new SAADC driver. | 144 | /// Create a new SAADC driver. |
| 119 | pub fn new( | 145 | pub fn new( |
| 120 | saadc: impl Peripheral<P = peripherals::SAADC> + 'd, | 146 | saadc: impl Peripheral<P = peripherals::SAADC> + 'd, |
| 121 | irq: impl Peripheral<P = interrupt::SAADC> + 'd, | 147 | _irq: impl interrupt::Binding<interrupt::SAADC, InterruptHandler> + 'd, |
| 122 | config: Config, | 148 | config: Config, |
| 123 | channel_configs: [ChannelConfig; N], | 149 | channel_configs: [ChannelConfig; N], |
| 124 | ) -> Self { | 150 | ) -> Self { |
| 125 | into_ref!(saadc, irq); | 151 | into_ref!(saadc); |
| 126 | 152 | ||
| 127 | let r = unsafe { &*SAADC::ptr() }; | 153 | let r = unsafe { &*SAADC::ptr() }; |
| 128 | 154 | ||
| @@ -163,32 +189,12 @@ impl<'d, const N: usize> Saadc<'d, N> { | |||
| 163 | // Disable all events interrupts | 189 | // Disable all events interrupts |
| 164 | r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); | 190 | r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); |
| 165 | 191 | ||
| 166 | irq.set_handler(Self::on_interrupt); | 192 | unsafe { interrupt::SAADC::steal() }.unpend(); |
| 167 | irq.unpend(); | 193 | unsafe { interrupt::SAADC::steal() }.enable(); |
| 168 | irq.enable(); | ||
| 169 | 194 | ||
| 170 | Self { _p: saadc } | 195 | Self { _p: saadc } |
| 171 | } | 196 | } |
| 172 | 197 | ||
| 173 | fn on_interrupt(_ctx: *mut ()) { | ||
| 174 | let r = Self::regs(); | ||
| 175 | |||
| 176 | if r.events_calibratedone.read().bits() != 0 { | ||
| 177 | r.intenclr.write(|w| w.calibratedone().clear()); | ||
| 178 | WAKER.wake(); | ||
| 179 | } | ||
| 180 | |||
| 181 | if r.events_end.read().bits() != 0 { | ||
| 182 | r.intenclr.write(|w| w.end().clear()); | ||
| 183 | WAKER.wake(); | ||
| 184 | } | ||
| 185 | |||
| 186 | if r.events_started.read().bits() != 0 { | ||
| 187 | r.intenclr.write(|w| w.started().clear()); | ||
| 188 | WAKER.wake(); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | fn regs() -> &'static saadc::RegisterBlock { | 198 | fn regs() -> &'static saadc::RegisterBlock { |
| 193 | unsafe { &*SAADC::ptr() } | 199 | unsafe { &*SAADC::ptr() } |
| 194 | } | 200 | } |
diff --git a/examples/nrf52840/src/bin/saadc.rs b/examples/nrf52840/src/bin/saadc.rs index 7cf588090..ffd9a7f4b 100644 --- a/examples/nrf52840/src/bin/saadc.rs +++ b/examples/nrf52840/src/bin/saadc.rs | |||
| @@ -4,17 +4,21 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::info; | 5 | use defmt::info; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::interrupt; | ||
| 8 | use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; | 7 | use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; |
| 8 | use embassy_nrf::{bind_interrupts, saadc}; | ||
| 9 | use embassy_time::{Duration, Timer}; | 9 | use embassy_time::{Duration, Timer}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | SAADC => saadc::InterruptHandler; | ||
| 14 | }); | ||
| 15 | |||
| 12 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 13 | async fn main(_p: Spawner) { | 17 | async fn main(_p: Spawner) { |
| 14 | let mut p = embassy_nrf::init(Default::default()); | 18 | let mut p = embassy_nrf::init(Default::default()); |
| 15 | let config = Config::default(); | 19 | let config = Config::default(); |
| 16 | let channel_config = ChannelConfig::single_ended(&mut p.P0_02); | 20 | let channel_config = ChannelConfig::single_ended(&mut p.P0_02); |
| 17 | let mut saadc = Saadc::new(p.SAADC, interrupt::take!(SAADC), config, [channel_config]); | 21 | let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]); |
| 18 | 22 | ||
| 19 | loop { | 23 | loop { |
| 20 | let mut buf = [0; 1]; | 24 | let mut buf = [0; 1]; |
diff --git a/examples/nrf52840/src/bin/saadc_continuous.rs b/examples/nrf52840/src/bin/saadc_continuous.rs index 2551d15fd..a25e17465 100644 --- a/examples/nrf52840/src/bin/saadc_continuous.rs +++ b/examples/nrf52840/src/bin/saadc_continuous.rs | |||
| @@ -4,14 +4,18 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::info; | 5 | use defmt::info; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_nrf::interrupt; | ||
| 8 | use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc}; | 7 | use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc}; |
| 9 | use embassy_nrf::timer::Frequency; | 8 | use embassy_nrf::timer::Frequency; |
| 9 | use embassy_nrf::{bind_interrupts, saadc}; | ||
| 10 | use embassy_time::Duration; | 10 | use embassy_time::Duration; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 12 | ||
| 13 | // Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer | 13 | // Demonstrates both continuous sampling and scanning multiple channels driven by a PPI linked timer |
| 14 | 14 | ||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | SAADC => saadc::InterruptHandler; | ||
| 17 | }); | ||
| 18 | |||
| 15 | #[embassy_executor::main] | 19 | #[embassy_executor::main] |
| 16 | async fn main(_p: Spawner) { | 20 | async fn main(_p: Spawner) { |
| 17 | let mut p = embassy_nrf::init(Default::default()); | 21 | let mut p = embassy_nrf::init(Default::default()); |
| @@ -21,7 +25,7 @@ async fn main(_p: Spawner) { | |||
| 21 | let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04); | 25 | let channel_3_config = ChannelConfig::single_ended(&mut p.P0_04); |
| 22 | let mut saadc = Saadc::new( | 26 | let mut saadc = Saadc::new( |
| 23 | p.SAADC, | 27 | p.SAADC, |
| 24 | interrupt::take!(SAADC), | 28 | Irqs, |
| 25 | config, | 29 | config, |
| 26 | [channel_1_config, channel_2_config, channel_3_config], | 30 | [channel_1_config, channel_2_config, channel_3_config], |
| 27 | ); | 31 | ); |
