aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-03-05 21:56:22 +0100
committerDario Nieuwenhuis <[email protected]>2023-03-06 00:17:51 +0100
commit2dc56082033f650083355464c3106ccb57302338 (patch)
tree43cb99d983053b6eb71f71ad78dcd1ab681ba297
parentd113fcfe326bd338df2db7733fcf0ae9f230c594 (diff)
nrf/saadc: switch to new interrupt binding.
-rw-r--r--embassy-nrf/src/saadc.rs62
-rw-r--r--examples/nrf52840/src/bin/saadc.rs8
-rw-r--r--examples/nrf52840/src/bin/saadc_continuous.rs8
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;
6use core::sync::atomic::{compiler_fence, Ordering}; 6use core::sync::atomic::{compiler_fence, Ordering};
7use core::task::Poll; 7use core::task::Poll;
8 8
9use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
9use embassy_hal_common::drop::OnDrop; 10use embassy_hal_common::drop::OnDrop;
10use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; 11use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
11use embassy_sync::waitqueue::AtomicWaker; 12use embassy_sync::waitqueue::AtomicWaker;
@@ -17,7 +18,6 @@ use saadc::oversample::OVERSAMPLE_A;
17use saadc::resolution::VAL_A; 18use saadc::resolution::VAL_A;
18 19
19use self::sealed::Input as _; 20use self::sealed::Input as _;
20use crate::interrupt::InterruptExt;
21use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; 21use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
22use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 22use crate::timer::{Frequency, Instance as TimerInstance, Timer};
23use crate::{interrupt, pac, peripherals, Peripheral}; 23use crate::{interrupt, pac, peripherals, Peripheral};
@@ -28,9 +28,30 @@ use crate::{interrupt, pac, peripherals, Peripheral};
28#[non_exhaustive] 28#[non_exhaustive]
29pub enum Error {} 29pub enum Error {}
30 30
31/// One-shot and continuous SAADC. 31/// Interrupt handler.
32pub struct Saadc<'d, const N: usize> { 32pub struct InterruptHandler {
33 _p: PeripheralRef<'d, peripherals::SAADC>, 33 _private: (),
34}
35
36impl 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
36static WAKER: AtomicWaker = AtomicWaker::new(); 57static 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.
139pub struct Saadc<'d, const N: usize> {
140 _p: PeripheralRef<'d, peripherals::SAADC>,
141}
142
117impl<'d, const N: usize> Saadc<'d, N> { 143impl<'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
5use defmt::info; 5use defmt::info;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::interrupt;
8use embassy_nrf::saadc::{ChannelConfig, Config, Saadc}; 7use embassy_nrf::saadc::{ChannelConfig, Config, Saadc};
8use embassy_nrf::{bind_interrupts, saadc};
9use embassy_time::{Duration, Timer}; 9use embassy_time::{Duration, Timer};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12bind_interrupts!(struct Irqs {
13 SAADC => saadc::InterruptHandler;
14});
15
12#[embassy_executor::main] 16#[embassy_executor::main]
13async fn main(_p: Spawner) { 17async 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
5use defmt::info; 5use defmt::info;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_nrf::interrupt;
8use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc}; 7use embassy_nrf::saadc::{CallbackResult, ChannelConfig, Config, Saadc};
9use embassy_nrf::timer::Frequency; 8use embassy_nrf::timer::Frequency;
9use embassy_nrf::{bind_interrupts, saadc};
10use embassy_time::Duration; 10use embassy_time::Duration;
11use {defmt_rtt as _, panic_probe as _}; 11use {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
15bind_interrupts!(struct Irqs {
16 SAADC => saadc::InterruptHandler;
17});
18
15#[embassy_executor::main] 19#[embassy_executor::main]
16async fn main(_p: Spawner) { 20async 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 );