diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index c887360cf..bf6c60b54 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Refactor `Dac1`/`Dac2` drivers into a single `Dac` driver (#1661) + ### Removed ## [0.18.0] - 2024-06-04 diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index cd3a552d0..0187dac56 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -53,13 +53,13 @@ xtensa-lx = { version = "0.9.0", optional = true } # IMPORTANT: # Each supported device MUST have its PAC included below along with a # corresponding feature. -esp32 = { version = "0.31.0", features = ["critical-section", "rt"], optional = true } -esp32c2 = { version = "0.20.0", features = ["critical-section", "rt"], optional = true } -esp32c3 = { version = "0.23.0", features = ["critical-section", "rt"], optional = true } -esp32c6 = { version = "0.14.0", features = ["critical-section", "rt"], optional = true } -esp32h2 = { version = "0.10.0", features = ["critical-section", "rt"], optional = true } -esp32s2 = { version = "0.22.0", features = ["critical-section", "rt"], optional = true } -esp32s3 = { version = "0.26.0", features = ["critical-section", "rt"], optional = true } +esp32 = { git = "https://github.com/esp-rs/esp-pacs", rev = "a7c72f7", features = ["critical-section", "rt"], optional = true } +esp32c2 = { git = "https://github.com/esp-rs/esp-pacs", rev = "a7c72f7", features = ["critical-section", "rt"], optional = true } +esp32c3 = { git = "https://github.com/esp-rs/esp-pacs", rev = "a7c72f7", features = ["critical-section", "rt"], optional = true } +esp32c6 = { git = "https://github.com/esp-rs/esp-pacs", rev = "a7c72f7", features = ["critical-section", "rt"], optional = true } +esp32h2 = { git = "https://github.com/esp-rs/esp-pacs", rev = "a7c72f7", features = ["critical-section", "rt"], optional = true } +esp32s2 = { git = "https://github.com/esp-rs/esp-pacs", rev = "a7c72f7", features = ["critical-section", "rt"], optional = true } +esp32s3 = { git = "https://github.com/esp-rs/esp-pacs", rev = "a7c72f7", features = ["critical-section", "rt"], optional = true } [target.'cfg(target_arch = "riscv32")'.dependencies] esp-riscv-rt = { version = "0.8.0", path = "../esp-riscv-rt" } diff --git a/esp-hal/src/analog/dac.rs b/esp-hal/src/analog/dac.rs index be52b8f8e..b5f422972 100644 --- a/esp-hal/src/analog/dac.rs +++ b/esp-hal/src/analog/dac.rs @@ -16,8 +16,8 @@ //! let gpio25 = io.pins.gpio25; //! let gpio26 = io.pins.gpio26; //! -//! let mut dac1 = Dac1::new(peripherals.DAC1, gpio25); -//! let mut dac2 = Dac2::new(peripherals.DAC2, gpio26); +//! let mut dac1 = Dac::new(peripherals.DAC1, gpio25); +//! let mut dac2 = Dac::new(peripherals.DAC2, gpio26); //! //! let mut delay = Delay::new(&clocks); //! @@ -36,12 +36,16 @@ //! } //! ``` +#![deny(missing_docs)] + use crate::{ gpio::{self, AnalogPin}, peripheral::{Peripheral, PeripheralRef}, - peripherals, }; +// Only specific pins can be used with each DAC peripheral, and of course +// these pins are different depending on which chip you are using; for this +// reason, we will type alias the pins for ease of use later in this module: cfg_if::cfg_if! { if #[cfg(esp32)] { type Dac1Gpio = gpio::Gpio25; @@ -52,26 +56,33 @@ cfg_if::cfg_if! { } } -/// Digital-to-Analog Converter (DAC) Channel 1 -pub struct Dac1<'d> { - _inner: PeripheralRef<'d, peripherals::DAC1>, +/// Digital-to-Analog Converter (DAC) Channel +pub struct Dac<'d, T> +where + T: Instance, + T::Pin: AnalogPin, +{ + _inner: PeripheralRef<'d, T>, } -impl<'d> Dac1<'d> { - /// Constructs a new DAC instance. - pub fn new(dac: impl Peripheral
+ 'd, pin: Dac1Gpio) -> Self { +impl<'d, T> Dac<'d, T> +where + T: Instance, + T::Pin: AnalogPin, +{ + /// Construct a new instance of [`Dac`]. + pub fn new(dac: impl Peripheral
+ 'd, pin: T::Pin) -> Self { crate::into_ref!(dac); - // TODO revert this on drop + + // TODO: Revert on drop. pin.set_analog(crate::private::Internal); #[cfg(esp32s2)] - unsafe { &*peripherals::SENS::PTR } + unsafe { &*crate::peripherals::SENS::PTR } .sar_dac_ctrl1() .modify(|_, w| w.dac_clkgate_en().set_bit()); - unsafe { &*peripherals::RTC_IO::PTR } - .pad_dac1() - .modify(|_, w| w.pdac1_dac_xpd_force().set_bit().pdac1_xpd_dac().set_bit()); + T::enable_xpd(); Self { _inner: dac } } @@ -81,51 +92,44 @@ impl<'d> Dac1<'d> { /// 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) { + T::set_pad_source(); + T::write_byte(value); + } +} + +#[doc(hidden)] +pub trait Instance: crate::private::Sealed { + const INDEX: usize; + + type Pin; + + fn enable_xpd() { + unsafe { &*crate::peripherals::RTC_IO::PTR } + .pad_dac(Self::INDEX) + .modify(|_, w| w.dac_xpd_force().set_bit().xpd_dac().set_bit()); + } + + fn set_pad_source() { unsafe { &*crate::peripherals::SENS::PTR } .sar_dac_ctrl2() - .modify(|_, w| w.dac_cw_en1().clear_bit()); + .modify(|_, w| w.dac_cw_en(Self::INDEX as u8).clear_bit()); + } + fn write_byte(value: u8) { unsafe { &*crate::peripherals::RTC_IO::PTR } - .pad_dac1() - .modify(|_, w| unsafe { w.pdac1_dac().bits(value) }); + .pad_dac(Self::INDEX) + .modify(|_, w| unsafe { w.dac().bits(value) }); } } -/// Digital-to-Analog Converter (DAC) Channel 2 -pub struct Dac2<'d> { - _inner: PeripheralRef<'d, peripherals::DAC2>, +impl Instance for crate::peripherals::DAC1 { + const INDEX: usize = 0; + + type Pin = Dac1Gpio; } -impl<'d> Dac2<'d> { - /// Constructs a new DAC instance. - pub fn new(dac: impl Peripheral
+ 'd, pin: Dac2Gpio) -> Self {
- crate::into_ref!(dac);
- // TODO revert this on drop
- pin.set_analog(crate::private::Internal);
+impl Instance for crate::peripherals::DAC2 {
+ const INDEX: usize = 1;
- #[cfg(esp32s2)]
- unsafe { &*peripherals::SENS::PTR }
- .sar_dac_ctrl1()
- .modify(|_, w| w.dac_clkgate_en().set_bit());
-
- unsafe { &*peripherals::RTC_IO::PTR }
- .pad_dac2()
- .modify(|_, w| w.pdac2_dac_xpd_force().set_bit().pdac2_xpd_dac().set_bit());
-
- Self { _inner: dac }
- }
-
- /// Writes 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) {
- unsafe { &*crate::peripherals::SENS::PTR }
- .sar_dac_ctrl2()
- .modify(|_, w| w.dac_cw_en2().clear_bit());
-
- unsafe { &*crate::peripherals::RTC_IO::PTR }
- .pad_dac2()
- .modify(|_, w| unsafe { w.pdac2_dac().bits(value) });
- }
+ type Pin = Dac2Gpio;
}
diff --git a/esp-hal/src/prelude.rs b/esp-hal/src/prelude.rs
index 2f3c4df69..2abcb5a29 100644
--- a/esp-hal/src/prelude.rs
+++ b/esp-hal/src/prelude.rs
@@ -13,6 +13,8 @@ pub use embedded_dma::{
pub use fugit::{ExtU64 as _fugit_ExtU64, RateExtU32 as _fugit_RateExtU32};
pub use nb;
+#[cfg(dac)]
+pub use crate::analog::dac::Instance as _esp_hal_analog_dac_Instance;
#[cfg(any(dport, pcr, system))]
pub use crate::clock::Clock as _esp_hal_clock_Clock;
#[cfg(gpio)]
diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs
index 0366b3f6c..ab8a39f1b 100644
--- a/esp-hal/src/rtc_cntl/mod.rs
+++ b/esp-hal/src/rtc_cntl/mod.rs
@@ -788,9 +788,6 @@ impl Rwdt {
let rtc_cntl = unsafe { &*LP_WDT::PTR };
self.set_write_protection(false);
- #[cfg(any(esp32c6, esp32h2))]
- rtc_cntl.wdtfeed().write(|w| w.rtc_wdt_feed().set_bit());
- #[cfg(not(any(esp32c6, esp32h2)))]
rtc_cntl.wdtfeed().write(|w| w.wdt_feed().set_bit());
self.set_write_protection(true);
}
diff --git a/esp-hal/src/soc/esp32/gpio.rs b/esp-hal/src/soc/esp32/gpio.rs
index 1cd29c131..3c6e43969 100644
--- a/esp-hal/src/soc/esp32/gpio.rs
+++ b/esp-hal/src/soc/esp32/gpio.rs
@@ -811,10 +811,10 @@ pub(crate) fn errata36(pin_num: u8, pull_up: Option