diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-07-23 15:13:47 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-07-23 15:13:47 +0200 |
| commit | 709df0dc1dfff577fb79bbc2f67ea84670072456 (patch) | |
| tree | 4a54aee47c0d3881b9e0bc809e075728cee8eeae /embassy-nrf/src/saadc.rs | |
| parent | 19d1ef0e29fdd0bf0407cbe37c388e8a87e7ddfe (diff) | |
nrf: replace PhantomData usages with PeripheralRef.
Diffstat (limited to 'embassy-nrf/src/saadc.rs')
| -rw-r--r-- | embassy-nrf/src/saadc.rs | 134 |
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 | ||
| 3 | use core::marker::PhantomData; | ||
| 4 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 5 | use core::task::Poll; | 4 | use core::task::Poll; |
| 6 | 5 | ||
| 7 | use embassy::waitqueue::AtomicWaker; | 6 | use embassy::waitqueue::AtomicWaker; |
| 8 | use embassy_hal_common::{impl_peripheral, into_ref}; | 7 | use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; |
| 9 | use futures::future::poll_fn; | 8 | use futures::future::poll_fn; |
| 10 | use pac::{saadc, SAADC}; | 9 | use pac::{saadc, SAADC}; |
| 11 | use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}; | 10 | use 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; | |||
| 14 | use saadc::oversample::OVERSAMPLE_A; | 13 | use saadc::oversample::OVERSAMPLE_A; |
| 15 | use saadc::resolution::VAL_A; | 14 | use saadc::resolution::VAL_A; |
| 16 | 15 | ||
| 16 | use self::sealed::Input as _; | ||
| 17 | use crate::interrupt::InterruptExt; | 17 | use crate::interrupt::InterruptExt; |
| 18 | use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; | 18 | use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; |
| 19 | use crate::timer::{Frequency, Instance as TimerInstance, Timer}; | 19 | use 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. |
| 28 | pub struct Saadc<'d, const N: usize> { | 28 | pub struct Saadc<'d, const N: usize> { |
| 29 | phantom: PhantomData<&'d mut peripherals::SAADC>, | 29 | _p: PeripheralRef<'d, peripherals::SAADC>, |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | static WAKER: AtomicWaker = AtomicWaker::new(); | 32 | static 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. | ||
| 78 | pub struct VddInput; | ||
| 79 | |||
| 80 | impl_peripheral!(VddInput); | ||
| 81 | |||
| 82 | impl 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 | } | ||
| 92 | impl 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"))] | ||
| 97 | pub struct VddhDiv5Input; | ||
| 98 | |||
| 99 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] | ||
| 100 | impl_peripheral!(VddhDiv5Input); | ||
| 101 | |||
| 102 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] | ||
| 103 | impl 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"))] | ||
| 110 | impl Input for VddhDiv5Input {} | ||
| 111 | |||
| 112 | pub struct AnyInput { | ||
| 113 | channel: InputChannel, | ||
| 114 | } | ||
| 115 | |||
| 116 | impl_peripheral!(AnyInput); | ||
| 117 | |||
| 118 | impl sealed::Input for AnyInput { | ||
| 119 | fn channel(&self) -> InputChannel { | ||
| 120 | self.channel | ||
| 121 | } | ||
| 122 | } | 72 | } |
| 123 | 73 | ||
| 124 | impl Input for AnyInput {} | ||
| 125 | |||
| 126 | impl<'d> ChannelConfig<'d> { | 74 | impl<'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 | ||
| 168 | impl<'d, const N: usize> Saadc<'d, N> { | 114 | impl<'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. |
| 677 | pub trait Input: sealed::Input + Peripheral<P = Self> + Sized { | 625 | pub 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 | ||
| 633 | pub struct AnyInput { | ||
| 634 | channel: InputChannel, | ||
| 635 | } | ||
| 636 | |||
| 637 | impl_peripheral!(AnyInput); | ||
| 638 | |||
| 639 | impl sealed::Input for AnyInput { | ||
| 640 | fn channel(&self) -> InputChannel { | ||
| 641 | self.channel | ||
| 642 | } | ||
| 643 | } | ||
| 644 | |||
| 645 | impl Input for AnyInput {} | ||
| 646 | |||
| 685 | macro_rules! impl_saadc_input { | 647 | macro_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. | ||
| 669 | pub struct VddInput; | ||
| 670 | |||
| 671 | impl_peripheral!(VddInput); | ||
| 672 | #[cfg(not(feature = "_nrf9160"))] | ||
| 673 | impl_saadc_input!(@local, VddInput, VDD); | ||
| 674 | #[cfg(feature = "_nrf9160")] | ||
| 675 | impl_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"))] | ||
| 680 | pub struct VddhDiv5Input; | ||
| 681 | |||
| 682 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] | ||
| 683 | impl_peripheral!(VddhDiv5Input); | ||
| 684 | |||
| 685 | #[cfg(any(feature = "_nrf5340-app", feature = "nrf52833", feature = "nrf52840"))] | ||
| 686 | impl_saadc_input!(@local, VddhDiv5Input, VDDHDIV5); | ||
