diff --git a/embassy-nrf/src/saadc.rs b/embassy-nrf/src/saadc.rs index 7fffea1b6..bc83b5b61 100644 --- a/embassy-nrf/src/saadc.rs +++ b/embassy-nrf/src/saadc.rs @@ -18,10 +18,10 @@ use pac::{saadc, SAADC}; // We treat the positive and negative channels with the same enum values to keep our type tidy and given they are the same pub(crate) use saadc::ch::pselp::PSELP_A as InputChannel; -pub use saadc::{ - ch::config::{GAIN_A as Gain, REFSEL_A as Reference, RESP_A as Resistor, TACQ_A as Time}, - oversample::OVERSAMPLE_A as Oversample, - resolution::VAL_A as Resolution, +use saadc::{ + ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A}, + oversample::OVERSAMPLE_A, + resolution::VAL_A, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -161,8 +161,9 @@ impl<'d, const N: usize> Saadc<'d, N> { // Configure channels r.enable.write(|w| w.enable().enabled()); - r.resolution.write(|w| w.val().variant(resolution)); - r.oversample.write(|w| w.oversample().variant(oversample)); + r.resolution.write(|w| w.val().variant(resolution.into())); + r.oversample + .write(|w| w.oversample().variant(oversample.into())); for (i, cc) in channel_configs.iter().enumerate() { r.ch[i].pselp.write(|w| w.pselp().variant(cc.p_channel)); @@ -172,15 +173,15 @@ impl<'d, const N: usize> Saadc<'d, N> { .write(|w| unsafe { w.pseln().bits(n_channel as u8) }); } r.ch[i].config.write(|w| { - w.refsel().variant(cc.reference); - w.gain().variant(cc.gain); - w.tacq().variant(cc.time); + w.refsel().variant(cc.reference.into()); + w.gain().variant(cc.gain.into()); + w.tacq().variant(cc.time.into()); if cc.n_channel.is_none() { w.mode().se(); } else { w.mode().diff(); } - w.resp().variant(cc.resistor); + w.resp().variant(cc.resistor.into()); w.resn().bypass(); if !matches!(oversample, Oversample::BYPASS) { w.burst().enabled(); @@ -405,6 +406,183 @@ impl<'d, const N: usize> Drop for Saadc<'d, N> { } } +impl From for GAIN_A { + fn from(gain: Gain) -> Self { + match gain { + Gain::GAIN1_6 => GAIN_A::GAIN1_6, + Gain::GAIN1_5 => GAIN_A::GAIN1_5, + Gain::GAIN1_4 => GAIN_A::GAIN1_4, + Gain::GAIN1_3 => GAIN_A::GAIN1_3, + Gain::GAIN1_2 => GAIN_A::GAIN1_2, + Gain::GAIN1 => GAIN_A::GAIN1, + Gain::GAIN2 => GAIN_A::GAIN2, + Gain::GAIN4 => GAIN_A::GAIN4, + } + } +} + +/// Gain control +#[non_exhaustive] +#[derive(Clone, Copy)] +pub enum Gain { + /// 1/6 + GAIN1_6 = 0, + /// 1/5 + GAIN1_5 = 1, + /// 1/4 + GAIN1_4 = 2, + /// 1/3 + GAIN1_3 = 3, + /// 1/2 + GAIN1_2 = 4, + /// 1 + GAIN1 = 5, + /// 2 + GAIN2 = 6, + /// 4 + GAIN4 = 7, +} + +impl From for REFSEL_A { + fn from(reference: Reference) -> Self { + match reference { + Reference::INTERNAL => REFSEL_A::INTERNAL, + Reference::VDD1_4 => REFSEL_A::VDD1_4, + } + } +} + +/// Reference control +#[non_exhaustive] +#[derive(Clone, Copy)] +pub enum Reference { + /// Internal reference (0.6 V) + INTERNAL = 0, + /// VDD/4 as reference + VDD1_4 = 1, +} + +impl From for RESP_A { + fn from(resistor: Resistor) -> Self { + match resistor { + Resistor::BYPASS => RESP_A::BYPASS, + Resistor::PULLDOWN => RESP_A::PULLDOWN, + Resistor::PULLUP => RESP_A::PULLUP, + Resistor::VDD1_2 => RESP_A::VDD1_2, + } + } +} + +/// Positive channel resistor control +#[non_exhaustive] +#[derive(Clone, Copy)] +pub enum Resistor { + /// Bypass resistor ladder + BYPASS = 0, + /// Pull-down to GND + PULLDOWN = 1, + /// Pull-up to VDD + PULLUP = 2, + /// Set input at VDD/2 + VDD1_2 = 3, +} + +impl From