feat: initial work on saadc config
@@ -9,6 +9,12 @@ use core::{
};
use embedded_hal::adc::{Channel, OneShot};
+pub use crate::target::saadc::{
+ ch::config::{GAINW as Gain, REFSELW as Reference, RESPW as Resistor, TACQW as Time},
+ oversample::OVERSAMPLEW as Oversample,
+ resolution::VALW as Resolution,
+};
+
// Only 1 channel is allowed right now, a discussion needs to be had as to how
// multiple channels should work (See "scan mode" in the datasheet)
// Issue: https://github.com/nrf-rs/nrf52-hal/issues/82
@@ -19,30 +25,45 @@ pub trait SaadcExt: Deref<Target = saadc::RegisterBlock> + Sized {
impl SaadcExt for SAADC {
fn constrain(self) -> Saadc {
- Saadc::new(self)
+ Saadc::new(self, SaadcConfig::default())
}
}
pub struct Saadc(SAADC);
impl Saadc {
- pub fn new(saadc: SAADC) -> Self {
+ pub fn new(saadc: SAADC, config: SaadcConfig) -> Self {
+ // The write enums do not implement clone/copy/debug, only the
+ // read ones, hence the need to pull out and move the values
+ let SaadcConfig {
+ resolution,
+ oversample,
+ reference,
+ gain,
+ resistor,
+ time
+ } = config;
+
saadc.enable.write(|w| w.enable().enabled());
- saadc.resolution.write(|w| w.val()._12bit());
- saadc.oversample.write(|w| w.oversample().bypass());
+ saadc
+ .resolution
+ .write(|w| w.val().variant(resolution));
+ saadc
+ .oversample
+ .write(|w| w.oversample().variant(oversample));
saadc.samplerate.write(|w| w.mode().task());
saadc.ch[0].config.write(|w| {
w.refsel()
- .internal()
+ .variant(reference)
.gain()
- .gain1_6()
+ .variant(gain)
.tacq()
- ._20us()
+ .variant(time)
.mode()
.se()
.resp()
- .bypass()
+ .variant(resistor)
.resn()
.bypass()
.burst()
@@ -58,6 +79,29 @@ impl Saadc {
}
}
+pub struct SaadcConfig {
+ resolution: Resolution,
+ oversample: Oversample,
+ reference: Reference,
+ gain: Gain,
+ resistor: Resistor,
+ time: Time,
+}
+
+// 0 volts reads as 0, VDD volts reads as u16::MAX
+impl Default for SaadcConfig {
+ fn default() -> Self {
+ SaadcConfig {
+ resolution: Resolution::_14BIT,
+ oversample: Oversample::OVER8X,
+ reference: Reference::VDD1_4,
+ gain: Gain::GAIN1_4,
+ resistor: Resistor::BYPASS,
+ time: Time::_20US,
+ }
+ }
+}
+
impl<PIN> OneShot<Saadc, u16, PIN> for Saadc
where
PIN: Channel<Saadc, ID = u8>,
@@ -75,7 +119,7 @@ where
7 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input7()),
// This can never happen the only analog pins have already been defined
// PAY CLOSE ATTENTION TO ANY CHANGES TO THIS IMPL OR THE `channel_mappings!` MACRO
- _ => unsafe { unreachable_unchecked() }
+ _ => unsafe { unreachable_unchecked() },
}
let mut val: u16 = 0;
