#![cfg_attr(feature = "52840", doc = "```no_run")]
#![cfg_attr(not(feature = "52840"), doc = "```ignore")]
#[cfg(any(feature = "9160", feature = "5340-app"))]
use crate::pac::{saadc_ns as saadc, SAADC_NS as SAADC};
#[cfg(not(any(feature = "9160", feature = "5340-app")))]
use crate::pac::{saadc, SAADC};
use core::sync::atomic::{compiler_fence, Ordering::SeqCst};
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,
};
#[cfg(feature = "embedded-hal-02")]
pub trait Channel: embedded_hal_02::adc::Channel<Saadc, ID = u8> {}
#[cfg(not(feature = "embedded-hal-02"))]
pub trait Channel {
fn channel() -> u8;
}
pub struct Saadc(SAADC);
impl Saadc {
pub fn new(saadc: SAADC, config: SaadcConfig) -> Self {
let SaadcConfig {
resolution,
oversample,
reference,
gain,
resistor,
time,
} = config;
saadc.enable.write(|w| w.enable().enabled());
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().variant(reference);
w.gain().variant(gain);
w.tacq().variant(time);
w.mode().se();
w.resp().variant(resistor);
w.resn().bypass();
w.burst().enabled();
w
});
saadc.ch[0].pseln.write(|w| w.pseln().nc());
saadc.events_calibratedone.reset();
saadc.tasks_calibrateoffset.write(|w| unsafe { w.bits(1) });
while saadc.events_calibratedone.read().bits() == 0 {}
Saadc(saadc)
}
pub fn free(self) -> SAADC {
self.0.enable.write(|w| w.enable().disabled());
self.0
}
pub fn read_channel<PIN: Channel>(&mut self, _pin: &mut PIN) -> Result<i16, ()> {
match PIN::channel() {
0 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input0()),
1 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input1()),
2 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input2()),
3 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input3()),
4 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input4()),
5 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input5()),
6 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input6()),
7 => self.0.ch[0].pselp.write(|w| w.pselp().analog_input7()),
#[cfg(not(feature = "9160"))]
8 => self.0.ch[0].pselp.write(|w| w.pselp().vdd()),
#[cfg(any(feature = "52833", feature = "52840"))]
13 => self.0.ch[0].pselp.write(|w| w.pselp().vddhdiv5()),
_ => return Err(()),
}
let mut val: i16 = 0;
self.0
.result
.ptr
.write(|w| unsafe { w.ptr().bits(((&mut val) as *mut _) as u32) });
self.0
.result
.maxcnt
.write(|w| unsafe { w.maxcnt().bits(1) });
compiler_fence(SeqCst);
self.0.tasks_start.write(|w| unsafe { w.bits(1) });
self.0.tasks_sample.write(|w| unsafe { w.bits(1) });
while self.0.events_end.read().bits() == 0 {}
self.0.events_end.reset();
if self.0.result.amount.read().bits() != 1 {
return Err(());
}
compiler_fence(SeqCst);
Ok(val)
}
}
pub struct SaadcConfig {
pub resolution: Resolution,
pub oversample: Oversample,
pub reference: Reference,
pub gain: Gain,
pub resistor: Resistor,
pub time: Time,
}
#[cfg_attr(feature = "52840", doc = "```")]
#[cfg_attr(not(feature = "52840"), doc = "```ignore")]
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,
}
}
}
#[cfg(feature = "embedded-hal-02")]
impl<PIN> embedded_hal_02::adc::OneShot<Saadc, i16, PIN> for Saadc
where
PIN: Channel,
{
type Error = ();
fn read(&mut self, pin: &mut PIN) -> nb::Result<i16, Self::Error> {
Ok(self.read_channel(pin)?)
}
}
macro_rules! channel_mappings {
( $($n:expr => $pin:ident,)*) => {
$(
#[cfg(feature = "embedded-hal-02")]
impl<STATE> embedded_hal_02::adc::Channel<Saadc> for crate::gpio::p0::$pin<STATE> {
type ID = u8;
fn channel() -> u8 {
$n
}
}
impl<STATE> Channel for crate::gpio::p0::$pin<STATE> {
#[cfg(not(feature = "embedded-hal-02"))]
fn channel() -> u8 {
$n
}
}
)*
};
}
#[cfg(feature = "9160")]
channel_mappings! {
0 => P0_13,
1 => P0_14,
2 => P0_15,
3 => P0_16,
4 => P0_17,
5 => P0_18,
6 => P0_19,
7 => P0_20,
}
#[cfg(not(feature = "9160"))]
channel_mappings! {
0 => P0_02,
1 => P0_03,
2 => P0_04,
3 => P0_05,
4 => P0_28,
5 => P0_29,
6 => P0_30,
7 => P0_31,
}
#[cfg(all(not(feature = "9160"), feature = "embedded-hal-02"))]
impl embedded_hal_02::adc::Channel<Saadc> for InternalVdd {
type ID = u8;
fn channel() -> u8 {
8
}
}
#[cfg(not(feature = "9160"))]
impl Channel for InternalVdd {
#[cfg(not(feature = "embedded-hal-02"))]
fn channel() -> u8 {
8
}
}
#[cfg(not(feature = "9160"))]
pub struct InternalVdd;
#[cfg(all(any(feature = "52833", feature = "52840"), feature = "embedded-hal-02"))]
impl embedded_hal_02::adc::Channel<Saadc> for InternalVddHdiv5 {
type ID = u8;
fn channel() -> u8 {
13
}
}
#[cfg(any(feature = "52833", feature = "52840"))]
impl Channel for InternalVddHdiv5 {
#[cfg(not(feature = "embedded-hal-02"))]
fn channel() -> u8 {
13
}
}
#[cfg(any(feature = "52833", feature = "52840"))]
pub struct InternalVddHdiv5;