#![cfg_attr(docsrs, procmacros::doc_replace(
"dac1_pin" => {
cfg(esp32) => "GPIO25",
cfg(esp32s2) => "GPIO17"
}
))]
use crate::gpio::AnalogPin;
cfg_if::cfg_if! {
if #[cfg(esp32)] {
type Dac1Gpio<'d> = crate::peripherals::GPIO25<'d>;
type Dac2Gpio<'d> = crate::peripherals::GPIO26<'d>;
} else if #[cfg(esp32s2)] {
type Dac1Gpio<'d> = crate::peripherals::GPIO17<'d>;
type Dac2Gpio<'d> = crate::peripherals::GPIO18<'d>;
}
}
pub struct Dac<'d, T>
where
T: Instance + 'd,
T::Pin: AnalogPin + 'd,
{
_inner: T,
_lifetime: core::marker::PhantomData<&'d mut ()>,
}
impl<'d, T> Dac<'d, T>
where
T: Instance + 'd,
T::Pin: AnalogPin + 'd,
{
pub fn new(dac: T, pin: T::Pin) -> Self {
pin.set_analog(crate::private::Internal);
#[cfg(esp32s2)]
crate::peripherals::SENS::regs()
.sar_dac_ctrl1()
.modify(|_, w| w.dac_clkgate_en().set_bit());
T::enable_xpd();
Self {
_inner: dac,
_lifetime: core::marker::PhantomData,
}
}
pub fn write(&mut self, value: u8) {
T::set_pad_source();
T::write_byte(value);
}
}
#[doc(hidden)]
pub trait Instance: crate::private::Sealed {
const INDEX: usize;
type Pin;
fn enable_xpd() {
crate::peripherals::RTC_IO::regs()
.pad_dac(Self::INDEX)
.modify(|_, w| w.dac_xpd_force().set_bit().xpd_dac().set_bit());
}
fn set_pad_source() {
crate::peripherals::SENS::regs()
.sar_dac_ctrl2()
.modify(|_, w| w.dac_cw_en(Self::INDEX as u8).clear_bit());
}
fn write_byte(value: u8) {
crate::peripherals::RTC_IO::regs()
.pad_dac(Self::INDEX)
.modify(|_, w| unsafe { w.dac().bits(value) });
}
}
#[cfg(dac_dac1)]
impl<'d> Instance for crate::peripherals::DAC1<'d> {
const INDEX: usize = 0;
type Pin = Dac1Gpio<'d>;
}
#[cfg(dac_dac2)]
impl<'d> Instance for crate::peripherals::DAC2<'d> {
const INDEX: usize = 1;
type Pin = Dac2Gpio<'d>;
}