diff --git a/esp-hal/src/aes/esp32.rs b/esp-hal/src/aes/esp32.rs index f9920a9a4d3..f3c7a661243 100644 --- a/esp-hal/src/aes/esp32.rs +++ b/esp-hal/src/aes/esp32.rs @@ -5,7 +5,7 @@ use crate::{ impl<'d> Aes<'d> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); + PeripheralClockControl::enable(PeripheralEnable::Aes, true); self.write_endianness( Endianness::BigEndian, Endianness::BigEndian, diff --git a/esp-hal/src/aes/esp32cX.rs b/esp-hal/src/aes/esp32cX.rs index b20923cc9e3..a87ee79df61 100644 --- a/esp-hal/src/aes/esp32cX.rs +++ b/esp-hal/src/aes/esp32cX.rs @@ -5,7 +5,7 @@ use crate::{ impl Aes<'_> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); + PeripheralClockControl::enable(PeripheralEnable::Aes, true); self.write_dma(false); } diff --git a/esp-hal/src/aes/esp32s2.rs b/esp-hal/src/aes/esp32s2.rs index 926612821c4..042d365c87d 100644 --- a/esp-hal/src/aes/esp32s2.rs +++ b/esp-hal/src/aes/esp32s2.rs @@ -5,7 +5,7 @@ use crate::{ impl<'d> Aes<'d> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); + PeripheralClockControl::enable(PeripheralEnable::Aes, true); self.write_dma(false); self.write_endianness( Endianness::BigEndian, diff --git a/esp-hal/src/aes/esp32s3.rs b/esp-hal/src/aes/esp32s3.rs index 6adc108449f..f92193191d6 100644 --- a/esp-hal/src/aes/esp32s3.rs +++ b/esp-hal/src/aes/esp32s3.rs @@ -5,7 +5,7 @@ use crate::{ impl<'d> Aes<'d> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); + PeripheralClockControl::enable(PeripheralEnable::Aes, true); self.write_dma(false); } diff --git a/esp-hal/src/aes/mod.rs b/esp-hal/src/aes/mod.rs index eac8f95066a..172ea4f2e01 100644 --- a/esp-hal/src/aes/mod.rs +++ b/esp-hal/src/aes/mod.rs @@ -59,6 +59,8 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::AES, reg_access::{AlignmentHelper, NativeEndianess}, + system, + system::PeripheralClockControl, }; #[cfg_attr(esp32, path = "esp32.rs")] @@ -143,8 +145,8 @@ impl<'d> Aes<'d> { pub fn new(aes: impl Peripheral

+ 'd) -> Self { crate::into_ref!(aes); - crate::system::PeripheralClockControl::reset(crate::system::Peripheral::Aes); - crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Aes); + PeripheralClockControl::reset(system::Peripheral::Aes); + PeripheralClockControl::enable(system::Peripheral::Aes, true); let mut ret = Self { aes, @@ -190,6 +192,12 @@ impl<'d> Aes<'d> { } } +impl<'d> Drop for Aes<'d> { + fn drop(&mut self) { + PeripheralClockControl::enable(system::Peripheral::Aes, false); + } +} + /// Specifications for AES flavours pub trait AesFlavour: crate::private::Sealed { /// Type of the AES key, a fixed-size array of bytes diff --git a/esp-hal/src/analog/adc/riscv.rs b/esp-hal/src/analog/adc/riscv.rs index 6b54131600a..eb15909ef92 100644 --- a/esp-hal/src/analog/adc/riscv.rs +++ b/esp-hal/src/analog/adc/riscv.rs @@ -409,7 +409,7 @@ where config: AdcConfig, ) -> Self { PeripheralClockControl::reset(Peripheral::ApbSarAdc); - PeripheralClockControl::enable(Peripheral::ApbSarAdc); + PeripheralClockControl::enable(Peripheral::ApbSarAdc, true); unsafe { &*APB_SARADC::PTR }.ctrl().modify(|_, w| unsafe { w.start_force().set_bit(); @@ -500,6 +500,12 @@ where } } +impl<'d, ADCI> Drop for Adc<'d, ADCI> { + fn drop(&mut self) { + PeripheralClockControl::enable(Peripheral::ApbSarAdc, false); + } +} + #[cfg(any(esp32c2, esp32c3, esp32c6))] impl super::AdcCalEfuse for crate::peripherals::ADC1 { fn get_init_code(atten: Attenuation) -> Option { diff --git a/esp-hal/src/analog/adc/xtensa.rs b/esp-hal/src/analog/adc/xtensa.rs index bc9d6ef3202..d4f63f360e0 100644 --- a/esp-hal/src/analog/adc/xtensa.rs +++ b/esp-hal/src/analog/adc/xtensa.rs @@ -402,7 +402,7 @@ where config: AdcConfig, ) -> Self { PeripheralClockControl::reset(Peripheral::ApbSarAdc); - PeripheralClockControl::enable(Peripheral::ApbSarAdc); + PeripheralClockControl::enable(Peripheral::ApbSarAdc, true); let sensors = unsafe { &*SENS::ptr() }; @@ -560,6 +560,12 @@ where } } +impl<'d, ADCI> Drop for Adc<'d, ADCI> { + fn drop(&mut self) { + PeripheralClockControl::enable(Peripheral::ApbSarAdc, false); + } +} + #[cfg(esp32s3)] impl super::AdcCalEfuse for crate::peripherals::ADC1 { fn get_init_code(atten: Attenuation) -> Option { diff --git a/esp-hal/src/dma/gdma.rs b/esp-hal/src/dma/gdma.rs index bff710a2ec8..f43386b7b7a 100644 --- a/esp-hal/src/dma/gdma.rs +++ b/esp-hal/src/dma/gdma.rs @@ -662,7 +662,7 @@ impl<'d> Dma<'d> { ) -> Dma<'d> { crate::into_ref!(dma); - PeripheralClockControl::enable(Peripheral::Gdma); + PeripheralClockControl::enable(Peripheral::Gdma, true); dma.misc_conf().modify(|_, w| w.ahbm_rst_inter().set_bit()); dma.misc_conf() .modify(|_, w| w.ahbm_rst_inter().clear_bit()); diff --git a/esp-hal/src/dma/pdma.rs b/esp-hal/src/dma/pdma.rs index 1659eb5f95d..565e3b5b0a5 100644 --- a/esp-hal/src/dma/pdma.rs +++ b/esp-hal/src/dma/pdma.rs @@ -878,7 +878,7 @@ impl<'d> Dma<'d> { pub fn new( dma: impl crate::peripheral::Peripheral

+ 'd, ) -> Dma<'d> { - PeripheralClockControl::enable(Peripheral::Dma); + PeripheralClockControl::enable(Peripheral::Dma, true); #[cfg(esp32)] { diff --git a/esp-hal/src/ecc.rs b/esp-hal/src/ecc.rs index 7c6ccfcc2b9..71b857bf68c 100644 --- a/esp-hal/src/ecc.rs +++ b/esp-hal/src/ecc.rs @@ -103,7 +103,7 @@ impl<'d> Ecc<'d, crate::Blocking> { crate::into_ref!(ecc); PeripheralClockControl::reset(PeripheralEnable::Ecc); - PeripheralClockControl::enable(PeripheralEnable::Ecc); + PeripheralClockControl::enable(PeripheralEnable::Ecc, true); Self { ecc, @@ -113,6 +113,12 @@ impl<'d> Ecc<'d, crate::Blocking> { } } +impl<'d, DM: crate::Mode> Drop for Ecc<'d, DM> { + fn drop(&mut self) { + PeripheralClockControl::enable(PeripheralEnable::Ecc, false); + } +} + impl crate::private::Sealed for Ecc<'_, crate::Blocking> {} impl InterruptConfigurable for Ecc<'_, crate::Blocking> { diff --git a/esp-hal/src/etm.rs b/esp-hal/src/etm.rs index f2c603a67e7..d0cf7860b8d 100644 --- a/esp-hal/src/etm.rs +++ b/esp-hal/src/etm.rs @@ -152,7 +152,7 @@ macro_rules! create_etm { crate::into_ref!(peripheral); PeripheralClockControl::reset(crate::system::Peripheral::Etm); - PeripheralClockControl::enable(crate::system::Peripheral::Etm); + PeripheralClockControl::enable(crate::system::Peripheral::Etm, true); Self { _peripheral: peripheral, diff --git a/esp-hal/src/hmac.rs b/esp-hal/src/hmac.rs index e7709972b50..e67efbe33fd 100644 --- a/esp-hal/src/hmac.rs +++ b/esp-hal/src/hmac.rs @@ -108,7 +108,7 @@ impl<'d> Hmac<'d> { crate::into_ref!(hmac); PeripheralClockControl::reset(PeripheralEnable::Hmac); - PeripheralClockControl::enable(PeripheralEnable::Hmac); + PeripheralClockControl::enable(PeripheralEnable::Hmac, true); Self { hmac, @@ -345,3 +345,9 @@ impl<'d> Hmac<'d> { while self.is_busy() {} } } + +impl<'d> Drop for Hmac<'d> { + fn drop(&mut self) { + PeripheralClockControl::enable(PeripheralEnable::Hmac, false); + } +} diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index 036e2099d63..fc263f7a98a 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -314,7 +314,7 @@ where }; PeripheralClockControl::reset(i2c.info().peripheral); - PeripheralClockControl::enable(i2c.info().peripheral); + PeripheralClockControl::enable(i2c.info().peripheral, true); let i2c = i2c.with_sda(sda).with_scl(scl); @@ -328,7 +328,7 @@ where fn internal_recover(&self) { PeripheralClockControl::reset(self.info().peripheral); - PeripheralClockControl::enable(self.info().peripheral); + PeripheralClockControl::enable(self.info().peripheral, true); self.info().setup(self.frequency, self.timeout); } diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index 6a418b966e8..b1ad0ad6069 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -289,7 +289,7 @@ where // the targets the same and force same configuration for both, TX and RX PeripheralClockControl::reset(i2s.peripheral()); - PeripheralClockControl::enable(i2s.peripheral()); + PeripheralClockControl::enable(i2s.peripheral(), true); i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits())); i2s.configure(&standard, &data_format); i2s.set_master(); diff --git a/esp-hal/src/i2s/parallel.rs b/esp-hal/src/i2s/parallel.rs index 865346fb648..34874ac26cc 100644 --- a/esp-hal/src/i2s/parallel.rs +++ b/esp-hal/src/i2s/parallel.rs @@ -223,7 +223,7 @@ where let channel = channel.degrade(); PeripheralClockControl::reset(i2s.peripheral()); - PeripheralClockControl::enable(i2s.peripheral()); + PeripheralClockControl::enable(i2s.peripheral(), true); // configure the I2S peripheral for parallel mode i2s.setup(frequency, pins.bus_width()); // setup the clock pin diff --git a/esp-hal/src/lcd_cam/mod.rs b/esp-hal/src/lcd_cam/mod.rs index b442b2450ef..d3fa0a82a03 100644 --- a/esp-hal/src/lcd_cam/mod.rs +++ b/esp-hal/src/lcd_cam/mod.rs @@ -39,7 +39,7 @@ impl<'d> LcdCam<'d, Blocking> { crate::into_ref!(lcd_cam); PeripheralClockControl::reset(system::Peripheral::LcdCam); - PeripheralClockControl::enable(system::Peripheral::LcdCam); + PeripheralClockControl::enable(system::Peripheral::LcdCam, true); Self { lcd: Lcd { diff --git a/esp-hal/src/ledc/mod.rs b/esp-hal/src/ledc/mod.rs index 3b0a61cfefc..d7c05a64154 100644 --- a/esp-hal/src/ledc/mod.rs +++ b/esp-hal/src/ledc/mod.rs @@ -114,7 +114,7 @@ impl<'d> Ledc<'d> { crate::into_ref!(_instance); PeripheralClockControl::reset(PeripheralEnable::Ledc); - PeripheralClockControl::enable(PeripheralEnable::Ledc); + PeripheralClockControl::enable(PeripheralEnable::Ledc, true); let ledc = unsafe { &*crate::peripherals::LEDC::ptr() }; Ledc { _instance, ledc } @@ -173,3 +173,9 @@ impl<'d> Ledc<'d> { Channel::new(number, output_pin) } } + +impl<'d> Drop for Ledc<'d> { + fn drop(&mut self) { + PeripheralClockControl::enable(PeripheralEnable::Ledc, false); + } +} diff --git a/esp-hal/src/mcpwm/mod.rs b/esp-hal/src/mcpwm/mod.rs index a4907be376f..23d9adec244 100644 --- a/esp-hal/src/mcpwm/mod.rs +++ b/esp-hal/src/mcpwm/mod.rs @@ -135,7 +135,7 @@ impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> { crate::into_ref!(peripheral); PWM::reset(); - PWM::enable(); + PWM::enable(true); #[cfg(not(esp32c6))] { @@ -317,7 +317,7 @@ pub struct FrequencyError; /// A MCPWM peripheral pub trait PwmPeripheral: Deref + crate::private::Sealed { /// Enable peripheral - fn enable(); + fn enable(enable: bool); /// Reset peripheral fn reset(); /// Get a pointer to the peripheral RegisterBlock @@ -328,8 +328,8 @@ pub trait PwmPeripheral: Deref + crate::private::Sealed #[cfg(mcpwm0)] impl PwmPeripheral for crate::peripherals::MCPWM0 { - fn enable() { - PeripheralClockControl::enable(PeripheralEnable::Mcpwm0) + fn enable(enable: bool) { + PeripheralClockControl::enable(PeripheralEnable::Mcpwm0, enable) } fn reset() { @@ -355,8 +355,8 @@ impl PwmPeripheral for crate::peripherals::MCPWM0 { #[cfg(mcpwm1)] impl PwmPeripheral for crate::peripherals::MCPWM1 { - fn enable() { - PeripheralClockControl::enable(PeripheralEnable::Mcpwm1) + fn enable(enable: bool) { + PeripheralClockControl::enable(PeripheralEnable::Mcpwm1, enable) } fn reset() { diff --git a/esp-hal/src/otg_fs.rs b/esp-hal/src/otg_fs.rs index 97e0d246f0c..fe6dff1e565 100644 --- a/esp-hal/src/otg_fs.rs +++ b/esp-hal/src/otg_fs.rs @@ -71,7 +71,7 @@ impl<'d> Usb<'d> { M: UsbDm + Send + Sync, { PeripheralClockControl::reset(PeripheralEnable::Usb); - PeripheralClockControl::enable(PeripheralEnable::Usb); + PeripheralClockControl::enable(PeripheralEnable::Usb, true); Self { _usb0: usb0.into_ref(), @@ -110,6 +110,12 @@ impl<'d> Usb<'d> { } } +impl<'d> Drop for Usb<'d> { + fn drop(&mut self) { + PeripheralClockControl::enable(PeripheralEnable::Usb, false); + } +} + unsafe impl<'d> Sync for Usb<'d> {} unsafe impl<'d> UsbPeripheral for Usb<'d> { diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 57b558cc5ff..fc8fbaa699f 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -1275,7 +1275,7 @@ fn internal_init(frequency: HertzU32) -> Result<(), Error> { } PeripheralClockControl::reset(crate::system::Peripheral::ParlIo); - PeripheralClockControl::enable(crate::system::Peripheral::ParlIo); + PeripheralClockControl::enable(crate::system::Peripheral::ParlIo, true); let pcr = unsafe { &*crate::peripherals::PCR::PTR }; diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index 742404b3f17..6b44de828d8 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -65,7 +65,7 @@ impl<'d> Pcnt<'d> { // Enable the PCNT peripherals clock in the system peripheral PeripheralClockControl::reset(crate::system::Peripheral::Pcnt); - PeripheralClockControl::enable(crate::system::Peripheral::Pcnt); + PeripheralClockControl::enable(crate::system::Peripheral::Pcnt, true); let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() }; diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 984d621cf54..6c519ba56d0 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -89,6 +89,7 @@ use core::{ use embassy_sync::waitqueue::AtomicWaker; use enumset::{EnumSet, EnumSetType}; use fugit::HertzU32; +use portable_atomic::{AtomicU8, Ordering::Relaxed}; use crate::{ gpio::interconnect::{PeripheralInput, PeripheralOutput}, @@ -101,6 +102,7 @@ use crate::{ Blocking, InterruptConfigurable, }; +static REF_COUNTER: AtomicU8 = AtomicU8::new(0); /// Errors #[derive(Debug, Clone, Copy, PartialEq)] @@ -230,7 +232,7 @@ where } PeripheralClockControl::reset(crate::system::Peripheral::Rmt); - PeripheralClockControl::enable(crate::system::Peripheral::Rmt); + PeripheralClockControl::enable(crate::system::Peripheral::Rmt, true); cfg_if::cfg_if! { if #[cfg(any(esp32, esp32s2))] { @@ -325,6 +327,8 @@ fn configure_rx_channel<'d, P: PeripheralInput, T: RxChannelInternal, M: crat T::set_filter_threshold(config.filter_threshold); T::set_idle_threshold(config.idle_threshold); + REF_COUNTER.fetch_add(1, Relaxed); + Ok(T::new()) } @@ -345,6 +349,8 @@ fn configure_tx_channel<'d, P: PeripheralOutput, T: TxChannelInternal, M: cra ); T::set_idle_output(config.idle_output, config.idle_output_level); + REF_COUNTER.fetch_add(1, Relaxed); + Ok(T::new()) } @@ -978,6 +984,15 @@ where phantom: PhantomData, } +impl Drop for Channel { + fn drop(&mut self) { + REF_COUNTER.fetch_sub(1, Relaxed); + if REF_COUNTER.load(Relaxed) == 0 { + PeripheralClockControl::enable(crate::system::Peripheral::Rmt, false); + } + } +} + /// Channel in TX mode pub trait TxChannel: TxChannelInternal { /// Start transmitting the given pulse code sequence. diff --git a/esp-hal/src/rsa/mod.rs b/esp-hal/src/rsa/mod.rs index cde24f4e88c..39c7d16cbb4 100644 --- a/esp-hal/src/rsa/mod.rs +++ b/esp-hal/src/rsa/mod.rs @@ -96,7 +96,7 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { crate::into_ref!(rsa); PeripheralClockControl::reset(PeripheralEnable::Rsa); - PeripheralClockControl::enable(PeripheralEnable::Rsa); + PeripheralClockControl::enable(PeripheralEnable::Rsa, true); Self { rsa, diff --git a/esp-hal/src/sha.rs b/esp-hal/src/sha.rs index 48e85227628..570d550d430 100644 --- a/esp-hal/src/sha.rs +++ b/esp-hal/src/sha.rs @@ -82,7 +82,7 @@ impl<'d> Sha<'d> { crate::into_ref!(sha); PeripheralClockControl::reset(crate::system::Peripheral::Sha); - PeripheralClockControl::enable(crate::system::Peripheral::Sha); + PeripheralClockControl::enable(crate::system::Peripheral::Sha, true); Self { sha } } @@ -100,6 +100,12 @@ impl<'d> Sha<'d> { } } +impl<'d> Drop for Sha<'d> { + fn drop(&mut self) { + PeripheralClockControl::enable(crate::system::Peripheral::Sha, false); + } +} + impl crate::private::Sealed for Sha<'_> {} #[cfg(not(esp32))] diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 1609c7c2909..b9fb0be03b5 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -580,7 +580,7 @@ where _mode: PhantomData, }; - PeripheralClockControl::enable(this.driver().peripheral); + PeripheralClockControl::enable(this.driver().peripheral, true); PeripheralClockControl::reset(this.driver().peripheral); this.driver().init(); diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 86a80ffdca4..42aeb638018 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -128,7 +128,7 @@ where }; PeripheralClockControl::reset(this.spi.info().peripheral); - PeripheralClockControl::enable(this.spi.info().peripheral); + PeripheralClockControl::enable(this.spi.info().peripheral, true); this.spi.info().init(); this.spi.info().set_data_mode(mode, false); diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 0406d89d0f4..c77516268a9 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -127,8 +127,9 @@ pub(crate) struct PeripheralClockControl; #[cfg(not(any(esp32c6, esp32h2)))] impl PeripheralClockControl { - /// Enables and resets the given peripheral - pub(crate) fn enable(peripheral: Peripheral) { + /// Enables or disables the given peripheral depending on the value of + /// enable. + pub(crate) fn enable(peripheral: Peripheral, enable: bool) { let system = unsafe { &*SYSTEM::PTR }; #[cfg(esp32)] @@ -149,201 +150,273 @@ impl PeripheralClockControl { critical_section::with(|_cs| match peripheral { #[cfg(spi2)] Peripheral::Spi2 => { - perip_clk_en0.modify(|_, w| w.spi2_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.spi2_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit()); + } } #[cfg(spi3)] Peripheral::Spi3 => { - perip_clk_en0.modify(|_, w| w.spi3_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.spi3_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit()); + } } #[cfg(all(i2c0, esp32))] Peripheral::I2cExt0 => { - perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().clear_bit()); + } } #[cfg(all(i2c0, not(esp32)))] Peripheral::I2cExt0 => { - perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().clear_bit()); + } } #[cfg(i2c1)] Peripheral::I2cExt1 => { - perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().clear_bit()); + } } #[cfg(rmt)] Peripheral::Rmt => { - perip_clk_en0.modify(|_, w| w.rmt_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.rmt_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.rmt_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.rmt_rst().clear_bit()); + } } #[cfg(ledc)] Peripheral::Ledc => { - perip_clk_en0.modify(|_, w| w.ledc_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.ledc_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.ledc_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.ledc_rst().clear_bit()); + } } #[cfg(mcpwm0)] Peripheral::Mcpwm0 => { - perip_clk_en0.modify(|_, w| w.pwm0_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.pwm0_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.pwm0_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.pwm0_rst().clear_bit()); + } } #[cfg(mcpwm1)] Peripheral::Mcpwm1 => { - perip_clk_en0.modify(|_, w| w.pwm1_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.pwm1_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.pwm1_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.pwm1_rst().clear_bit()); + } } #[cfg(pcnt)] Peripheral::Pcnt => { - perip_clk_en0.modify(|_, w| w.pcnt_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.pcnt_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.pcnt_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.pcnt_rst().clear_bit()); + } } #[cfg(apb_saradc)] Peripheral::ApbSarAdc => { - perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.apb_saradc_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.apb_saradc_rst().clear_bit()); + } } #[cfg(gdma)] Peripheral::Gdma => { - perip_clk_en1.modify(|_, w| w.dma_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.dma_rst().clear_bit()); + perip_clk_en1.modify(|_, w| w.dma_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.dma_rst().clear_bit()); + } } #[cfg(esp32)] Peripheral::Dma => { - perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.spi_dma_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.spi_dma_rst().clear_bit()); + } } #[cfg(esp32s2)] Peripheral::Dma => { - perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.spi2_dma_rst().clear_bit()); - perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.spi3_dma_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.spi2_dma_rst().clear_bit()); + perip_rst_en0.modify(|_, w| w.spi3_dma_rst().clear_bit()); + } } #[cfg(esp32c3)] Peripheral::I2s0 => { // on ESP32-C3 note that i2s1_clk_en / rst is really I2s0 - perip_clk_en0.modify(|_, w| w.i2s1_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit()); + } } #[cfg(any(esp32s3, esp32, esp32s2))] Peripheral::I2s0 => { - perip_clk_en0.modify(|_, w| w.i2s0_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.i2s0_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.i2s0_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.i2s0_rst().clear_bit()); + } } #[cfg(any(esp32s3, esp32))] Peripheral::I2s1 => { - perip_clk_en0.modify(|_, w| w.i2s1_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit()); + } } #[cfg(usb0)] Peripheral::Usb => { - perip_clk_en0.modify(|_, w| w.usb_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.usb_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.usb_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.usb_rst().clear_bit()); + } } #[cfg(twai0)] Peripheral::Twai0 => { - perip_clk_en0.modify(|_, w| w.twai_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.twai_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.twai_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.twai_rst().clear_bit()); + } } #[cfg(esp32)] Peripheral::Aes => { - peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | 1) }); - peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & (!1)) }); + peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | enable as u32) }); + if enable { + peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & (!1)) }); + } } #[cfg(any(esp32c3, esp32s2, esp32s3))] Peripheral::Aes => { - perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.crypto_aes_rst().clear_bit()); + perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.crypto_aes_rst().clear_bit()); + } } #[cfg(timg0)] Peripheral::Timg0 => { #[cfg(any(esp32c3, esp32s2, esp32s3))] - perip_clk_en0.modify(|_, w| w.timers_clk_en().set_bit()); - perip_clk_en0.modify(|_, w| w.timergroup_clk_en().set_bit()); + perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.timergroup_clk_en().bit(enable)); #[cfg(any(esp32c3, esp32s2, esp32s3))] - perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit()); - perip_rst_en0.modify(|_, w| w.timergroup_rst().clear_bit()); + if enable { + perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit()); + perip_rst_en0.modify(|_, w| w.timergroup_rst().clear_bit()); + } } #[cfg(timg1)] Peripheral::Timg1 => { #[cfg(any(esp32c3, esp32s2, esp32s3))] - perip_clk_en0.modify(|_, w| w.timers_clk_en().set_bit()); - perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().set_bit()); + perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().bit(enable)); #[cfg(any(esp32c3, esp32s2, esp32s3))] - perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit()); - perip_rst_en0.modify(|_, w| w.timergroup1_rst().clear_bit()); + if enable { + perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit()); + perip_rst_en0.modify(|_, w| w.timergroup1_rst().clear_bit()); + } } #[cfg(sha)] Peripheral::Sha => { #[cfg(not(esp32))] - perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().set_bit()); + perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().bit(enable)); #[cfg(not(esp32))] - perip_rst_en1.modify(|_, w| w.crypto_sha_rst().clear_bit()); + if enable { + perip_rst_en1.modify(|_, w| w.crypto_sha_rst().clear_bit()); + } } #[cfg(esp32c3)] Peripheral::UsbDevice => { - perip_clk_en0.modify(|_, w| w.usb_device_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.usb_device_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.usb_device_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.usb_device_rst().clear_bit()); + } } #[cfg(esp32s3)] Peripheral::UsbDevice => { - perip_clk_en1.modify(|_, w| w.usb_device_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.usb_device_rst().clear_bit()); + perip_clk_en1.modify(|_, w| w.usb_device_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.usb_device_rst().clear_bit()); + } } #[cfg(uart0)] Peripheral::Uart0 => { - perip_clk_en0.modify(|_, w| w.uart_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.uart_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.uart_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.uart_rst().clear_bit()); + } } #[cfg(uart1)] Peripheral::Uart1 => { - perip_clk_en0.modify(|_, w| w.uart1_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.uart1_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.uart1_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.uart1_rst().clear_bit()); + } } #[cfg(all(uart2, esp32s3))] Peripheral::Uart2 => { - perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.uart2_rst().clear_bit()); + perip_clk_en1.modify(|_, w| w.uart2_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.uart2_rst().clear_bit()); + } } #[cfg(all(uart2, esp32))] Peripheral::Uart2 => { - perip_clk_en0.modify(|_, w| w.uart2_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.uart2_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.uart2_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.uart2_rst().clear_bit()); + } } #[cfg(all(rsa, esp32))] Peripheral::Rsa => { - peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | 1 << 2) }); - peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << 2)) }); + peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | (enable as u32) << 2) }); + if enable { + peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << 2)) }); + } } #[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))] Peripheral::Rsa => { - perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().clear_bit()); - system - .rsa_pd_ctrl() - .modify(|_, w| w.rsa_mem_pd().clear_bit()); + perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().clear_bit()); + system + .rsa_pd_ctrl() + .modify(|_, w| w.rsa_mem_pd().clear_bit()); + } } #[cfg(hmac)] Peripheral::Hmac => { - perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.crypto_hmac_rst().clear_bit()); + perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.crypto_hmac_rst().clear_bit()); + } } #[cfg(ecc)] Peripheral::Ecc => { - perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.crypto_ecc_rst().clear_bit()); + perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.crypto_ecc_rst().clear_bit()); + } } #[cfg(lcd_cam)] Peripheral::LcdCam => { - perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().set_bit()); - perip_rst_en1.modify(|_, w| w.lcd_cam_rst().clear_bit()); + perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().bit(enable)); + if enable { + perip_rst_en1.modify(|_, w| w.lcd_cam_rst().clear_bit()); + } } #[cfg(systimer)] Peripheral::Systimer => { - perip_clk_en0.modify(|_, w| w.systimer_clk_en().set_bit()); - perip_rst_en0.modify(|_, w| w.systimer_rst().clear_bit()); + perip_clk_en0.modify(|_, w| w.systimer_clk_en().bit(enable)); + if enable { + perip_rst_en0.modify(|_, w| w.systimer_rst().clear_bit()); + } } }); } @@ -560,89 +633,122 @@ impl PeripheralClockControl { #[cfg(any(esp32c6, esp32h2))] impl PeripheralClockControl { - /// Enables and resets the given peripheral - pub(crate) fn enable(peripheral: Peripheral) { + /// Enables or disables the given peripheral depending on the value of + /// enable. + pub(crate) fn enable(peripheral: Peripheral, enable: bool) { let system = unsafe { &*SYSTEM::PTR }; match peripheral { #[cfg(spi2)] Peripheral::Spi2 => { - system.spi2_conf().modify(|_, w| w.spi2_clk_en().set_bit()); system .spi2_conf() - .modify(|_, w| w.spi2_rst_en().clear_bit()); + .modify(|_, w| w.spi2_clk_en().bit(enable)); + if enable { + system + .spi2_conf() + .modify(|_, w| w.spi2_rst_en().clear_bit()); + } } #[cfg(i2c0)] Peripheral::I2cExt0 => { #[cfg(any(esp32c6, esp32h2))] { - system.i2c0_conf().modify(|_, w| w.i2c0_clk_en().set_bit()); system .i2c0_conf() - .modify(|_, w| w.i2c0_rst_en().clear_bit()); + .modify(|_, w| w.i2c0_clk_en().bit(enable)); + if enable { + system + .i2c0_conf() + .modify(|_, w| w.i2c0_rst_en().clear_bit()); + } } } #[cfg(i2c1)] Peripheral::I2cExt1 => { #[cfg(esp32h2)] { - system.i2c1_conf().modify(|_, w| w.i2c1_clk_en().set_bit()); system .i2c1_conf() - .modify(|_, w| w.i2c1_rst_en().clear_bit()); + .modify(|_, w| w.i2c1_clk_en().bit(enable)); + if enable { + system + .i2c1_conf() + .modify(|_, w| w.i2c1_rst_en().clear_bit()); + } } } #[cfg(rmt)] Peripheral::Rmt => { - system.rmt_conf().modify(|_, w| w.rmt_clk_en().set_bit()); - system.rmt_conf().modify(|_, w| w.rmt_rst_en().clear_bit()); + system.rmt_conf().modify(|_, w| w.rmt_clk_en().bit(enable)); + if enable { + system.rmt_conf().modify(|_, w| w.rmt_rst_en().clear_bit()); + } } #[cfg(ledc)] Peripheral::Ledc => { - system.ledc_conf().modify(|_, w| w.ledc_clk_en().set_bit()); system .ledc_conf() - .modify(|_, w| w.ledc_rst_en().clear_bit()); + .modify(|_, w| w.ledc_clk_en().bit(enable)); + if enable { + system + .ledc_conf() + .modify(|_, w| w.ledc_rst_en().clear_bit()); + } } #[cfg(mcpwm0)] Peripheral::Mcpwm0 => { - system.pwm_conf().modify(|_, w| w.pwm_clk_en().set_bit()); - system.pwm_conf().modify(|_, w| w.pwm_rst_en().clear_bit()); + system.pwm_conf().modify(|_, w| w.pwm_clk_en().bit(enable)); + if enable { + system.pwm_conf().modify(|_, w| w.pwm_rst_en().clear_bit()); + } } #[cfg(mcpwm1)] Peripheral::Mcpwm1 => { - system.pwm_conf.modify(|_, w| w.pwm_clk_en().set_bit()); - system.pwm_conf.modify(|_, w| w.pwm_rst_en().clear_bit()); + system.pwm_conf.modify(|_, w| w.pwm_clk_en().bit(enable)); + if enable { + system.pwm_conf.modify(|_, w| w.pwm_rst_en().clear_bit()); + } } #[cfg(apb_saradc)] Peripheral::ApbSarAdc => { system .saradc_conf() - .modify(|_, w| w.saradc_reg_clk_en().set_bit()); - system - .saradc_conf() - .modify(|_, w| w.saradc_reg_rst_en().clear_bit()); + .modify(|_, w| w.saradc_reg_clk_en().bit(enable)); + if enable { + system + .saradc_conf() + .modify(|_, w| w.saradc_reg_rst_en().clear_bit()); + } } #[cfg(gdma)] Peripheral::Gdma => { - system.gdma_conf().modify(|_, w| w.gdma_clk_en().set_bit()); system .gdma_conf() - .modify(|_, w| w.gdma_rst_en().clear_bit()); + .modify(|_, w| w.gdma_clk_en().bit(enable)); + if enable { + system + .gdma_conf() + .modify(|_, w| w.gdma_rst_en().clear_bit()); + } } #[cfg(i2s0)] Peripheral::I2s0 => { - system.i2s_conf().modify(|_, w| w.i2s_clk_en().set_bit()); - system.i2s_conf().modify(|_, w| w.i2s_rst_en().clear_bit()); + system.i2s_conf().modify(|_, w| w.i2s_clk_en().bit(enable)); + if enable { + system.i2s_conf().modify(|_, w| w.i2s_rst_en().clear_bit()); + } } #[cfg(twai0)] Peripheral::Twai0 => { system .twai0_conf() - .modify(|_, w| w.twai0_clk_en().set_bit()); - system - .twai0_conf() - .modify(|_, w| w.twai0_rst_en().clear_bit()); + .modify(|_, w| w.twai0_clk_en().bit(enable)); + if enable { + system + .twai0_conf() + .modify(|_, w| w.twai0_rst_en().clear_bit()); + } // use Xtal clk-src system.twai0_func_clk_conf().modify(|_, w| { @@ -656,130 +762,159 @@ impl PeripheralClockControl { Peripheral::Twai1 => { system .twai1_conf() - .modify(|_, w| w.twai1_clk_en().set_bit()); - system - .twai1_conf() - .modify(|_, w| w.twai1_rst_en().clear_bit()); + .modify(|_, w| w.twai1_clk_en().bit(enable)); + if enable { + system + .twai1_conf() + .modify(|_, w| w.twai1_rst_en().clear_bit()); + } } #[cfg(aes)] Peripheral::Aes => { - system.aes_conf().modify(|_, w| w.aes_clk_en().set_bit()); - system.aes_conf().modify(|_, w| w.aes_rst_en().clear_bit()); + system.aes_conf().modify(|_, w| w.aes_clk_en().bit(enable)); + if enable { + system.aes_conf().modify(|_, w| w.aes_rst_en().clear_bit()); + } } #[cfg(pcnt)] Peripheral::Pcnt => { - system.pcnt_conf().modify(|_, w| w.pcnt_clk_en().set_bit()); system .pcnt_conf() - .modify(|_, w| w.pcnt_rst_en().clear_bit()); + .modify(|_, w| w.pcnt_clk_en().bit(enable)); + if enable { + system + .pcnt_conf() + .modify(|_, w| w.pcnt_rst_en().clear_bit()); + } } #[cfg(timg0)] Peripheral::Timg0 => { system .timergroup0_timer_clk_conf() - .modify(|_, w| w.tg0_timer_clk_en().set_bit()); + .modify(|_, w| w.tg0_timer_clk_en().bit(enable)); } #[cfg(timg1)] Peripheral::Timg1 => { system .timergroup1_timer_clk_conf() - .modify(|_, w| w.tg1_timer_clk_en().set_bit()); + .modify(|_, w| w.tg1_timer_clk_en().bit(enable)); } #[cfg(lp_wdt)] Peripheral::Wdt => { system .timergroup0_wdt_clk_conf() - .modify(|_, w| w.tg0_wdt_clk_en().set_bit()); + .modify(|_, w| w.tg0_wdt_clk_en().bit(enable)); system .timergroup1_timer_clk_conf() - .modify(|_, w| w.tg1_timer_clk_en().set_bit()); + .modify(|_, w| w.tg1_timer_clk_en().bit(enable)); } #[cfg(sha)] Peripheral::Sha => { - system.sha_conf().modify(|_, w| w.sha_clk_en().set_bit()); - system.sha_conf().modify(|_, w| w.sha_rst_en().clear_bit()); + system.sha_conf().modify(|_, w| w.sha_clk_en().bit(enable)); + if enable { + system.sha_conf().modify(|_, w| w.sha_rst_en().clear_bit()); + } } #[cfg(usb_device)] Peripheral::UsbDevice => { system .usb_device_conf() - .modify(|_, w| w.usb_device_clk_en().set_bit()); - system - .usb_device_conf() - .modify(|_, w| w.usb_device_rst_en().clear_bit()); + .modify(|_, w| w.usb_device_clk_en().bit(enable)); + if enable { + system + .usb_device_conf() + .modify(|_, w| w.usb_device_rst_en().clear_bit()); + } } #[cfg(uart0)] Peripheral::Uart0 => { system .uart0_conf() - .modify(|_, w| w.uart0_clk_en().set_bit()); - system - .uart0_conf() - .modify(|_, w| w.uart0_rst_en().clear_bit()); + .modify(|_, w| w.uart0_clk_en().bit(enable)); + if enable { + system + .uart0_conf() + .modify(|_, w| w.uart0_rst_en().clear_bit()); + } } #[cfg(uart1)] Peripheral::Uart1 => { system .uart1_conf() - .modify(|_, w| w.uart1_clk_en().set_bit()); - system - .uart1_conf() - .modify(|_, w| w.uart1_rst_en().clear_bit()); + .modify(|_, w| w.uart1_clk_en().bit(enable)); + if enable { + system + .uart1_conf() + .modify(|_, w| w.uart1_rst_en().clear_bit()); + } } #[cfg(rsa)] Peripheral::Rsa => { - system.rsa_conf().modify(|_, w| w.rsa_clk_en().set_bit()); - system.rsa_conf().modify(|_, w| w.rsa_rst_en().clear_bit()); - system - .rsa_pd_ctrl() - .modify(|_, w| w.rsa_mem_pd().clear_bit()); + system.rsa_conf().modify(|_, w| w.rsa_clk_en().bit(enable)); + if enable { + system.rsa_conf().modify(|_, w| w.rsa_rst_en().clear_bit()); + system + .rsa_pd_ctrl() + .modify(|_, w| w.rsa_mem_pd().clear_bit()); + } } #[cfg(parl_io)] Peripheral::ParlIo => { system .parl_io_conf() - .modify(|_, w| w.parl_clk_en().set_bit()); - system - .parl_io_conf() - .modify(|_, w| w.parl_rst_en().set_bit()); - system - .parl_io_conf() - .modify(|_, w| w.parl_rst_en().clear_bit()); + .modify(|_, w| w.parl_clk_en().bit(enable)); + if enable { + system + .parl_io_conf() + .modify(|_, w| w.parl_rst_en().clear_bit()); + } } #[cfg(hmac)] Peripheral::Hmac => { - system.hmac_conf().modify(|_, w| w.hmac_clk_en().set_bit()); system .hmac_conf() - .modify(|_, w| w.hmac_rst_en().clear_bit()); + .modify(|_, w| w.hmac_clk_en().bit(enable)); + if enable { + system + .hmac_conf() + .modify(|_, w| w.hmac_rst_en().clear_bit()); + } } #[cfg(ecc)] Peripheral::Ecc => { - system.ecc_conf().modify(|_, w| w.ecc_clk_en().set_bit()); - system.ecc_conf().modify(|_, w| w.ecc_rst_en().clear_bit()); + system.ecc_conf().modify(|_, w| w.ecc_clk_en().bit(enable)); + if enable { + system.ecc_conf().modify(|_, w| w.ecc_rst_en().clear_bit()); + } } #[cfg(soc_etm)] Peripheral::Etm => { - system.etm_conf().modify(|_, w| w.etm_clk_en().set_bit()); - system.etm_conf().modify(|_, w| w.etm_rst_en().clear_bit()); + system.etm_conf().modify(|_, w| w.etm_clk_en().bit(enable)); + if enable { + system.etm_conf().modify(|_, w| w.etm_rst_en().clear_bit()); + } } #[cfg(trace0)] Peripheral::Trace0 => { system .trace_conf() - .modify(|_, w| w.trace_clk_en().set_bit()); - system - .trace_conf() - .modify(|_, w| w.trace_rst_en().clear_bit()); + .modify(|_, w| w.trace_clk_en().bit(enable)); + if enable { + system + .trace_conf() + .modify(|_, w| w.trace_rst_en().clear_bit()); + } } #[cfg(systimer)] Peripheral::Systimer => { system .systimer_conf() - .modify(|_, w| w.systimer_clk_en().set_bit()); - system - .systimer_conf() - .modify(|_, w| w.systimer_rst_en().clear_bit()); + .modify(|_, w| w.systimer_clk_en().bit(enable)); + if enable { + system + .systimer_conf() + .modify(|_, w| w.systimer_rst_en().clear_bit()); + } } } } diff --git a/esp-hal/src/timer/systimer.rs b/esp-hal/src/timer/systimer.rs index d2bac3ddf19..93804af5226 100644 --- a/esp-hal/src/timer/systimer.rs +++ b/esp-hal/src/timer/systimer.rs @@ -148,7 +148,7 @@ impl<'d> SystemTimer<'d> { /// Create a new instance. pub fn new(_systimer: impl Peripheral

+ 'd) -> Self { // Don't reset Systimer as it will break `time::now`, only enable it - PeripheralClockControl::enable(PeripheralEnable::Systimer); + PeripheralClockControl::enable(PeripheralEnable::Systimer, true); #[cfg(soc_etm)] etm::enable_etm(); diff --git a/esp-hal/src/timer/timg.rs b/esp-hal/src/timer/timg.rs index 8f67b33db23..e19f0683986 100644 --- a/esp-hal/src/timer/timg.rs +++ b/esp-hal/src/timer/timg.rs @@ -152,7 +152,7 @@ impl TimerGroupInstance for TIMG0 { } fn enable_peripheral() { - crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Timg0) + crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Timg0, true) } fn reset_peripheral() { @@ -215,7 +215,7 @@ impl TimerGroupInstance for crate::peripherals::TIMG1 { } fn enable_peripheral() { - crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Timg1) + crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Timg1, true) } fn reset_peripheral() { @@ -820,7 +820,7 @@ where TG: TimerGroupInstance, { fn enable_peripheral(&self) { - PeripheralClockControl::enable(PeripheralEnable::Timg0); + PeripheralClockControl::enable(PeripheralEnable::Timg0, true); } } @@ -830,7 +830,7 @@ where TG: TimerGroupInstance, { fn enable_peripheral(&self) { - PeripheralClockControl::enable(PeripheralEnable::Timg1); + PeripheralClockControl::enable(PeripheralEnable::Timg1, true); } } @@ -956,7 +956,7 @@ where /// Construct a new instance of [`Wdt`] pub fn new() -> Self { #[cfg(lp_wdt)] - PeripheralClockControl::enable(PeripheralEnable::Wdt); + PeripheralClockControl::enable(PeripheralEnable::Wdt, true); TG::configure_wdt_src_clk(); diff --git a/esp-hal/src/trace.rs b/esp-hal/src/trace.rs index a0c735b1e4e..62ae47ed73f 100644 --- a/esp-hal/src/trace.rs +++ b/esp-hal/src/trace.rs @@ -22,8 +22,8 @@ //! ```rust, no_run #![doc = crate::before_snippet!()] //! # use esp_hal::trace::Trace; -//! let mut trace = Trace::new(peripherals.TRACE0); //! let mut buffer = [0_u8; 1024]; +//! let mut trace = Trace::new(peripherals.TRACE0); //! trace.start_trace(&mut buffer); //! // traced code //! @@ -70,7 +70,7 @@ where crate::into_ref!(peripheral); PeripheralClockControl::reset(crate::system::Peripheral::Trace0); - PeripheralClockControl::enable(crate::system::Peripheral::Trace0); + PeripheralClockControl::enable(crate::system::Peripheral::Trace0, true); Self { peripheral, @@ -203,6 +203,12 @@ where } } +impl<'d, T> Drop for Trace<'d, T> { + fn drop(&mut self) { + PeripheralClockControl::enable(crate::system::Peripheral::Trace0, false); + } +} + /// Trace peripheral instance pub trait Instance: crate::private::Sealed { /// Get a reference to the peripheral's underlying register block diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index a89d5cfda3d..b8fa6d31b8e 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -774,7 +774,7 @@ where crate::into_mapped_ref!(tx_pin, rx_pin); // Enable the peripheral clock for the TWAI peripheral. - PeripheralClockControl::enable(twai.peripheral()); + PeripheralClockControl::enable(twai.peripheral(), true); PeripheralClockControl::reset(twai.peripheral()); let mut this = TwaiConfiguration { diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index ef1ccb9e3b0..30e3ad03058 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -1210,7 +1210,7 @@ where } }; - PeripheralClockControl::enable(self.tx.uart.info().peripheral); + PeripheralClockControl::enable(self.tx.uart.info().peripheral, true); self.uart_peripheral_reset(); self.rx.disable_rx_interrupts(); self.tx.disable_tx_interrupts(); diff --git a/esp-hal/src/usb_serial_jtag.rs b/esp-hal/src/usb_serial_jtag.rs index 42c82f8aacd..69ab2ecce07 100644 --- a/esp-hal/src/usb_serial_jtag.rs +++ b/esp-hal/src/usb_serial_jtag.rs @@ -314,7 +314,7 @@ where fn new_inner(usb_device: impl Peripheral

+ 'd) -> Self { // Do NOT reset the peripheral. Doing so will result in a broken USB JTAG // connection. - PeripheralClockControl::enable(crate::system::Peripheral::UsbDevice); + PeripheralClockControl::enable(crate::system::Peripheral::UsbDevice, true); USB_DEVICE::disable_tx_interrupts(); USB_DEVICE::disable_rx_interrupts();