aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-09-01 23:59:56 +0200
committerGitHub <[email protected]>2021-09-01 23:59:56 +0200
commitdb3cb02032fd6b861b2c39a0a354767cc72af1df (patch)
treef8b262a799495b46fa20cacfff9dd15b6dae7236
parentbc68657c2397008087bdd6afcd2088ee649a0058 (diff)
parent6b158ba94aa096619e218f0302eec35baeebaf12 (diff)
Merge pull request #383 from embassy-rs/saadc-fixes
nrf: Saadc fixes
-rw-r--r--embassy-nrf/src/saadc.rs36
-rw-r--r--examples/nrf/src/bin/saadc.rs25
2 files changed, 48 insertions, 13 deletions
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 7bc38f1d3..bc7f34716 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -2,17 +2,14 @@ use core::future::Future;
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5use embassy::util::{wake_on_interrupt, Unborrow}; 5use embassy::interrupt::InterruptExt;
6use embassy::util::{AtomicWaker, Unborrow};
6use embassy_hal_common::unborrow; 7use embassy_hal_common::unborrow;
7use futures::future::poll_fn; 8use futures::future::poll_fn;
8 9
9use crate::interrupt; 10use crate::interrupt;
10use crate::{pac, peripherals}; 11use crate::{pac, peripherals};
11 12
12#[cfg(feature = "9160")]
13use pac::{saadc_ns as saadc, SAADC_NS as SAADC};
14
15#[cfg(not(feature = "9160"))]
16use pac::{saadc, SAADC}; 13use pac::{saadc, SAADC};
17 14
18pub use saadc::{ 15pub use saadc::{
@@ -31,10 +28,11 @@ pub enum Error {}
31 28
32/// One-shot saadc. Continuous sample mode TODO. 29/// One-shot saadc. Continuous sample mode TODO.
33pub struct OneShot<'d> { 30pub struct OneShot<'d> {
34 irq: interrupt::SAADC,
35 phantom: PhantomData<&'d mut peripherals::SAADC>, 31 phantom: PhantomData<&'d mut peripherals::SAADC>,
36} 32}
37 33
34static WAKER: AtomicWaker = AtomicWaker::new();
35
38/// Used to configure the SAADC peripheral. 36/// Used to configure the SAADC peripheral.
39/// 37///
40/// See the `Default` impl for suitable default values. 38/// See the `Default` impl for suitable default values.
@@ -108,18 +106,30 @@ impl<'d> OneShot<'d> {
108 // Disable all events interrupts 106 // Disable all events interrupts
109 r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); 107 r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) });
110 108
109 irq.set_handler(Self::on_interrupt);
110 irq.unpend();
111 irq.enable();
112
111 Self { 113 Self {
112 irq,
113 phantom: PhantomData, 114 phantom: PhantomData,
114 } 115 }
115 } 116 }
116 117
117 fn regs(&self) -> &saadc::RegisterBlock { 118 fn on_interrupt(_ctx: *mut ()) {
119 let r = Self::regs();
120
121 if r.events_end.read().bits() != 0 {
122 r.intenclr.write(|w| w.end().clear());
123 WAKER.wake();
124 }
125 }
126
127 fn regs() -> &'static saadc::RegisterBlock {
118 unsafe { &*SAADC::ptr() } 128 unsafe { &*SAADC::ptr() }
119 } 129 }
120 130
121 async fn sample_inner(&mut self, pin: PositiveChannel) -> i16 { 131 async fn sample_inner(&mut self, pin: PositiveChannel) -> i16 {
122 let r = self.regs(); 132 let r = Self::regs();
123 133
124 // Set positive channel 134 // Set positive channel
125 r.ch[0].pselp.write(|w| w.pselp().variant(pin)); 135 r.ch[0].pselp.write(|w| w.pselp().variant(pin));
@@ -144,15 +154,15 @@ impl<'d> OneShot<'d> {
144 154
145 // Wait for 'end' event. 155 // Wait for 'end' event.
146 poll_fn(|cx| { 156 poll_fn(|cx| {
147 let r = self.regs(); 157 let r = Self::regs();
158
159 WAKER.register(cx.waker());
148 160
149 if r.events_end.read().bits() != 0 { 161 if r.events_end.read().bits() != 0 {
150 r.events_end.reset(); 162 r.events_end.reset();
151 return Poll::Ready(()); 163 return Poll::Ready(());
152 } 164 }
153 165
154 wake_on_interrupt(&mut self.irq, cx.waker());
155
156 Poll::Pending 166 Poll::Pending
157 }) 167 })
158 .await; 168 .await;
@@ -164,7 +174,7 @@ impl<'d> OneShot<'d> {
164 174
165impl<'d> Drop for OneShot<'d> { 175impl<'d> Drop for OneShot<'d> {
166 fn drop(&mut self) { 176 fn drop(&mut self) {
167 let r = self.regs(); 177 let r = Self::regs();
168 r.enable.write(|w| w.enable().disabled()); 178 r.enable.write(|w| w.enable().disabled());
169 } 179 }
170} 180}
diff --git a/examples/nrf/src/bin/saadc.rs b/examples/nrf/src/bin/saadc.rs
new file mode 100644
index 000000000..f96cf2903
--- /dev/null
+++ b/examples/nrf/src/bin/saadc.rs
@@ -0,0 +1,25 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4#![allow(incomplete_features)]
5
6#[path = "../example_common.rs"]
7mod example_common;
8use defmt::panic;
9use embassy::executor::Spawner;
10use embassy::time::{Duration, Timer};
11use embassy_nrf::saadc::{Config, OneShot, Sample};
12use embassy_nrf::{interrupt, Peripherals};
13use example_common::*;
14
15#[embassy::main]
16async fn main(_spawner: Spawner, mut p: Peripherals) {
17 let config = Config::default();
18 let mut saadc = OneShot::new(p.SAADC, interrupt::take!(SAADC), config);
19
20 loop {
21 let sample = saadc.sample(&mut p.P0_02).await;
22 info!("sample: {=i16}", sample);
23 Timer::after(Duration::from_millis(100)).await;
24 }
25}