use crate::{ peripheral::PeripheralRef, peripherals::{RTC_IO, SENS}, }; pub trait DAC { fn write(&mut self, value: u8); } #[doc(hidden)] pub trait DAC1Impl { fn set_power(self) -> Self where Self: Sized, { #[cfg(esp32s2)] { let sensors = unsafe { &*SENS::ptr() }; sensors .sar_dac_ctrl1 .modify(|_, w| w.dac_clkgate_en().set_bit()); } let rtcio = unsafe { &*RTC_IO::ptr() }; rtcio.pad_dac1.modify(|_, w| { w.pdac1_dac_xpd_force().set_bit(); w.pdac1_xpd_dac().set_bit() }); self } fn write(&mut self, value: u8) { let rtcio = unsafe { &*RTC_IO::ptr() }; let sensors = unsafe { &*SENS::ptr() }; sensors .sar_dac_ctrl2 .modify(|_, w| w.dac_cw_en1().clear_bit()); rtcio .pad_dac1 .modify(|_, w| unsafe { w.pdac1_dac().bits(value) }); } } #[doc(hidden)] pub trait DAC2Impl { fn set_power(self) -> Self where Self: Sized, { #[cfg(esp32s2)] { let sensors = unsafe { &*SENS::ptr() }; sensors .sar_dac_ctrl1 .modify(|_, w| w.dac_clkgate_en().set_bit()); } let rtcio = unsafe { &*RTC_IO::ptr() }; rtcio.pad_dac2.modify(|_, w| { w.pdac2_dac_xpd_force().set_bit(); w.pdac2_xpd_dac().set_bit() }); self } fn write(&mut self, value: u8) { let rtcio = unsafe { &*RTC_IO::ptr() }; let sensors = unsafe { &*SENS::ptr() }; sensors .sar_dac_ctrl2 .modify(|_, w| w.dac_cw_en2().clear_bit()); rtcio .pad_dac2 .modify(|_, w| unsafe { w.pdac2_dac().bits(value) }); } } #[doc(hidden)] #[macro_export] macro_rules! impl_dac { ($($number:literal => $gpio:ident,)+) => { use core::marker::PhantomData; use crate::gpio; $( paste::paste! { pub use $crate::analog::dac::[]; /// DAC channel pub struct []<'d, DAC> { _dac: PeripheralRef<'d, DAC>, _private: PhantomData<()>, } impl<'d, DAC> [] for []<'d, DAC> {} impl<'d, DAC> []<'d, DAC> { /// Constructs a new DAC instance pub fn dac( dac: impl $crate::peripheral::Peripheral

+'d, _pin: gpio::$gpio<$crate::gpio::Analog>, ) -> Result { let dac = Self { _dac: dac.into_ref(), _private: PhantomData, } .set_power(); Ok(dac) } /// Write the given value /// /// For each DAC channel, the output analog voltage can be calculated as follows: /// DACn_OUT = VDD3P3_RTC * PDACn_DAC/256 pub fn write(&mut self, value: u8) { []::write(self, value) } } } )+ }; } pub use impl_dac; #[cfg(esp32)] pub mod implementation { //! Digital to analog (DAC) conversion. //! //! This module provides functions for controling two digital to //! analog converters, available on ESP32: `DAC1` and `DAC2`. //! //! The DAC1 is available on the GPIO pin 25, and DAC2 on pin 26. pub use super::*; use crate::impl_dac; impl_dac!(1 => Gpio25, 2 => Gpio26,); } #[cfg(esp32s2)] pub mod implementation { //! Digital to analog (DAC) conversion. //! //! This module provides functions for controling two digital to //! analog converters, available on ESP32: `DAC1` and `DAC2`. //! //! The DAC1 is available on the GPIO pin 17, and DAC2 on pin 18. pub use super::*; use crate::impl_dac; impl_dac!(1 => Gpio17, 2 => Gpio18,); }