diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-09-01 23:59:56 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-09-01 23:59:56 +0200 |
| commit | db3cb02032fd6b861b2c39a0a354767cc72af1df (patch) | |
| tree | f8b262a799495b46fa20cacfff9dd15b6dae7236 | |
| parent | bc68657c2397008087bdd6afcd2088ee649a0058 (diff) | |
| parent | 6b158ba94aa096619e218f0302eec35baeebaf12 (diff) | |
Merge pull request #383 from embassy-rs/saadc-fixes
nrf: Saadc fixes
| -rw-r--r-- | embassy-nrf/src/saadc.rs | 36 | ||||
| -rw-r--r-- | examples/nrf/src/bin/saadc.rs | 25 |
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; | |||
| 2 | use core::marker::PhantomData; | 2 | use core::marker::PhantomData; |
| 3 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 4 | use core::task::Poll; | 4 | use core::task::Poll; |
| 5 | use embassy::util::{wake_on_interrupt, Unborrow}; | 5 | use embassy::interrupt::InterruptExt; |
| 6 | use embassy::util::{AtomicWaker, Unborrow}; | ||
| 6 | use embassy_hal_common::unborrow; | 7 | use embassy_hal_common::unborrow; |
| 7 | use futures::future::poll_fn; | 8 | use futures::future::poll_fn; |
| 8 | 9 | ||
| 9 | use crate::interrupt; | 10 | use crate::interrupt; |
| 10 | use crate::{pac, peripherals}; | 11 | use crate::{pac, peripherals}; |
| 11 | 12 | ||
| 12 | #[cfg(feature = "9160")] | ||
| 13 | use pac::{saadc_ns as saadc, SAADC_NS as SAADC}; | ||
| 14 | |||
| 15 | #[cfg(not(feature = "9160"))] | ||
| 16 | use pac::{saadc, SAADC}; | 13 | use pac::{saadc, SAADC}; |
| 17 | 14 | ||
| 18 | pub use saadc::{ | 15 | pub 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. |
| 33 | pub struct OneShot<'d> { | 30 | pub 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 | ||
| 34 | static 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 | ||
| 165 | impl<'d> Drop for OneShot<'d> { | 175 | impl<'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"] | ||
| 7 | mod example_common; | ||
| 8 | use defmt::panic; | ||
| 9 | use embassy::executor::Spawner; | ||
| 10 | use embassy::time::{Duration, Timer}; | ||
| 11 | use embassy_nrf::saadc::{Config, OneShot, Sample}; | ||
| 12 | use embassy_nrf::{interrupt, Peripherals}; | ||
| 13 | use example_common::*; | ||
| 14 | |||
| 15 | #[embassy::main] | ||
| 16 | async 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 | } | ||
