aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src/saadc.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-07-23 15:13:47 +0200
committerDario Nieuwenhuis <[email protected]>2022-07-23 15:13:47 +0200
commit709df0dc1dfff577fb79bbc2f67ea84670072456 (patch)
tree4a54aee47c0d3881b9e0bc809e075728cee8eeae /embassy-nrf/src/saadc.rs
parent19d1ef0e29fdd0bf0407cbe37c388e8a87e7ddfe (diff)
nrf: replace PhantomData usages with PeripheralRef.
Diffstat (limited to 'embassy-nrf/src/saadc.rs')
-rw-r--r--embassy-nrf/src/saadc.rs134
1 files changed, 63 insertions, 71 deletions
diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs
index 644ffa1f0..6ddc70e52 100644
--- a/embassy-nrf/src/saadc.rs
+++ b/embassy-nrf/src/saadc.rs
@@ -1,11 +1,10 @@
1#![macro_use] 1#![macro_use]
2 2
3use core::marker::PhantomData;
4use core::sync::atomic::{compiler_fence, Ordering}; 3use core::sync::atomic::{compiler_fence, Ordering};
5use core::task::Poll; 4use core::task::Poll;
6 5
7use embassy::waitqueue::AtomicWaker; 6use embassy::waitqueue::AtomicWaker;
8use embassy_hal_common::{impl_peripheral, into_ref}; 7use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
9use futures::future::poll_fn; 8use futures::future::poll_fn;
10use pac::{saadc, SAADC}; 9use pac::{saadc, SAADC};
11use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; 10use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
@@ -14,6 +13,7 @@ pub(crate) use saadc::ch::pselp::PSELP_A as InputChannel;
14use saadc::oversample::OVERSAMPLE_A; 13use saadc::oversample::OVERSAMPLE_A;
15use saadc::resolution::VAL_A; 14use saadc::resolution::VAL_A;
16 15
16use self::sealed::Input as _;
17use crate::interrupt::InterruptExt; 17use crate::interrupt::InterruptExt;
18use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; 18use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
19use crate::timer::{Frequency, Instance as TimerInstance, Timer}; 19use crate::timer::{Frequency, Instance as TimerInstance, Timer};
@@ -26,7 +26,7 @@ pub enum Error {}
26 26
27/// One-shot and continuous SAADC. 27/// One-shot and continuous SAADC.
28pub struct Saadc<'d, const N: usize> { 28pub struct Saadc<'d, const N: usize> {
29 phantom: PhantomData<&'d mut peripherals::SAADC>, 29 _p: PeripheralRef<'d, peripherals::SAADC>,
30} 30}
31 31
32static WAKER: AtomicWaker = AtomicWaker::new(); 32static WAKER: AtomicWaker = AtomicWaker::new();
@@ -66,63 +66,11 @@ pub struct ChannelConfig<'d> {
66 /// Acquisition time in microseconds. 66 /// Acquisition time in microseconds.
67 pub time: Time, 67 pub time: Time,
68 /// Positive channel to sample 68 /// Positive channel to sample
69 p_channel: InputChannel, 69 p_channel: PeripheralRef<'d, AnyInput>,
70 /// An optional negative channel to sample 70 /// An optional negative channel to sample
71 n_channel: Option<InputChannel>, 71 n_channel: Option<PeripheralRef<'d, AnyInput>>,
72
73 phantom: PhantomData<&'d ()>,
74}
75
76/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
77/// internal voltage.
78pub struct VddInput;
79
80impl_peripheral!(VddInput);
81
82impl sealed::Input for VddInput {
83 #[cfg(not(feature = "_nrf9160"))]
84 fn channel(&self) -> InputChannel {
85 InputChannel::VDD
86 }
87 #[cfg(feature = "_nrf9160")]
88 fn channel(&self) -> InputChannel {
89 InputChannel::VDDGPIO
90 }
91}
92impl Input for VddInput {}
93
94/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
95/// VDDH / 5 voltage.
96#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
97pub struct VddhDiv5Input;
98
99#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
100impl_peripheral!(VddhDiv5Input);
101
102#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
103impl sealed::Input for VddhDiv5Input {
104 fn channel(&self) -> InputChannel {
105 InputChannel::VDDHDIV5
106 }
107}
108
109#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
110impl Input for VddhDiv5Input {}
111
112pub struct AnyInput {
113 channel: InputChannel,
114}
115
116impl_peripheral!(AnyInput);
117
118impl sealed::Input for AnyInput {
119 fn channel(&self) -> InputChannel {
120 self.channel
121 }
122} 72}
123 73
124impl Input for AnyInput {}
125
126impl<'d> ChannelConfig<'d> { 74impl<'d> ChannelConfig<'d> {
127 /// Default configuration for single ended channel sampling. 75 /// Default configuration for single ended channel sampling.
128 pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self { 76 pub fn single_ended(input: impl Peripheral<P = impl Input> + 'd) -> Self {
@@ -132,9 +80,8 @@ impl<'d> ChannelConfig<'d> {
132 gain: Gain::GAIN1_6, 80 gain: Gain::GAIN1_6,
133 resistor: Resistor::BYPASS, 81 resistor: Resistor::BYPASS,
134 time: Time::_10US, 82 time: Time::_10US,
135 p_channel: input.channel(), 83 p_channel: input.map_into(),
136 n_channel: None, 84 n_channel: None,
137 phantom: PhantomData,
138 } 85 }
139 } 86 }
140 /// Default configuration for differential channel sampling. 87 /// Default configuration for differential channel sampling.
@@ -148,9 +95,8 @@ impl<'d> ChannelConfig<'d> {
148 gain: Gain::GAIN1_6, 95 gain: Gain::GAIN1_6,
149 resistor: Resistor::BYPASS, 96 resistor: Resistor::BYPASS,
150 time: Time::_10US, 97 time: Time::_10US,
151 p_channel: p_input.channel(), 98 p_channel: p_input.map_into(),
152 n_channel: Some(n_input.channel()), 99 n_channel: Some(n_input.map_into()),
153 phantom: PhantomData,
154 } 100 }
155 } 101 }
156} 102}
@@ -167,12 +113,12 @@ pub enum SamplerState {
167 113
168impl<'d, const N: usize> Saadc<'d, N> { 114impl<'d, const N: usize> Saadc<'d, N> {
169 pub fn new( 115 pub fn new(
170 _saadc: impl Peripheral<P = peripherals::SAADC> + 'd, 116 saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
171 irq: impl Peripheral<P = interrupt::SAADC> + 'd, 117 irq: impl Peripheral<P = interrupt::SAADC> + 'd,
172 config: Config, 118 config: Config,
173 channel_configs: [ChannelConfig; N], 119 channel_configs: [ChannelConfig; N],
174 ) -> Self { 120 ) -> Self {
175 into_ref!(irq); 121 into_ref!(saadc, irq);
176 122
177 let r = unsafe { &*SAADC::ptr() }; 123 let r = unsafe { &*SAADC::ptr() };
178 124
@@ -184,9 +130,11 @@ impl<'d, const N: usize> Saadc<'d, N> {
184 r.oversample.write(|w| w.oversample().variant(oversample.into())); 130 r.oversample.write(|w| w.oversample().variant(oversample.into()));
185 131
186 for (i, cc) in channel_configs.iter().enumerate() { 132 for (i, cc) in channel_configs.iter().enumerate() {
187 r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel)); 133 r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel.channel()));
188 if let Some(n_channel) = cc.n_channel { 134 if let Some(n_channel) = &cc.n_channel {
189 r.ch[i].pseln.write(|w| unsafe { w.pseln().bits(n_channel as u8) }); 135 r.ch[i]
136 .pseln
137 .write(|w| unsafe { w.pseln().bits(n_channel.channel() as u8) });
190 } 138 }
191 r.ch[i].config.write(|w| { 139 r.ch[i].config.write(|w| {
192 w.refsel().variant(cc.reference.into()); 140 w.refsel().variant(cc.reference.into());
@@ -215,7 +163,7 @@ impl<'d, const N: usize> Saadc<'d, N> {
215 irq.unpend(); 163 irq.unpend();
216 irq.enable(); 164 irq.enable();
217 165
218 Self { phantom: PhantomData } 166 Self { _p: saadc }
219 } 167 }
220 168
221 fn on_interrupt(_ctx: *mut ()) { 169 fn on_interrupt(_ctx: *mut ()) {
@@ -674,7 +622,7 @@ pub(crate) mod sealed {
674} 622}
675 623
676/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal. 624/// An input that can be used as either or negative end of a ADC differential in the SAADC periperhal.
677pub trait Input: sealed::Input + Peripheral<P = Self> + Sized { 625pub trait Input: sealed::Input + Into<AnyInput> + Peripheral<P = Self> + Sized + 'static {
678 fn degrade_saadc(self) -> AnyInput { 626 fn degrade_saadc(self) -> AnyInput {
679 AnyInput { 627 AnyInput {
680 channel: self.channel(), 628 channel: self.channel(),
@@ -682,13 +630,57 @@ pub trait Input: sealed::Input + Peripheral<P = Self> + Sized {
682 } 630 }
683} 631}
684 632
633pub struct AnyInput {
634 channel: InputChannel,
635}
636
637impl_peripheral!(AnyInput);
638
639impl sealed::Input for AnyInput {
640 fn channel(&self) -> InputChannel {
641 self.channel
642 }
643}
644
645impl Input for AnyInput {}
646
685macro_rules! impl_saadc_input { 647macro_rules! impl_saadc_input {
686 ($pin:ident, $ch:ident) => { 648 ($pin:ident, $ch:ident) => {
687 impl crate::saadc::sealed::Input for crate::peripherals::$pin { 649 impl_saadc_input!(@local, crate::peripherals::$pin, $ch);
650 };
651 (@local, $pin:ty, $ch:ident) => {
652 impl crate::saadc::sealed::Input for $pin {
688 fn channel(&self) -> crate::saadc::InputChannel { 653 fn channel(&self) -> crate::saadc::InputChannel {
689 crate::saadc::InputChannel::$ch 654 crate::saadc::InputChannel::$ch
690 } 655 }
691 } 656 }
692 impl crate::saadc::Input for crate::peripherals::$pin {} 657 impl crate::saadc::Input for $pin {}
658
659 impl From<$pin> for crate::saadc::AnyInput {
660 fn from(val: $pin) -> Self {
661 crate::saadc::Input::degrade_saadc(val)
662 }
663 }
693 }; 664 };
694} 665}
666
667/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
668/// internal voltage.
669pub struct VddInput;
670
671impl_peripheral!(VddInput);
672#[cfg(not(feature = "_nrf9160"))]
673impl_saadc_input!(@local, VddInput, VDD);
674#[cfg(feature = "_nrf9160")]
675impl_saadc_input!(@local, VddInput, VDDGPIO);
676
677/// A dummy `Input` pin implementation for SAADC peripheral sampling from the
678/// VDDH / 5 voltage.
679#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
680pub struct VddhDiv5Input;
681
682#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
683impl_peripheral!(VddhDiv5Input);
684
685#[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))]
686impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5);