From 4bc9668b1add43a2b9e1c5f265e9ca31cbc22288 Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Wed, 13 Nov 2024 15:35:58 +0100 Subject: [PATCH 01/14] Disable peripherals when unused --- esp-hal/src/aes/esp32.rs | 6 +- esp-hal/src/aes/esp32cX.rs | 6 +- esp-hal/src/aes/esp32s2.rs | 6 +- esp-hal/src/aes/esp32s3.rs | 6 +- esp-hal/src/aes/mod.rs | 11 +- esp-hal/src/analog/adc/riscv.rs | 11 +- esp-hal/src/analog/adc/xtensa.rs | 11 +- esp-hal/src/dma/gdma.rs | 4 +- esp-hal/src/dma/pdma.rs | 4 +- esp-hal/src/ecc.rs | 11 +- esp-hal/src/etm.rs | 10 +- esp-hal/src/hmac.rs | 11 +- esp-hal/src/i2c/master/mod.rs | 14 +- esp-hal/src/i2s/master.rs | 24 +- esp-hal/src/i2s/parallel.rs | 8 +- esp-hal/src/lcd_cam/mod.rs | 10 +- esp-hal/src/ledc/mod.rs | 5 +- esp-hal/src/lib.rs | 2 + esp-hal/src/mcpwm/mod.rs | 43 +- esp-hal/src/mcpwm/operator.rs | 24 +- esp-hal/src/mcpwm/timer.rs | 4 + esp-hal/src/otg_fs.rs | 11 +- esp-hal/src/parl_io.rs | 40 +- esp-hal/src/pcnt/channel.rs | 5 + esp-hal/src/pcnt/mod.rs | 10 +- esp-hal/src/pcnt/unit.rs | 7 +- esp-hal/src/rmt.rs | 56 +- esp-hal/src/rsa/mod.rs | 9 +- esp-hal/src/sha.rs | 11 +- esp-hal/src/spi/master.rs | 17 +- esp-hal/src/spi/slave.rs | 13 +- esp-hal/src/system.rs | 867 ++++++++++++------------ esp-hal/src/timer/systimer.rs | 2 +- esp-hal/src/timer/timg.rs | 7 +- esp-hal/src/trace.rs | 26 +- esp-hal/src/twai/mod.rs | 16 +- esp-hal/src/uart.rs | 17 +- esp-hal/src/usb_serial_jtag.rs | 2 +- examples/src/bin/spi_loopback.rs | 4 +- hil-test/tests/spi_half_duplex_write.rs | 3 +- 40 files changed, 783 insertions(+), 571 deletions(-) diff --git a/esp-hal/src/aes/esp32.rs b/esp-hal/src/aes/esp32.rs index dd69d4c5439..4e63a5f7fdc 100644 --- a/esp-hal/src/aes/esp32.rs +++ b/esp-hal/src/aes/esp32.rs @@ -1,11 +1,7 @@ -use crate::{ - aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, -}; +use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE}; impl<'d> Aes<'d> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); self.write_endianness( Endianness::BigEndian, Endianness::BigEndian, diff --git a/esp-hal/src/aes/esp32cX.rs b/esp-hal/src/aes/esp32cX.rs index 9477b17579b..1851bba4721 100644 --- a/esp-hal/src/aes/esp32cX.rs +++ b/esp-hal/src/aes/esp32cX.rs @@ -1,11 +1,7 @@ -use crate::{ - aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, -}; +use crate::aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE}; impl Aes<'_> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); self.write_dma(false); } diff --git a/esp-hal/src/aes/esp32s2.rs b/esp-hal/src/aes/esp32s2.rs index d00c34d20e8..b0a2d7e97fc 100644 --- a/esp-hal/src/aes/esp32s2.rs +++ b/esp-hal/src/aes/esp32s2.rs @@ -1,11 +1,7 @@ -use crate::{ - aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, -}; +use crate::aes::{Aes, Aes128, Aes192, Aes256, AesFlavour, Endianness, ALIGN_SIZE}; impl<'d> Aes<'d> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); 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 3e8085348a8..adc101bcea8 100644 --- a/esp-hal/src/aes/esp32s3.rs +++ b/esp-hal/src/aes/esp32s3.rs @@ -1,11 +1,7 @@ -use crate::{ - aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, -}; +use crate::aes::{Aes, Aes128, Aes256, AesFlavour, ALIGN_SIZE}; impl<'d> Aes<'d> { pub(super) fn init(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Aes); self.write_dma(false); } diff --git a/esp-hal/src/aes/mod.rs b/esp-hal/src/aes/mod.rs index 34a14f03ce9..f64b4acb769 100644 --- a/esp-hal/src/aes/mod.rs +++ b/esp-hal/src/aes/mod.rs @@ -143,8 +143,9 @@ 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); + if crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Aes, true) { + crate::system::PeripheralClockControl::reset(crate::system::Peripheral::Aes); + } let mut ret = Self { aes, @@ -190,6 +191,12 @@ impl<'d> Aes<'d> { } } +impl Drop for Aes<'_> { + fn drop(&mut self) { + crate::system::PeripheralClockControl::enable(crate::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 c9c4bcdd655..63b592857e6 100644 --- a/esp-hal/src/analog/adc/riscv.rs +++ b/esp-hal/src/analog/adc/riscv.rs @@ -408,8 +408,9 @@ where adc_instance: impl crate::peripheral::Peripheral

+ 'd, config: AdcConfig, ) -> Self { - PeripheralClockControl::reset(Peripheral::ApbSarAdc); - PeripheralClockControl::enable(Peripheral::ApbSarAdc); + if PeripheralClockControl::enable(Peripheral::ApbSarAdc, true) { + PeripheralClockControl::reset(Peripheral::ApbSarAdc); + } unsafe { &*APB_SARADC::PTR }.ctrl().modify(|_, w| unsafe { w.start_force().set_bit(); @@ -500,6 +501,12 @@ where } } +impl Drop for Adc<'_, ADCI> { + fn drop(&mut self) { + PeripheralClockControl::enable(Peripheral::ApbSarAdc, false); + } +} + #[cfg(any(esp32c2, esp32c3, esp32c6))] impl super::AdcCalEfuse for crate::peripherals::ADC1 { fn init_code(atten: Attenuation) -> Option { diff --git a/esp-hal/src/analog/adc/xtensa.rs b/esp-hal/src/analog/adc/xtensa.rs index 324c79462db..b60a76c0f6d 100644 --- a/esp-hal/src/analog/adc/xtensa.rs +++ b/esp-hal/src/analog/adc/xtensa.rs @@ -401,8 +401,9 @@ where adc_instance: impl crate::peripheral::Peripheral

+ 'd, config: AdcConfig, ) -> Self { - PeripheralClockControl::reset(Peripheral::ApbSarAdc); - PeripheralClockControl::enable(Peripheral::ApbSarAdc); + if PeripheralClockControl::enable(Peripheral::ApbSarAdc, true) { + PeripheralClockControl::reset(Peripheral::ApbSarAdc); + } let sensors = unsafe { &*SENS::ptr() }; @@ -560,6 +561,12 @@ where } } +impl Drop for Adc<'_, ADCI> { + fn drop(&mut self) { + PeripheralClockControl::enable(Peripheral::ApbSarAdc, false); + } +} + #[cfg(esp32s3)] impl super::AdcCalEfuse for crate::peripherals::ADC1 { fn init_code(atten: Attenuation) -> Option { diff --git a/esp-hal/src/dma/gdma.rs b/esp-hal/src/dma/gdma.rs index 8c2ca9a2468..581a8f9564f 100644 --- a/esp-hal/src/dma/gdma.rs +++ b/esp-hal/src/dma/gdma.rs @@ -753,7 +753,9 @@ impl<'d> Dma<'d> { ) -> Dma<'d> { crate::into_ref!(dma); - PeripheralClockControl::enable(Peripheral::Gdma); + if PeripheralClockControl::enable(Peripheral::Gdma, true) { + PeripheralClockControl::reset(Peripheral::Gdma); + } 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 609c89f24e4..0023f007b98 100644 --- a/esp-hal/src/dma/pdma.rs +++ b/esp-hal/src/dma/pdma.rs @@ -942,7 +942,9 @@ impl<'d> Dma<'d> { pub fn new( dma: impl crate::peripheral::Peripheral

+ 'd, ) -> Dma<'d> { - PeripheralClockControl::enable(Peripheral::Dma); + if PeripheralClockControl::enable(Peripheral::Dma, true) { + PeripheralClockControl::reset(Peripheral::Dma); + } #[cfg(esp32)] { diff --git a/esp-hal/src/ecc.rs b/esp-hal/src/ecc.rs index 7c6ccfcc2b9..74a31ff671c 100644 --- a/esp-hal/src/ecc.rs +++ b/esp-hal/src/ecc.rs @@ -102,8 +102,9 @@ impl<'d> Ecc<'d, crate::Blocking> { pub fn new(ecc: impl Peripheral

+ 'd) -> Self { crate::into_ref!(ecc); - PeripheralClockControl::reset(PeripheralEnable::Ecc); - PeripheralClockControl::enable(PeripheralEnable::Ecc); + if PeripheralClockControl::enable(PeripheralEnable::Ecc, true) { + PeripheralClockControl::reset(PeripheralEnable::Ecc); + } Self { ecc, @@ -964,3 +965,9 @@ impl Ecc<'_, DM> { } } } + +impl Drop for Ecc<'_, DM> { + fn drop(&mut self) { + PeripheralClockControl::enable(PeripheralEnable::Ecc, false); + } +} diff --git a/esp-hal/src/etm.rs b/esp-hal/src/etm.rs index 5276eadcccf..a2590cdeab7 100644 --- a/esp-hal/src/etm.rs +++ b/esp-hal/src/etm.rs @@ -75,6 +75,10 @@ impl EtmChannel { E: EtmEvent, T: EtmTask, { + if PeripheralClockControl::enable(crate::system::Peripheral::Etm, true) { + PeripheralClockControl::reset(crate::system::Peripheral::Etm); + } + let etm = unsafe { crate::peripherals::SOC_ETM::steal() }; etm.ch(C as usize) @@ -125,8 +129,9 @@ where T: EtmTask, { fn drop(&mut self) { - debug!("drop {}", C); + debug!("Drop ETM channel {}", C); disable_channel(C); + PeripheralClockControl::enable(crate::system::Peripheral::Etm, false); } } @@ -149,9 +154,6 @@ macro_rules! create_etm { pub fn new(peripheral: impl Peripheral

+ 'd) -> Self { crate::into_ref!(peripheral); - PeripheralClockControl::reset(crate::system::Peripheral::Etm); - PeripheralClockControl::enable(crate::system::Peripheral::Etm); - Self { _peripheral: peripheral, $([< channel $num >]: EtmChannel {},)+ diff --git a/esp-hal/src/hmac.rs b/esp-hal/src/hmac.rs index e7709972b50..bd40a18d8df 100644 --- a/esp-hal/src/hmac.rs +++ b/esp-hal/src/hmac.rs @@ -107,8 +107,9 @@ impl<'d> Hmac<'d> { pub fn new(hmac: impl Peripheral

+ 'd) -> Self { crate::into_ref!(hmac); - PeripheralClockControl::reset(PeripheralEnable::Hmac); - PeripheralClockControl::enable(PeripheralEnable::Hmac); + if PeripheralClockControl::enable(PeripheralEnable::Hmac, true) { + PeripheralClockControl::reset(PeripheralEnable::Hmac); + } Self { hmac, @@ -345,3 +346,9 @@ impl<'d> Hmac<'d> { while self.is_busy() {} } } + +impl Drop for Hmac<'_> { + fn drop(&mut self) { + PeripheralClockControl::enable(PeripheralEnable::Hmac, true); + } +} diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index fbbd8729904..dff8d9f1832 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -59,7 +59,7 @@ use crate::{ Interrupt, }, private, - system::PeripheralClockControl, + system::{PeripheralClockControl, PeripheralGuard}, Async, Blocking, Cpu, @@ -273,6 +273,7 @@ pub struct I2c<'d, DM: Mode, T = AnyI2c> { i2c: PeripheralRef<'d, T>, phantom: PhantomData, config: Config, + guard: PeripheralGuard, } impl SetConfig for I2c<'_, DM, T> { @@ -352,8 +353,9 @@ where } fn internal_recover(&self) { + PeripheralClockControl::enable(self.driver().info.peripheral, false); + PeripheralClockControl::enable(self.driver().info.peripheral, true); PeripheralClockControl::reset(self.driver().info.peripheral); - PeripheralClockControl::enable(self.driver().info.peripheral); // We know the configuration is valid, we can ignore the result. _ = self.driver().setup(&self.config); @@ -469,15 +471,15 @@ where pub fn new_typed(i2c: impl Peripheral

+ 'd, config: Config) -> Self { crate::into_ref!(i2c); + let guard = PeripheralGuard::new(i2c.info().peripheral); + let i2c = I2c { i2c, phantom: PhantomData, config, + guard, }; - PeripheralClockControl::reset(i2c.driver().info.peripheral); - PeripheralClockControl::enable(i2c.driver().info.peripheral); - unwrap!(i2c.driver().setup(&i2c.config)); i2c } @@ -492,6 +494,7 @@ where i2c: self.i2c, phantom: PhantomData, config: self.config, + guard: self.guard, } } @@ -695,6 +698,7 @@ where i2c: self.i2c, phantom: PhantomData, config: self.config, + guard: self.guard, } } diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index 111596ae9ff..8c89ebf52a7 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -100,7 +100,7 @@ use crate::{ gpio::interconnect::PeripheralOutput, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, - system::PeripheralClockControl, + system::PeripheralGuard, Async, Blocking, InterruptConfigurable, @@ -259,6 +259,7 @@ where pub i2s_rx: RxCreator<'d, M, T>, /// Handles the transmission (TX) side of the I2S peripheral. pub i2s_tx: TxCreator<'d, M, T>, + guard: PeripheralGuard, } impl<'d, DmaMode, T> I2s<'d, DmaMode, T> @@ -284,8 +285,10 @@ where // could be configured totally independently but for now handle all // the targets the same and force same configuration for both, TX and RX - PeripheralClockControl::reset(i2s.peripheral()); - PeripheralClockControl::enable(i2s.peripheral()); + // make sure the peripheral is enabled before configuring it + let peripheral = i2s.peripheral(); + let guard = PeripheralGuard::new(peripheral); + i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits())); i2s.configure(&standard, &data_format); i2s.set_master(); @@ -297,12 +300,15 @@ where i2s: unsafe { i2s.clone_unchecked() }, rx_channel: channel.rx, descriptors: rx_descriptors, + guard, }, i2s_tx: TxCreator { i2s, tx_channel: channel.tx, descriptors: tx_descriptors, + guard: PeripheralGuard::new(peripheral), }, + guard: PeripheralGuard::new(peripheral), } } } @@ -432,12 +438,15 @@ where i2s: self.i2s_rx.i2s, rx_channel: self.i2s_rx.rx_channel.into_async(), descriptors: self.i2s_rx.descriptors, + guard: self.i2s_rx.guard, }, i2s_tx: TxCreator { i2s: self.i2s_tx.i2s, tx_channel: self.i2s_tx.tx_channel.into_async(), descriptors: self.i2s_tx.descriptors, + guard: self.i2s_tx.guard, }, + guard: self.guard, } } } @@ -465,6 +474,7 @@ where i2s: PeripheralRef<'d, T>, tx_channel: ChannelTx<'d, DmaMode, T::Dma>, tx_chain: DescriptorChain, + _guard: PeripheralGuard, } impl core::fmt::Debug for I2sTx<'_, DmaMode, T> @@ -597,6 +607,7 @@ where i2s: PeripheralRef<'d, T>, rx_channel: ChannelRx<'d, DmaMode, T::Dma>, rx_chain: DescriptorChain, + _guard: PeripheralGuard, } impl core::fmt::Debug for I2sRx<'_, DmaMode, T> @@ -742,6 +753,7 @@ mod private { I2sInterrupt, I2sRx, I2sTx, + PeripheralGuard, RegisterAccess, Standard, I2S_LL_MCLK_DIVIDER_MAX, @@ -774,6 +786,7 @@ mod private { pub i2s: PeripheralRef<'d, T>, pub tx_channel: ChannelTx<'d, M, T::Dma>, pub descriptors: &'static mut [DmaDescriptor], + pub(crate) guard: PeripheralGuard, } impl<'d, M, T> TxCreator<'d, M, T> @@ -782,10 +795,12 @@ mod private { T: RegisterAccess, { pub fn build(self) -> I2sTx<'d, M, T> { + let peripheral = self.i2s.peripheral(); I2sTx { i2s: self.i2s, tx_channel: self.tx_channel, tx_chain: DescriptorChain::new(self.descriptors), + _guard: PeripheralGuard::new(peripheral), } } @@ -831,6 +846,7 @@ mod private { pub i2s: PeripheralRef<'d, T>, pub rx_channel: ChannelRx<'d, M, T::Dma>, pub descriptors: &'static mut [DmaDescriptor], + pub(crate) guard: PeripheralGuard, } impl<'d, M, T> RxCreator<'d, M, T> @@ -839,10 +855,12 @@ mod private { T: RegisterAccess, { pub fn build(self) -> I2sRx<'d, M, T> { + let peripheral = self.i2s.peripheral(); I2sRx { i2s: self.i2s, rx_channel: self.rx_channel, rx_chain: DescriptorChain::new(self.descriptors), + _guard: PeripheralGuard::new(peripheral), } } diff --git a/esp-hal/src/i2s/parallel.rs b/esp-hal/src/i2s/parallel.rs index 9d6ab818a7d..810b116860a 100644 --- a/esp-hal/src/i2s/parallel.rs +++ b/esp-hal/src/i2s/parallel.rs @@ -60,7 +60,7 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::{i2s0::RegisterBlock, I2S0, I2S1}, private::Internal, - system::PeripheralClockControl, + system::PeripheralGuard, Async, Mode, }; @@ -177,6 +177,7 @@ where { instance: PeripheralRef<'d, I>, tx_channel: ChannelTx<'d, DM, I::Dma>, + _guard: PeripheralGuard, } impl<'d, DM> I2sParallel<'d, DM> @@ -220,8 +221,8 @@ where channel.runtime_ensure_compatible(&i2s); let channel = channel.degrade(); - PeripheralClockControl::reset(i2s.peripheral()); - PeripheralClockControl::enable(i2s.peripheral()); + let guard = PeripheralGuard::new(i2s.peripheral()); + // configure the I2S peripheral for parallel mode i2s.setup(frequency, pins.bus_width()); // setup the clock pin @@ -232,6 +233,7 @@ where Self { instance: i2s, tx_channel: channel.tx, + _guard: guard, } } diff --git a/esp-hal/src/lcd_cam/mod.rs b/esp-hal/src/lcd_cam/mod.rs index b442b2450ef..5a993833c62 100644 --- a/esp-hal/src/lcd_cam/mod.rs +++ b/esp-hal/src/lcd_cam/mod.rs @@ -18,7 +18,7 @@ use crate::{ macros::handler, peripheral::Peripheral, peripherals::{Interrupt, LCD_CAM}, - system::{self, PeripheralClockControl}, + system::{self, PeripheralGuard}, Async, Blocking, Cpu, @@ -31,6 +31,8 @@ pub struct LcdCam<'d, DM: crate::Mode> { pub lcd: Lcd<'d, DM>, /// The Camera interface. pub cam: Cam<'d>, + + _guard: PeripheralGuard, } impl<'d> LcdCam<'d, Blocking> { @@ -38,8 +40,7 @@ impl<'d> LcdCam<'d, Blocking> { pub fn new(lcd_cam: impl Peripheral

+ 'd) -> Self { crate::into_ref!(lcd_cam); - PeripheralClockControl::reset(system::Peripheral::LcdCam); - PeripheralClockControl::enable(system::Peripheral::LcdCam); + let guard = PeripheralGuard::new(system::Peripheral::LcdCam); Self { lcd: Lcd { @@ -47,6 +48,7 @@ impl<'d> LcdCam<'d, Blocking> { _mode: PhantomData, }, cam: Cam { lcd_cam }, + _guard: guard, } } @@ -59,6 +61,7 @@ impl<'d> LcdCam<'d, Blocking> { _mode: PhantomData, }, cam: self.cam, + _guard: self._guard, } } } @@ -89,6 +92,7 @@ impl<'d> LcdCam<'d, Async> { _mode: PhantomData, }, cam: self.cam, + _guard: self._guard, } } } diff --git a/esp-hal/src/ledc/mod.rs b/esp-hal/src/ledc/mod.rs index 98b95ff72cd..83e90a6e11b 100644 --- a/esp-hal/src/ledc/mod.rs +++ b/esp-hal/src/ledc/mod.rs @@ -111,8 +111,9 @@ impl<'d> Ledc<'d> { pub fn new(_instance: impl Peripheral

+ 'd) -> Self { crate::into_ref!(_instance); - PeripheralClockControl::reset(PeripheralEnable::Ledc); - PeripheralClockControl::enable(PeripheralEnable::Ledc); + if PeripheralClockControl::enable(PeripheralEnable::Ledc, true) { + PeripheralClockControl::reset(PeripheralEnable::Ledc); + } let ledc = unsafe { &*crate::peripherals::LEDC::ptr() }; Ledc { _instance, ledc } diff --git a/esp-hal/src/lib.rs b/esp-hal/src/lib.rs index 755f02b1e7b..c9fd6b64358 100644 --- a/esp-hal/src/lib.rs +++ b/esp-hal/src/lib.rs @@ -515,6 +515,8 @@ pub struct Config { /// This function sets up the CPU clock and watchdog, then, returns the /// peripherals and clocks. pub fn init(config: Config) -> Peripherals { + system::disable_peripherals(); + let mut peripherals = Peripherals::take(); // RTC domain must be enabled before we try to disable diff --git a/esp-hal/src/mcpwm/mod.rs b/esp-hal/src/mcpwm/mod.rs index dc981794a96..f61f7035eff 100644 --- a/esp-hal/src/mcpwm/mod.rs +++ b/esp-hal/src/mcpwm/mod.rs @@ -94,7 +94,7 @@ use crate::{ clock::Clocks, gpio::OutputSignal, peripheral::{Peripheral, PeripheralRef}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, + system::{self, PeripheralGuard}, }; /// MCPWM operators @@ -115,11 +115,12 @@ pub struct McPwm<'d, PWM> { /// Timer2 pub timer2: Timer<2, PWM>, /// Operator0 - pub operator0: Operator<0, PWM>, + pub operator0: Operator<'d, 0, PWM>, /// Operator1 - pub operator1: Operator<1, PWM>, + pub operator1: Operator<'d, 1, PWM>, /// Operator2 - pub operator2: Operator<2, PWM>, + pub operator2: Operator<'d, 2, PWM>, + _guard: PeripheralGuard, } impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> { @@ -131,8 +132,7 @@ impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> { ) -> Self { crate::into_ref!(peripheral); - PWM::reset(); - PWM::enable(); + let guard = PeripheralGuard::new(PWM::peripheral()); #[cfg(not(esp32c6))] { @@ -181,6 +181,7 @@ impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> { operator0: Operator::new(), operator1: Operator::new(), operator2: Operator::new(), + _guard: guard, } } } @@ -313,26 +314,16 @@ pub struct FrequencyError; /// A MCPWM peripheral pub trait PwmPeripheral: Deref + crate::private::Sealed { - /// Enable peripheral - fn enable(); - /// Reset peripheral - fn reset(); /// Get a pointer to the peripheral RegisterBlock fn block() -> *const RegisterBlock; /// Get operator GPIO mux output signal fn output_signal() -> OutputSignal; + /// Peripheral + fn peripheral() -> system::Peripheral; } #[cfg(mcpwm0)] impl PwmPeripheral for crate::peripherals::MCPWM0 { - fn enable() { - PeripheralClockControl::enable(PeripheralEnable::Mcpwm0) - } - - fn reset() { - PeripheralClockControl::reset(PeripheralEnable::Mcpwm0) - } - fn block() -> *const RegisterBlock { Self::PTR } @@ -348,18 +339,14 @@ impl PwmPeripheral for crate::peripherals::MCPWM0 { _ => unreachable!(), } } + + fn peripheral() -> system::Peripheral { + system::Peripheral::Mcpwm0 + } } #[cfg(mcpwm1)] impl PwmPeripheral for crate::peripherals::MCPWM1 { - fn enable() { - PeripheralClockControl::enable(PeripheralEnable::Mcpwm1) - } - - fn reset() { - PeripheralClockControl::reset(PeripheralEnable::Mcpwm1) - } - fn block() -> *const RegisterBlock { Self::PTR } @@ -375,4 +362,8 @@ impl PwmPeripheral for crate::peripherals::MCPWM1 { _ => unreachable!(), } } + + fn peripheral() -> system::Peripheral { + system::Peripheral::Mcpwm1 + } } diff --git a/esp-hal/src/mcpwm/operator.rs b/esp-hal/src/mcpwm/operator.rs index 8c99ee03ecd..98441048e85 100644 --- a/esp-hal/src/mcpwm/operator.rs +++ b/esp-hal/src/mcpwm/operator.rs @@ -11,6 +11,7 @@ use core::marker::PhantomData; +use super::PeripheralGuard; use crate::{ gpio::interconnect::{OutputConnection, PeripheralOutput}, mcpwm::{timer::Timer, PwmPeripheral}, @@ -167,12 +168,15 @@ impl DeadTimeCfg { /// * Superimposes a carrier on the PWM signal, if configured to do so. (Not yet /// implemented) /// * Handles response under fault conditions. (Not yet implemented) -pub struct Operator { - phantom: PhantomData, +pub struct Operator<'d, const OP: u8, PWM> { + phantom: PhantomData<&'d PWM>, + _guard: PeripheralGuard, } -impl Operator { +impl<'d, const OP: u8, PWM: PwmPeripheral> Operator<'d, OP, PWM> { pub(super) fn new() -> Self { + let guard = PeripheralGuard::new(PWM::peripheral()); + // Side note: // It would have been nice to deselect any timer reference on peripheral // initialization. @@ -181,6 +185,7 @@ impl Operator { // written. Operator { phantom: PhantomData, + _guard: guard, } } @@ -204,7 +209,7 @@ impl Operator { } /// Use the A output with the given pin and configuration - pub fn with_pin_a<'d>( + pub fn with_pin_a( self, pin: impl Peripheral

+ 'd, config: PwmPinConfig, @@ -213,7 +218,7 @@ impl Operator { } /// Use the B output with the given pin and configuration - pub fn with_pin_b<'d>( + pub fn with_pin_b( self, pin: impl Peripheral

+ 'd, config: PwmPinConfig, @@ -222,7 +227,7 @@ impl Operator { } /// Use both the A and the B output with the given pins and configurations - pub fn with_pins<'d>( + pub fn with_pins( self, pin_a: impl Peripheral

+ 'd, config_a: PwmPinConfig, @@ -236,7 +241,7 @@ impl Operator { /// /// This is useful for complementary or mirrored signals with or without /// configured deadtime - pub fn with_linked_pins<'d>( + pub fn with_linked_pins( self, pin_a: impl Peripheral

+ 'd, config_a: PwmPinConfig, @@ -283,6 +288,7 @@ impl PwmPinConfig { pub struct PwmPin<'d, PWM, const OP: u8, const IS_A: bool> { pin: PeripheralRef<'d, OutputConnection>, phantom: PhantomData, + _guard: PeripheralGuard, } impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP, IS_A> { @@ -291,9 +297,13 @@ impl<'d, PWM: PwmPeripheral, const OP: u8, const IS_A: bool> PwmPin<'d, PWM, OP, config: PwmPinConfig, ) -> Self { crate::into_mapped_ref!(pin); + + let guard = PeripheralGuard::new(PWM::peripheral()); + let mut pin = PwmPin { pin, phantom: PhantomData, + _guard: guard, }; pin.set_actions(config.actions); pin.set_update_method(config.update_method); diff --git a/esp-hal/src/mcpwm/timer.rs b/esp-hal/src/mcpwm/timer.rs index 5afe5a37426..b4c31b584f4 100644 --- a/esp-hal/src/mcpwm/timer.rs +++ b/esp-hal/src/mcpwm/timer.rs @@ -8,6 +8,7 @@ use core::marker::PhantomData; use fugit::HertzU32; +use super::PeripheralGuard; use crate::mcpwm::{FrequencyError, PeripheralClockConfig, PwmPeripheral}; /// A MCPWM timer @@ -17,12 +18,15 @@ use crate::mcpwm::{FrequencyError, PeripheralClockConfig, PwmPeripheral}; /// [`Operator`](super::operator::Operator) of that peripheral pub struct Timer { pub(super) phantom: PhantomData, + _guard: PeripheralGuard, } impl Timer { pub(super) fn new() -> Self { + let guard = PeripheralGuard::new(PWM::peripheral()); Timer { phantom: PhantomData, + _guard: guard, } } diff --git a/esp-hal/src/otg_fs.rs b/esp-hal/src/otg_fs.rs index 97e0d246f0c..dc8a91b0e27 100644 --- a/esp-hal/src/otg_fs.rs +++ b/esp-hal/src/otg_fs.rs @@ -70,8 +70,9 @@ impl<'d> Usb<'d> { P: UsbDp + Send + Sync, M: UsbDm + Send + Sync, { - PeripheralClockControl::reset(PeripheralEnable::Usb); - PeripheralClockControl::enable(PeripheralEnable::Usb); + if PeripheralClockControl::enable(PeripheralEnable::Usb, true) { + PeripheralClockControl::reset(PeripheralEnable::Usb); + } Self { _usb0: usb0.into_ref(), @@ -110,6 +111,12 @@ impl<'d> Usb<'d> { } } +impl Drop for Usb<'_> { + 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 1b81ca2901e..797b102369c 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -54,7 +54,7 @@ use crate::{ interrupt::InterruptHandler, peripheral::{self, Peripheral}, peripherals::{self, Interrupt, PARL_IO}, - system::PeripheralClockControl, + system::PeripheralGuard, Async, Blocking, InterruptConfigurable, @@ -757,6 +757,8 @@ where P: FullDuplex + TxPins + ConfigurePins, CP: TxClkPin, { + let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + tx_pins.configure()?; clk_pin.configure(); @@ -767,6 +769,7 @@ where Ok(ParlIoTx { tx_channel: self.tx_channel, tx_chain: DescriptorChain::new(self.descriptors), + _guard: guard, }) } } @@ -788,6 +791,8 @@ where P: TxPins + ConfigurePins, CP: TxClkPin, { + let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + tx_pins.configure()?; clk_pin.configure(); @@ -798,6 +803,7 @@ where Ok(ParlIoTx { tx_channel: self.tx_channel, tx_chain: DescriptorChain::new(self.descriptors), + _guard: guard, }) } } @@ -809,6 +815,7 @@ where { tx_channel: ChannelTx<'d, DM, ::Dma>, tx_chain: DescriptorChain, + _guard: PeripheralGuard, } impl core::fmt::Debug for ParlIoTx<'_, DM> @@ -836,6 +843,8 @@ where P: FullDuplex + RxPins + ConfigurePins, CP: RxClkPin, { + let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + rx_pins.configure()?; clk_pin.configure(); @@ -845,6 +854,7 @@ where Ok(ParlIoRx { rx_channel: self.rx_channel, rx_chain: DescriptorChain::new(self.descriptors), + _guard: guard, }) } } @@ -865,6 +875,8 @@ where P: RxPins + ConfigurePins, CP: RxClkPin, { + let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + rx_pins.configure()?; clk_pin.configure(); @@ -874,6 +886,7 @@ where Ok(ParlIoRx { rx_channel: self.rx_channel, rx_chain: DescriptorChain::new(self.descriptors), + _guard: guard, }) } } @@ -885,6 +898,7 @@ where { rx_channel: ChannelRx<'d, DM, ::Dma>, rx_chain: DescriptorChain, + _guard: PeripheralGuard, } impl core::fmt::Debug for ParlIoRx<'_, DM> @@ -991,6 +1005,8 @@ where /// The receiver (RX) channel responsible for handling DMA transfers in the /// parallel I/O full-duplex operation. pub rx: RxCreatorFullDuplex<'d, DM>, + + _guard: PeripheralGuard, } impl<'d> ParlIoFullDuplex<'d, Blocking> { @@ -1007,6 +1023,7 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> { CH: DmaChannelConvert<::Dma>, Channel<'d, Blocking, CH>: From>, { + let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); let dma_channel = Channel::::from(dma_channel); internal_init(frequency)?; @@ -1014,11 +1031,14 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> { tx: TxCreatorFullDuplex { tx_channel: dma_channel.tx.degrade(), descriptors: tx_descriptors, + _guard: PeripheralGuard::new(crate::system::Peripheral::ParlIo), }, rx: RxCreatorFullDuplex { rx_channel: dma_channel.rx.degrade(), descriptors: rx_descriptors, + _guard: PeripheralGuard::new(crate::system::Peripheral::ParlIo), }, + _guard: guard, }) } @@ -1028,11 +1048,14 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> { tx: TxCreatorFullDuplex { tx_channel: self.tx.tx_channel.into_async(), descriptors: self.tx.descriptors, + _guard: self.tx._guard, }, rx: RxCreatorFullDuplex { rx_channel: self.rx.rx_channel.into_async(), descriptors: self.rx.descriptors, + _guard: self.rx._guard, }, + _guard: self._guard, } } @@ -1080,11 +1103,14 @@ impl<'d> ParlIoFullDuplex<'d, Async> { tx: TxCreatorFullDuplex { tx_channel: self.tx.tx_channel.into_blocking(), descriptors: self.tx.descriptors, + _guard: self.tx._guard, }, rx: RxCreatorFullDuplex { rx_channel: self.rx.rx_channel.into_blocking(), descriptors: self.rx.descriptors, + _guard: self.rx._guard, }, + _guard: self._guard, } } } @@ -1097,6 +1123,7 @@ where /// The transmitter (TX) channel responsible for handling DMA transfers in /// the parallel I/O operation. pub tx: TxCreator<'d, DM>, + _guard: PeripheralGuard, } impl<'d, DM> ParlIoTxOnly<'d, DM> @@ -1114,6 +1141,7 @@ where where CH: DmaChannelConvert<::Dma>, { + let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); internal_init(frequency)?; Ok(Self { @@ -1121,6 +1149,7 @@ where tx_channel: dma_channel.tx.degrade(), descriptors, }, + _guard: guard, }) } } @@ -1171,6 +1200,8 @@ where /// The receiver (RX) channel responsible for handling DMA transfers in the /// parallel I/O operation. pub rx: RxCreator<'d, DM>, + + _guard: PeripheralGuard, } impl<'d, DM> ParlIoRxOnly<'d, DM> @@ -1188,6 +1219,7 @@ where where CH: DmaChannelConvert<::Dma>, { + let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); internal_init(frequency)?; Ok(Self { @@ -1195,6 +1227,7 @@ where rx_channel: dma_channel.rx.degrade(), descriptors, }, + _guard: guard, }) } } @@ -1242,9 +1275,6 @@ fn internal_init(frequency: HertzU32) -> Result<(), Error> { return Err(Error::UnreachableClockRate); } - PeripheralClockControl::reset(crate::system::Peripheral::ParlIo); - PeripheralClockControl::enable(crate::system::Peripheral::ParlIo); - let pcr = unsafe { &*crate::peripherals::PCR::PTR }; let divider = crate::soc::constants::PARL_IO_SCLK / frequency.raw(); @@ -1476,6 +1506,7 @@ where { tx_channel: ChannelTx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], + _guard: PeripheralGuard, } /// Creates a RX channel @@ -1485,6 +1516,7 @@ where { rx_channel: ChannelRx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], + _guard: PeripheralGuard, } #[doc(hidden)] diff --git a/esp-hal/src/pcnt/channel.rs b/esp-hal/src/pcnt/channel.rs index c1c565b38e2..9bc7bf1c442 100644 --- a/esp-hal/src/pcnt/channel.rs +++ b/esp-hal/src/pcnt/channel.rs @@ -13,6 +13,7 @@ pub use crate::peripherals::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE use crate::{ gpio::{interconnect::PeripheralInput, InputSignal}, peripheral::Peripheral, + system::PeripheralGuard, }; /// Represents a channel within a pulse counter unit. @@ -20,14 +21,18 @@ pub struct Channel<'d, const UNIT: usize, const NUM: usize> { _phantom: PhantomData<&'d ()>, // Individual channels are not Send, since they share registers. _not_send: PhantomData<*const ()>, + _guard: PeripheralGuard, } impl Channel<'_, UNIT, NUM> { /// return a new Channel pub(super) fn new() -> Self { + let guard = PeripheralGuard::new(crate::system::Peripheral::Pcnt); + Self { _phantom: PhantomData, _not_send: PhantomData, + _guard: guard, } } diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index 742404b3f17..c5aad52e3e5 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -25,7 +25,7 @@ use crate::{ interrupt::{self, InterruptHandler}, peripheral::{Peripheral, PeripheralRef}, peripherals::{self, Interrupt}, - system::PeripheralClockControl, + system::PeripheralGuard, InterruptConfigurable, }; @@ -56,6 +56,8 @@ pub struct Pcnt<'d> { #[cfg(esp32)] /// Unit 7 pub unit7: Unit<'d, 7>, + + _guard: PeripheralGuard, } impl<'d> Pcnt<'d> { @@ -63,10 +65,7 @@ impl<'d> Pcnt<'d> { pub fn new(_instance: impl Peripheral

+ 'd) -> Self { crate::into_ref!(_instance); - // Enable the PCNT peripherals clock in the system peripheral - PeripheralClockControl::reset(crate::system::Peripheral::Pcnt); - PeripheralClockControl::enable(crate::system::Peripheral::Pcnt); - + let guard = PeripheralGuard::new(crate::system::Peripheral::Pcnt); let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() }; // disable filter, all events, and channel settings @@ -105,6 +104,7 @@ impl<'d> Pcnt<'d> { unit6: Unit::new(), #[cfg(esp32)] unit7: Unit::new(), + _guard: guard, } } } diff --git a/esp-hal/src/pcnt/unit.rs b/esp-hal/src/pcnt/unit.rs index fb1a0cf4914..9a2aad15bef 100644 --- a/esp-hal/src/pcnt/unit.rs +++ b/esp-hal/src/pcnt/unit.rs @@ -13,7 +13,7 @@ use core::marker::PhantomData; use critical_section::CriticalSection; -use crate::pcnt::channel::Channel; +use crate::{pcnt::channel::Channel, system::PeripheralGuard}; /// Invalid filter threshold value #[derive(Debug, Clone, Copy, PartialEq)] @@ -82,15 +82,20 @@ pub struct Unit<'d, const NUM: usize> { pub channel0: Channel<'d, NUM, 0>, /// The second channel in PCNT unit. pub channel1: Channel<'d, NUM, 1>, + + _guard: PeripheralGuard, } impl Unit<'_, NUM> { /// return a new Unit pub(super) fn new() -> Self { + let guard = PeripheralGuard::new(crate::system::Peripheral::Pcnt); + Self { counter: Counter::new(), channel0: Channel::new(), channel1: Channel::new(), + _guard: guard, } } diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index f1c0975e6d5..68de4288a18 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -94,7 +94,7 @@ use crate::{ peripheral::Peripheral, peripherals::Interrupt, soc::constants, - system::PeripheralClockControl, + system::PeripheralGuard, Async, Blocking, InterruptConfigurable, @@ -228,9 +228,6 @@ where return Err(Error::UnreachableTargetFrequency); } - PeripheralClockControl::reset(crate::system::Peripheral::Rmt); - PeripheralClockControl::enable(crate::system::Peripheral::Rmt); - cfg_if::cfg_if! { if #[cfg(any(esp32, esp32s2))] { self::chip_specific::configure_clock(); @@ -603,7 +600,10 @@ macro_rules! impl_rx_channel_creator { mod impl_for_chip { use core::marker::PhantomData; - use crate::peripheral::{Peripheral, PeripheralRef}; + use crate::{ + peripheral::{Peripheral, PeripheralRef}, + system::PeripheralGuard, + }; /// RMT Instance pub struct Rmt<'d, M> @@ -620,6 +620,7 @@ mod impl_for_chip { /// RMT Channel 3. pub channel3: ChannelCreator, phantom: PhantomData, + _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -631,21 +632,28 @@ mod impl_for_chip { ) -> Self { crate::into_ref!(peripheral); + let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); + Self { peripheral, channel0: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel1: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel2: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel3: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, + _guard: guard, } } } @@ -656,6 +664,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, + _guard: PeripheralGuard, } impl_tx_channel_creator!(0); @@ -675,7 +684,10 @@ mod impl_for_chip { mod impl_for_chip { use core::marker::PhantomData; - use crate::peripheral::{Peripheral, PeripheralRef}; + use crate::{ + peripheral::{Peripheral, PeripheralRef}, + system::PeripheralGuard, + }; /// RMT Instance pub struct Rmt<'d, M> @@ -710,34 +722,44 @@ mod impl_for_chip { peripheral: impl Peripheral

+ 'd, ) -> Self { crate::into_ref!(peripheral); + let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); Self { peripheral, channel0: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel1: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel2: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel3: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel4: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel5: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel6: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel7: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, + _guard: guard, } } } @@ -791,7 +813,10 @@ mod impl_for_chip { mod impl_for_chip { use core::marker::PhantomData; - use crate::peripheral::{Peripheral, PeripheralRef}; + use crate::{ + peripheral::{Peripheral, PeripheralRef}, + system::PeripheralGuard, + }; /// RMT Instance pub struct Rmt<'d, M> @@ -871,7 +896,10 @@ mod impl_for_chip { mod impl_for_chip { use core::marker::PhantomData; - use crate::peripheral::{Peripheral, PeripheralRef}; + use crate::{ + peripheral::{Peripheral, PeripheralRef}, + system::PeripheralGuard, + }; /// RMT Instance pub struct Rmt<'d, M> @@ -969,12 +997,18 @@ mod impl_for_chip { /// RMT Channel #[non_exhaustive] -#[derive(Debug)] pub struct Channel where M: crate::Mode, { phantom: PhantomData, + _guard: PeripheralGuard, +} + +impl core::fmt::Debug for Channel { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "Rmt Channel {}", CHANNEL) + } } /// Channel in TX mode @@ -1594,8 +1628,10 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { + let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); Self { phantom: core::marker::PhantomData, + _guard: guard, } } @@ -1755,8 +1791,10 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { + let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); Self { phantom: core::marker::PhantomData, + _guard: guard, } } diff --git a/esp-hal/src/rsa/mod.rs b/esp-hal/src/rsa/mod.rs index cde24f4e88c..77211cedfd8 100644 --- a/esp-hal/src/rsa/mod.rs +++ b/esp-hal/src/rsa/mod.rs @@ -27,7 +27,7 @@ use crate::{ interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::{Interrupt, RSA}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, + system::{Peripheral as PeripheralEnable, PeripheralGuard}, Async, Blocking, Cpu, @@ -48,6 +48,7 @@ pub use rsa_spec_impl::operand_sizes; pub struct Rsa<'d, DM: crate::Mode> { rsa: PeripheralRef<'d, RSA>, phantom: PhantomData, + _guard: PeripheralGuard, } impl<'d> Rsa<'d, Blocking> { @@ -64,6 +65,7 @@ impl<'d> Rsa<'d, Blocking> { Rsa { rsa: self.rsa, phantom: PhantomData, + _guard: self._guard, } } } @@ -87,6 +89,7 @@ impl<'d> Rsa<'d, Async> { Rsa { rsa: self.rsa, phantom: PhantomData, + _guard: self._guard, } } } @@ -95,12 +98,12 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { fn new_internal(rsa: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rsa); - PeripheralClockControl::reset(PeripheralEnable::Rsa); - PeripheralClockControl::enable(PeripheralEnable::Rsa); + let guard = PeripheralGuard::new(PeripheralEnable::Rsa); Self { rsa, phantom: PhantomData, + _guard: guard, } } diff --git a/esp-hal/src/sha.rs b/esp-hal/src/sha.rs index 48e85227628..e5b333070f9 100644 --- a/esp-hal/src/sha.rs +++ b/esp-hal/src/sha.rs @@ -81,8 +81,9 @@ impl<'d> Sha<'d> { pub fn new(sha: impl Peripheral

+ 'd) -> Self { crate::into_ref!(sha); - PeripheralClockControl::reset(crate::system::Peripheral::Sha); - PeripheralClockControl::enable(crate::system::Peripheral::Sha); + if PeripheralClockControl::enable(crate::system::Peripheral::Sha, true) { + PeripheralClockControl::reset(crate::system::Peripheral::Sha); + } Self { sha } } @@ -102,6 +103,12 @@ impl<'d> Sha<'d> { impl crate::private::Sealed for Sha<'_> {} +impl Drop for Sha<'_> { + fn drop(&mut self) { + PeripheralClockControl::enable(crate::system::Peripheral::Sha, false); + } +} + #[cfg(not(esp32))] impl crate::InterruptConfigurable for Sha<'_> { fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) { diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 2bc93c5d61c..b850dabe6c6 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -85,7 +85,7 @@ use crate::{ peripherals::spi2::RegisterBlock, private, spi::AnySpi, - system::PeripheralClockControl, + system::PeripheralGuard, Async, Blocking, Mode, @@ -462,6 +462,7 @@ pub enum ConfigError {} pub struct Spi<'d, M, T = AnySpi> { spi: PeripheralRef<'d, T>, _mode: PhantomData, + guard: PeripheralGuard, } impl<'d, M, T> Spi<'d, M, T> @@ -543,6 +544,7 @@ impl<'d> Spi<'d, Blocking> { Spi { spi: self.spi, _mode: PhantomData, + guard: self.guard, } } } @@ -553,6 +555,7 @@ impl<'d> Spi<'d, Async> { Spi { spi: self.spi, _mode: PhantomData, + guard: self.guard, } } } @@ -573,14 +576,14 @@ where ) -> Spi<'d, M, T> { crate::into_ref!(spi); + let guard = PeripheralGuard::new(spi.info().peripheral); + let mut this = Spi { spi, _mode: PhantomData, + guard, }; - PeripheralClockControl::enable(this.driver().peripheral); - PeripheralClockControl::reset(this.driver().peripheral); - this.driver().init(); unwrap!(this.apply_config(&config)); // FIXME: update based on the resolution of https://github.com/esp-rs/esp-hal/issues/2416 @@ -885,6 +888,7 @@ mod dma { rx_transfer_in_progress: bool, #[cfg(all(esp32, spi_address_workaround))] address_buffer: DmaTxBuf, + guard: PeripheralGuard, } impl crate::private::Sealed for SpiDma<'_, M, T> @@ -907,6 +911,7 @@ mod dma { rx_transfer_in_progress: self.rx_transfer_in_progress, #[cfg(all(esp32, spi_address_workaround))] address_buffer: self.address_buffer, + guard: self.guard, } } } @@ -924,6 +929,7 @@ mod dma { rx_transfer_in_progress: self.rx_transfer_in_progress, #[cfg(all(esp32, spi_address_workaround))] address_buffer: self.address_buffer, + guard: self.guard, } } } @@ -1015,6 +1021,8 @@ mod dma { )) }; + let guard = PeripheralGuard::new(spi.info().peripheral); + Self { spi, channel: channel.degrade(), @@ -1022,6 +1030,7 @@ mod dma { address_buffer, tx_transfer_in_progress: false, rx_transfer_in_progress: false, + guard, } } diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs index 7e00288f48f..576f8cd95d0 100644 --- a/esp-hal/src/spi/slave.rs +++ b/esp-hal/src/spi/slave.rs @@ -88,7 +88,7 @@ use crate::{ peripherals::spi2::RegisterBlock, private, spi::AnySpi, - system::PeripheralClockControl, + system::PeripheralGuard, Blocking, }; @@ -102,6 +102,7 @@ pub struct Spi<'d, M, T = AnySpi> { #[allow(dead_code)] data_mode: SpiMode, _mode: PhantomData, + _guard: PeripheralGuard, } impl<'d> Spi<'d, Blocking> { @@ -119,15 +120,15 @@ where pub fn new_typed(spi: impl Peripheral

+ 'd, mode: SpiMode) -> Spi<'d, M, T> { crate::into_ref!(spi); + let guard = PeripheralGuard::new(spi.info().peripheral); + let this = Spi { spi, data_mode: mode, _mode: PhantomData, + _guard: guard, }; - PeripheralClockControl::reset(this.spi.info().peripheral); - PeripheralClockControl::enable(this.spi.info().peripheral); - this.spi.info().init(); this.spi.info().set_data_mode(mode, false); @@ -226,6 +227,7 @@ pub mod dma { pub(crate) channel: Channel<'d, M, T::Dma>, rx_chain: DescriptorChain, tx_chain: DescriptorChain, + _guard: PeripheralGuard, } impl core::fmt::Debug for SpiDma<'_, DmaMode, T> @@ -304,11 +306,14 @@ pub mod dma { CH: DmaChannelConvert, { channel.runtime_ensure_compatible(&spi); + let guard = PeripheralGuard::new(spi.info().peripheral); + Self { spi, channel: channel.degrade(), rx_chain: DescriptorChain::new(rx_descriptors), tx_chain: DescriptorChain::new(tx_descriptors), + _guard: guard, } } diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 0406d89d0f4..c197392606a 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -5,8 +5,22 @@ //! This `system` module defines the available radio peripherals and provides an //! interface to control and configure radio clocks. +use core::sync::atomic::Ordering; + +use portable_atomic::AtomicUsize; +use strum::{EnumCount, EnumIter, IntoEnumIterator}; + use crate::peripherals::SYSTEM; +pub(crate) const KEEP_ENABLED: &[Peripheral] = &[ + Peripheral::Uart0, + #[cfg(usb_device)] + Peripheral::UsbDevice, + #[cfg(systimer)] + Peripheral::Systimer, + Peripheral::Timg0, +]; + /// Peripherals which can be enabled via `PeripheralClockControl`. /// /// This enum represents various hardware peripherals that can be enabled @@ -15,7 +29,8 @@ use crate::peripherals::SYSTEM; // FIXME: This enum needs to be public because it's exposed via a bunch of traits, but it's not // useful to users. #[doc(hidden)] -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, EnumCount, EnumIter)] +#[repr(u8)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Peripheral { /// SPI2 peripheral. @@ -78,9 +93,6 @@ pub enum Peripheral { /// Timer Group 1 peripheral. #[cfg(timg1)] Timg1, - /// Low-power watchdog timer (WDT) peripheral. - #[cfg(lp_wdt)] - Wdt, /// SHA peripheral (Secure Hash Algorithm). #[cfg(sha)] Sha, @@ -122,234 +134,247 @@ pub enum Peripheral { Systimer, } +static PERIPHERAL_REF_COUNT: [AtomicUsize; Peripheral::COUNT] = + [const { AtomicUsize::new(0) }; Peripheral::COUNT]; + +/// Disable all peripherals. +/// +/// Peripherals listed in [KEEP_ENABLED] are NOT disabled. +pub(crate) fn disable_peripherals() { + for p in Peripheral::iter() { + if KEEP_ENABLED.contains(&p) { + continue; + } + PeripheralClockControl::enable_forced(p, false, true); + } +} + +pub(crate) struct PeripheralGuard { + peripheral: Peripheral, +} + +impl PeripheralGuard { + pub(crate) fn new(p: Peripheral) -> Self { + if !KEEP_ENABLED.contains(&p) { + if PeripheralClockControl::enable(p, true) { + PeripheralClockControl::reset(p); + } + } + + Self { peripheral: p } + } +} + +impl Drop for PeripheralGuard { + fn drop(&mut self) { + if !KEEP_ENABLED.contains(&self.peripheral) { + PeripheralClockControl::enable(self.peripheral, false); + } + } +} + /// Controls the enablement of peripheral clocks. pub(crate) struct PeripheralClockControl; #[cfg(not(any(esp32c6, esp32h2)))] impl PeripheralClockControl { - /// Enables and resets the given peripheral - pub(crate) fn enable(peripheral: Peripheral) { - let system = unsafe { &*SYSTEM::PTR }; - - #[cfg(esp32)] - let (perip_clk_en0, perip_rst_en0, peri_clk_en, peri_rst_en) = { - ( - &system.perip_clk_en(), - &system.perip_rst_en(), - &system.peri_clk_en(), - &system.peri_rst_en(), - ) - }; - #[cfg(not(esp32))] - let (perip_clk_en0, perip_rst_en0) = { (&system.perip_clk_en0(), &system.perip_rst_en0()) }; - - #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] - let (perip_clk_en1, perip_rst_en1) = { (&system.perip_clk_en1(), &system.perip_rst_en1()) }; - - 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()); - } - #[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()); - } - #[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()); + pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool { + debug!("Enable {:?} {} {}", peripheral, enable, force); + critical_section::with(|_cs| { + if !force { + if enable { + let prev = + PERIPHERAL_REF_COUNT[peripheral as usize].fetch_add(1, Ordering::Relaxed); + if prev > 0 { + return false; + } + } else { + let prev = + PERIPHERAL_REF_COUNT[peripheral as usize].fetch_sub(1, Ordering::Relaxed); + if prev > 1 { + return false; + } + }; } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); + + if !enable { + Self::reset(peripheral); } + + let system = unsafe { &*SYSTEM::PTR }; + #[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)) }); - } - #[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()); - } - #[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()); + let (perip_clk_en0, peri_clk_en) = { (&system.perip_clk_en(), &system.peri_clk_en()) }; + #[cfg(not(esp32))] + let perip_clk_en0 = &system.perip_clk_en0(); - #[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()); - } - #[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()); + #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] + let perip_clk_en1 = &system.perip_clk_en1(); + match peripheral { + #[cfg(spi2)] + Peripheral::Spi2 => { + perip_clk_en0.modify(|_, w| w.spi2_clk_en().bit(enable)); + } + #[cfg(spi3)] + Peripheral::Spi3 => { + perip_clk_en0.modify(|_, w| w.spi3_clk_en().bit(enable)); + } + #[cfg(all(i2c0, esp32))] + Peripheral::I2cExt0 => { + perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().bit(enable)); + } + #[cfg(all(i2c0, not(esp32)))] + Peripheral::I2cExt0 => { + perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().bit(enable)); + } + #[cfg(i2c1)] + Peripheral::I2cExt1 => { + perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().bit(enable)); + } + #[cfg(rmt)] + Peripheral::Rmt => { + perip_clk_en0.modify(|_, w| w.rmt_clk_en().bit(enable)); + } + #[cfg(ledc)] + Peripheral::Ledc => { + perip_clk_en0.modify(|_, w| w.ledc_clk_en().bit(enable)); + } + #[cfg(mcpwm0)] + Peripheral::Mcpwm0 => { + perip_clk_en0.modify(|_, w| w.pwm0_clk_en().bit(enable)); + } + #[cfg(mcpwm1)] + Peripheral::Mcpwm1 => { + perip_clk_en0.modify(|_, w| w.pwm1_clk_en().bit(enable)); + } + #[cfg(pcnt)] + Peripheral::Pcnt => { + perip_clk_en0.modify(|_, w| w.pcnt_clk_en().bit(enable)); + } + #[cfg(apb_saradc)] + Peripheral::ApbSarAdc => { + perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().bit(enable)); + } + #[cfg(gdma)] + Peripheral::Gdma => { + perip_clk_en1.modify(|_, w| w.dma_clk_en().bit(enable)); + } + #[cfg(esp32)] + Peripheral::Dma => { + perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().bit(enable)); + } + #[cfg(esp32s2)] + Peripheral::Dma => { + perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().bit(enable)); + } + #[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().bit(enable)); + } + #[cfg(any(esp32s3, esp32, esp32s2))] + Peripheral::I2s0 => { + perip_clk_en0.modify(|_, w| w.i2s0_clk_en().bit(enable)); + } + #[cfg(any(esp32s3, esp32))] + Peripheral::I2s1 => { + perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable)); + } + #[cfg(usb0)] + Peripheral::Usb => { + perip_clk_en0.modify(|_, w| w.usb_clk_en().bit(enable)); + } + #[cfg(twai0)] + Peripheral::Twai0 => { + perip_clk_en0.modify(|_, w| w.twai_clk_en().bit(enable)); + } + #[cfg(esp32)] + Peripheral::Aes => { + peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | enable as u32) }); + } #[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()); - } - #[cfg(sha)] - Peripheral::Sha => { - #[cfg(not(esp32))] - perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().set_bit()); - #[cfg(not(esp32))] - 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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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)) }); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); + Peripheral::Aes => { + perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().bit(enable)); + } + #[cfg(timg0)] + Peripheral::Timg0 => { + #[cfg(any(esp32c3, esp32s2, esp32s3))] + perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.timergroup_clk_en().bit(enable)); + } + #[cfg(timg1)] + Peripheral::Timg1 => { + #[cfg(any(esp32c3, esp32s2, esp32s3))] + perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().bit(enable)); + } + #[cfg(sha)] + Peripheral::Sha => { + #[cfg(not(esp32))] + perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().bit(enable)); + } + #[cfg(esp32c3)] + Peripheral::UsbDevice => { + perip_clk_en0.modify(|_, w| w.usb_device_clk_en().bit(enable)); + } + #[cfg(esp32s3)] + Peripheral::UsbDevice => { + perip_clk_en1.modify(|_, w| w.usb_device_clk_en().bit(enable)); + } + #[cfg(uart0)] + Peripheral::Uart0 => { + perip_clk_en0.modify(|_, w| w.uart_clk_en().bit(enable)); + } + #[cfg(uart1)] + Peripheral::Uart1 => { + perip_clk_en0.modify(|_, w| w.uart1_clk_en().bit(enable)); + } + #[cfg(all(uart2, esp32s3))] + Peripheral::Uart2 => { + perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit()); + } + #[cfg(all(uart2, esp32))] + Peripheral::Uart2 => { + perip_clk_en0.modify(|_, w| w.uart2_clk_en().bit(enable)); + } + #[cfg(all(rsa, esp32))] + Peripheral::Rsa => { + peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | (enable as u32) << 2) }); + } + #[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))] + Peripheral::Rsa => { + perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().bit(enable)); + system + .rsa_pd_ctrl() + .modify(|_, w| w.rsa_mem_pd().bit(!enable)); + } + #[cfg(hmac)] + Peripheral::Hmac => { + perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().bit(enable)); + } + #[cfg(ecc)] + Peripheral::Ecc => { + perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().bit(enable)); + } + #[cfg(lcd_cam)] + Peripheral::LcdCam => { + perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().bit(enable)); + } + #[cfg(systimer)] + Peripheral::Systimer => { + perip_clk_en0.modify(|_, w| w.systimer_clk_en().bit(enable)); + } } - }); + + true + }) } /// Resets the given peripheral pub(crate) fn reset(peripheral: Peripheral) { + debug!("Reset {:?}", peripheral); let system = unsafe { &*SYSTEM::PTR }; #[cfg(esp32)] @@ -560,232 +585,198 @@ impl PeripheralClockControl { #[cfg(any(esp32c6, esp32h2))] impl PeripheralClockControl { - /// Enables and resets the given peripheral - pub(crate) fn enable(peripheral: Peripheral) { - let system = unsafe { &*SYSTEM::PTR }; + pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool { + debug!("Enable {:?} {} {}", peripheral, enable, force); + critical_section::with(|_| { + if !force { + if enable { + let prev = + PERIPHERAL_REF_COUNT[peripheral as usize].fetch_add(1, Ordering::Relaxed); + if prev > 0 { + return false; + } + } else { + let prev = + PERIPHERAL_REF_COUNT[peripheral as usize].fetch_sub(1, Ordering::Relaxed); + if prev > 1 { + return false; + } + }; + } - 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()); + if !enable { + Self::reset(peripheral); } - #[cfg(i2c0)] - Peripheral::I2cExt0 => { - #[cfg(any(esp32c6, esp32h2))] - { - system.i2c0_conf().modify(|_, w| w.i2c0_clk_en().set_bit()); + + let system = unsafe { &*SYSTEM::PTR }; + + match peripheral { + #[cfg(spi2)] + Peripheral::Spi2 => { + system + .spi2_conf() + .modify(|_, w| w.spi2_clk_en().bit(enable)); + } + #[cfg(i2c0)] + Peripheral::I2cExt0 => { system .i2c0_conf() - .modify(|_, w| w.i2c0_rst_en().clear_bit()); + .modify(|_, w| w.i2c0_clk_en().bit(enable)); } - } - #[cfg(i2c1)] - Peripheral::I2cExt1 => { - #[cfg(esp32h2)] - { - system.i2c1_conf().modify(|_, w| w.i2c1_clk_en().set_bit()); + #[cfg(i2c1)] + Peripheral::I2cExt1 => { system .i2c1_conf() - .modify(|_, w| w.i2c1_rst_en().clear_bit()); + .modify(|_, w| w.i2c1_clk_en().bit(enable)); } - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); + #[cfg(rmt)] + Peripheral::Rmt => { + system.rmt_conf().modify(|_, w| w.rmt_clk_en().bit(enable)); + } + #[cfg(ledc)] + Peripheral::Ledc => { + system + .ledc_conf() + .modify(|_, w| w.ledc_clk_en().bit(enable)); + } + #[cfg(mcpwm0)] + Peripheral::Mcpwm0 => { + system.pwm_conf().modify(|_, w| w.pwm_clk_en().bit(enable)); + } + #[cfg(mcpwm1)] + Peripheral::Mcpwm1 => { + system.pwm_conf.modify(|_, w| w.pwm_clk_en().bit(enable)); + } + #[cfg(apb_saradc)] + Peripheral::ApbSarAdc => { + system + .saradc_conf() + .modify(|_, w| w.saradc_reg_clk_en().bit(enable)); + } + #[cfg(gdma)] + Peripheral::Gdma => { + system + .gdma_conf() + .modify(|_, w| w.gdma_clk_en().bit(enable)); + } + #[cfg(i2s0)] + Peripheral::I2s0 => { + system.i2s_conf().modify(|_, w| w.i2s_clk_en().bit(enable)); + } + #[cfg(twai0)] + Peripheral::Twai0 => { + system + .twai0_conf() + .modify(|_, w| w.twai0_clk_en().bit(enable)); - // use Xtal clk-src - system.twai0_func_clk_conf().modify(|_, w| { - w.twai0_func_clk_en() - .set_bit() - .twai0_func_clk_sel() - .variant(false) - }); - } - #[cfg(twai1)] - Peripheral::Twai1 => { - system - .twai1_conf() - .modify(|_, w| w.twai1_clk_en().set_bit()); - 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()); - } - #[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()); - } - #[cfg(timg0)] - Peripheral::Timg0 => { - system - .timergroup0_timer_clk_conf() - .modify(|_, w| w.tg0_timer_clk_en().set_bit()); - } - #[cfg(timg1)] - Peripheral::Timg1 => { - system - .timergroup1_timer_clk_conf() - .modify(|_, w| w.tg1_timer_clk_en().set_bit()); - } - #[cfg(lp_wdt)] - Peripheral::Wdt => { - system - .timergroup0_wdt_clk_conf() - .modify(|_, w| w.tg0_wdt_clk_en().set_bit()); - system - .timergroup1_timer_clk_conf() - .modify(|_, w| w.tg1_timer_clk_en().set_bit()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); - } - #[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()); + if enable { + // use Xtal clk-src + system.twai0_func_clk_conf().modify(|_, w| { + w.twai0_func_clk_en() + .set_bit() + .twai0_func_clk_sel() + .variant(false) + }); + } + } + #[cfg(twai1)] + Peripheral::Twai1 => { + system + .twai1_conf() + .modify(|_, w| w.twai1_clk_en().bit(enable)); + } + #[cfg(aes)] + Peripheral::Aes => { + system.aes_conf().modify(|_, w| w.aes_clk_en().bit(enable)); + } + #[cfg(pcnt)] + Peripheral::Pcnt => { + system + .pcnt_conf() + .modify(|_, w| w.pcnt_clk_en().bit(enable)); + } + #[cfg(timg0)] + Peripheral::Timg0 => { + system + .timergroup0_timer_clk_conf() + .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().bit(enable)); + } + #[cfg(sha)] + Peripheral::Sha => { + system.sha_conf().modify(|_, w| w.sha_clk_en().bit(enable)); + } + #[cfg(usb_device)] + Peripheral::UsbDevice => { + system + .usb_device_conf() + .modify(|_, w| w.usb_device_clk_en().bit(enable)); + } + #[cfg(uart0)] + Peripheral::Uart0 => { + system + .uart0_conf() + .modify(|_, w| w.uart0_clk_en().bit(enable)); + } + #[cfg(uart1)] + Peripheral::Uart1 => { + system + .uart1_conf() + .modify(|_, w| w.uart1_clk_en().bit(enable)); + } + #[cfg(rsa)] + Peripheral::Rsa => { + system.rsa_conf().modify(|_, w| w.rsa_clk_en().bit(enable)); + 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().bit(enable)); + } + #[cfg(hmac)] + Peripheral::Hmac => { + system + .hmac_conf() + .modify(|_, w| w.hmac_clk_en().bit(enable)); + } + #[cfg(ecc)] + Peripheral::Ecc => { + system.ecc_conf().modify(|_, w| w.ecc_clk_en().bit(enable)); + } + #[cfg(soc_etm)] + Peripheral::Etm => { + system.etm_conf().modify(|_, w| w.etm_clk_en().bit(enable)); + } + #[cfg(trace0)] + Peripheral::Trace0 => { + system + .trace_conf() + .modify(|_, w| w.trace_clk_en().bit(enable)); + } + #[cfg(systimer)] + Peripheral::Systimer => { + system + .systimer_conf() + .modify(|_, w| w.systimer_clk_en().bit(enable)); + } } - } + true + }) } /// Resets the given peripheral pub(crate) fn reset(peripheral: Peripheral) { + debug!("Reset {:?}", peripheral); + let system = unsafe { &*SYSTEM::PTR }; match peripheral { @@ -897,10 +888,6 @@ impl PeripheralClockControl { Peripheral::Timg1 => { // no reset? } - #[cfg(lp_wdt)] - Peripheral::Wdt => { - // no reset? - } #[cfg(sha)] Peripheral::Sha => { system.sha_conf().modify(|_, w| w.sha_rst_en().set_bit()); @@ -986,6 +973,22 @@ impl PeripheralClockControl { } } + +impl PeripheralClockControl { + /// Enables/disables the given peripheral. + /// + /// This keeps track of enabling/disabling a peripheral - i.e. a peripheral + /// is only enabled with the first call attempt to enable it. It only + /// gets disabled when the number of enable/disable attempts is balanced. + /// + /// Returns `true` if it actually enabled/disabled the peripheral. + /// + /// Before disabling a peripheral it will also get reset + pub(crate) fn enable(peripheral: Peripheral, enable: bool) -> bool { + Self::enable_forced(peripheral, enable, false) + } +} + /// Enumeration of the available radio peripherals for this chip. #[cfg(any(bt, ieee802154, wifi))] pub enum RadioPeripherals { diff --git a/esp-hal/src/timer/systimer.rs b/esp-hal/src/timer/systimer.rs index d640502041e..f54aeb44eab 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 d51eec9e25e..77924fb87bb 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() { - PeripheralClockControl::enable(crate::system::Peripheral::Timg0) + PeripheralClockControl::enable(crate::system::Peripheral::Timg0, true); } fn reset_peripheral() { @@ -215,7 +215,7 @@ impl TimerGroupInstance for crate::peripherals::TIMG1 { } fn enable_peripheral() { - PeripheralClockControl::enable(crate::system::Peripheral::Timg1) + PeripheralClockControl::enable(crate::system::Peripheral::Timg1, true); } fn reset_peripheral() { @@ -929,9 +929,6 @@ where { /// Construct a new instance of [`Wdt`] pub fn new() -> Self { - #[cfg(lp_wdt)] - PeripheralClockControl::enable(crate::system::Peripheral::Wdt); - TG::configure_wdt_src_clk(); Self { diff --git a/esp-hal/src/trace.rs b/esp-hal/src/trace.rs index a0c735b1e4e..5bf11b5ad87 100644 --- a/esp-hal/src/trace.rs +++ b/esp-hal/src/trace.rs @@ -56,7 +56,10 @@ pub struct TraceResult { } /// TRACE Encoder Instance -pub struct Trace<'d, T> { +pub struct Trace<'d, T> +where + T: Instance, +{ peripheral: PeripheralRef<'d, T>, buffer: Option<&'d mut [u8]>, } @@ -69,8 +72,9 @@ where pub fn new(peripheral: impl Peripheral

+ 'd) -> Self { crate::into_ref!(peripheral); - PeripheralClockControl::reset(crate::system::Peripheral::Trace0); - PeripheralClockControl::enable(crate::system::Peripheral::Trace0); + if PeripheralClockControl::enable(peripheral.peripheral(), true) { + PeripheralClockControl::reset(peripheral.peripheral()); + } Self { peripheral, @@ -203,14 +207,30 @@ where } } +impl Drop for Trace<'_, T> +where + T: Instance, +{ + fn drop(&mut self) { + PeripheralClockControl::enable(self.peripheral.peripheral(), false); + } +} + /// Trace peripheral instance pub trait Instance: crate::private::Sealed { /// Get a reference to the peripheral's underlying register block fn register_block(&self) -> &RegisterBlock; + + /// Peripheral + fn peripheral(&self) -> crate::system::Peripheral; } impl Instance for crate::peripherals::TRACE0 { fn register_block(&self) -> &RegisterBlock { self } + + fn peripheral(&self) -> crate::system::Peripheral { + crate::system::Peripheral::Trace0 + } } diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index cfbb1f7ead0..32a8eccd378 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -134,7 +134,7 @@ use crate::{ interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::twai0::RegisterBlock, - system::PeripheralClockControl, + system::PeripheralGuard, twai::filter::SingleStandardFilter, Async, Blocking, @@ -751,6 +751,7 @@ pub struct TwaiConfiguration<'d, DM: crate::Mode, T = AnyTwai> { filter: Option<(FilterType, [u8; 8])>, phantom: PhantomData, mode: TwaiMode, + _guard: PeripheralGuard, } impl<'d, DM, T> TwaiConfiguration<'d, DM, T> @@ -769,15 +770,14 @@ where crate::into_ref!(twai); crate::into_mapped_ref!(tx_pin, rx_pin); - // Enable the peripheral clock for the TWAI peripheral. - PeripheralClockControl::enable(twai.peripheral()); - PeripheralClockControl::reset(twai.peripheral()); + let guard = PeripheralGuard::new(twai.peripheral()); let mut this = TwaiConfiguration { twai, filter: None, // We'll immediately call `set_filter` phantom: PhantomData, mode, + _guard: guard, }; // Accept all messages by default. @@ -1035,10 +1035,12 @@ where rx: TwaiRx { twai: unsafe { self.twai.clone_unchecked() }, phantom: PhantomData, + _guard: PeripheralGuard::new(self.twai.peripheral()), }, tx: TwaiTx { twai: unsafe { self.twai.clone_unchecked() }, phantom: PhantomData, + _guard: PeripheralGuard::new(self.twai.peripheral()), }, twai: unsafe { self.twai.clone_unchecked() }, phantom: PhantomData, @@ -1116,6 +1118,7 @@ where filter: self.filter, phantom: PhantomData, mode: self.mode, + _guard: self._guard, } } } @@ -1136,6 +1139,7 @@ where filter: self.filter, phantom: PhantomData, mode: self.mode, + _guard: self._guard, } } } @@ -1191,11 +1195,13 @@ where let mode = self.mode(); + let guard = PeripheralGuard::new(self.twai.peripheral()); TwaiConfiguration { twai: self.twai, filter: None, // filter already applied, no need to restore it phantom: PhantomData, mode, + _guard: guard, } } @@ -1277,6 +1283,7 @@ where pub struct TwaiTx<'d, DM: crate::Mode, T = AnyTwai> { twai: PeripheralRef<'d, T>, phantom: PhantomData, + _guard: PeripheralGuard, } impl TwaiTx<'_, DM, T> @@ -1319,6 +1326,7 @@ where pub struct TwaiRx<'d, DM: crate::Mode, T = AnyTwai> { twai: PeripheralRef<'d, T>, phantom: PhantomData, + _guard: PeripheralGuard, } impl TwaiRx<'_, DM, T> diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index b67f6b97427..82447b33c1c 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -132,7 +132,7 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::{uart0::RegisterBlock, Interrupt}, private::Internal, - system::PeripheralClockControl, + system::{PeripheralClockControl, PeripheralGuard}, Async, Blocking, InterruptConfigurable, @@ -462,14 +462,19 @@ where } fn init(self, config: Config) -> Result, Error> { + let rx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral); + let tx_guard = PeripheralGuard::new(self.uart.parts().0.peripheral); + let mut serial = Uart { rx: UartRx { uart: unsafe { self.uart.clone_unchecked() }, phantom: PhantomData, + guard: rx_guard, }, tx: UartTx { uart: self.uart, phantom: PhantomData, + guard: tx_guard, }, }; serial.init(config)?; @@ -488,12 +493,14 @@ pub struct Uart<'d, M, T = AnyUart> { pub struct UartTx<'d, M, T = AnyUart> { uart: PeripheralRef<'d, T>, phantom: PhantomData, + guard: PeripheralGuard, } /// UART (Receive) pub struct UartRx<'d, M, T = AnyUart> { uart: PeripheralRef<'d, T>, phantom: PhantomData, + guard: PeripheralGuard, } impl SetConfig for Uart<'_, M, T> @@ -698,6 +705,7 @@ where UartTx { uart: self.uart, phantom: PhantomData, + guard: self.guard, } } } @@ -719,6 +727,7 @@ where UartTx { uart: self.uart, phantom: PhantomData, + guard: self.guard, } } } @@ -951,6 +960,7 @@ where UartRx { uart: self.uart, phantom: PhantomData, + guard: self.guard, } } } @@ -972,6 +982,7 @@ where UartRx { uart: self.uart, phantom: PhantomData, + guard: self.guard, } } } @@ -1197,8 +1208,8 @@ where } }; - PeripheralClockControl::enable(self.tx.uart.info().peripheral); self.uart_peripheral_reset(); + self.rx.disable_rx_interrupts(); self.tx.disable_tx_interrupts(); @@ -1242,7 +1253,7 @@ where } fn rst_core(_reg_block: &RegisterBlock, _enable: bool) { - #[cfg(not(any(esp32, esp32s2)))] + #[cfg(not(any(esp32, esp32s2, esp32c6, esp32h2)))] _reg_block .clk_conf() .modify(|_, w| w.rst_core().bit(_enable)); diff --git a/esp-hal/src/usb_serial_jtag.rs b/esp-hal/src/usb_serial_jtag.rs index c94c2be6c93..c76d714a828 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(); diff --git a/examples/src/bin/spi_loopback.rs b/examples/src/bin/spi_loopback.rs index 22e92a29ca5..67ff6a9a7a1 100644 --- a/examples/src/bin/spi_loopback.rs +++ b/examples/src/bin/spi_loopback.rs @@ -46,8 +46,8 @@ fn main() -> ! { }, ) .with_sck(sclk) - .with_mosi(miso_mosi) - .with_miso(miso) + .with_miso(miso) // order matters + .with_mosi(miso_mosi) // order matters .with_cs(cs); let delay = Delay::new(); diff --git a/hil-test/tests/spi_half_duplex_write.rs b/hil-test/tests/spi_half_duplex_write.rs index 1db9ad2cb13..dcefb5b5321 100644 --- a/hil-test/tests/spi_half_duplex_write.rs +++ b/hil-test/tests/spi_half_duplex_write.rs @@ -112,7 +112,8 @@ mod tests { ) .map_err(|e| e.0) .unwrap(); - transfer.wait(); + // dropping SPI would make us see an additional edge - so let's keep SPI alive + let (_spi,_) = transfer.wait(); assert_eq!(unit.value(), (6 * DMA_BUFFER_SIZE) as _); } From 894cf938973f1576f153ebd569f42c3b87d9cd0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 12:32:18 +0100 Subject: [PATCH 02/14] Fixes --- esp-hal/src/rmt.rs | 24 ++++++++++++++++++++++++ esp-hal/src/system.rs | 11 ++++------- hil-test/tests/spi_half_duplex_write.rs | 2 +- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 68de4288a18..78777be15e8 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -712,6 +712,7 @@ mod impl_for_chip { /// RMT Channel 7. pub channel7: ChannelCreator, phantom: PhantomData, + _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -770,6 +771,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, + _guard: PeripheralGuard, } impl_tx_channel_creator!(0); @@ -833,6 +835,7 @@ mod impl_for_chip { /// RMT Channel 3. pub channel3: ChannelCreator, phantom: PhantomData, + _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -848,17 +851,22 @@ mod impl_for_chip { peripheral, channel0: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel1: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel2: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel3: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), } } } @@ -869,6 +877,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, + _guard: PeripheralGuard, } impl_tx_channel_creator!(0); @@ -924,6 +933,7 @@ mod impl_for_chip { /// RMT Channel 7. pub channel7: ChannelCreator, phantom: PhantomData, + _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -939,29 +949,38 @@ mod impl_for_chip { peripheral, channel0: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel1: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel2: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel3: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel4: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel5: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel6: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, channel7: ChannelCreator { phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, + _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), } } } @@ -972,6 +991,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, + _guard: PeripheralGuard, } impl_tx_channel_creator!(0); @@ -1982,8 +2002,10 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { + let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); Self { phantom: core::marker::PhantomData, + _guard: guard, } } @@ -2133,8 +2155,10 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { + let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); Self { phantom: core::marker::PhantomData, + _guard: guard, } } diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index c197392606a..15e977db374 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -155,10 +155,8 @@ pub(crate) struct PeripheralGuard { impl PeripheralGuard { pub(crate) fn new(p: Peripheral) -> Self { - if !KEEP_ENABLED.contains(&p) { - if PeripheralClockControl::enable(p, true) { - PeripheralClockControl::reset(p); - } + if !KEEP_ENABLED.contains(&p) && PeripheralClockControl::enable(p, true) { + PeripheralClockControl::reset(p); } Self { peripheral: p } @@ -200,7 +198,7 @@ impl PeripheralClockControl { if !enable { Self::reset(peripheral); } - + let system = unsafe { &*SYSTEM::PTR }; #[cfg(esp32)] @@ -973,7 +971,6 @@ impl PeripheralClockControl { } } - impl PeripheralClockControl { /// Enables/disables the given peripheral. /// @@ -982,7 +979,7 @@ impl PeripheralClockControl { /// gets disabled when the number of enable/disable attempts is balanced. /// /// Returns `true` if it actually enabled/disabled the peripheral. - /// + /// /// Before disabling a peripheral it will also get reset pub(crate) fn enable(peripheral: Peripheral, enable: bool) -> bool { Self::enable_forced(peripheral, enable, false) diff --git a/hil-test/tests/spi_half_duplex_write.rs b/hil-test/tests/spi_half_duplex_write.rs index dcefb5b5321..8bd445a7717 100644 --- a/hil-test/tests/spi_half_duplex_write.rs +++ b/hil-test/tests/spi_half_duplex_write.rs @@ -113,7 +113,7 @@ mod tests { .map_err(|e| e.0) .unwrap(); // dropping SPI would make us see an additional edge - so let's keep SPI alive - let (_spi,_) = transfer.wait(); + let (_spi, _) = transfer.wait(); assert_eq!(unit.value(), (6 * DMA_BUFFER_SIZE) as _); } From f8ee3fac975f7a05fa320de4f9fae7033d230700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 12:33:43 +0100 Subject: [PATCH 03/14] CHANGELOG.md --- esp-hal/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index db169daa7d4..bf7c07aff7f 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -78,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Trying to send a single-shot RMT transmission will result in an error now, `RMT` deals with `u32` now, `PulseCode` is a convenience trait now (#2463) - Removed `get_` prefixes from functions (#2528) - The `Camera` and `I8080` drivers' constructors now only accepts blocking-mode DMA channels. (#2519) +- Many peripherals are now disabled by default and also get disabled when the driver is dropped (#2544) ### Fixed From fbbfa768f18df377eb9ba48eafb5ee201ab79c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 12:57:17 +0100 Subject: [PATCH 04/14] Fix --- esp-hal/src/trace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp-hal/src/trace.rs b/esp-hal/src/trace.rs index 5bf11b5ad87..f093b525e89 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 //! From 33be628ac2ee1cdf49e00596dc15b2573c23c352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 12:57:28 +0100 Subject: [PATCH 05/14] Address review comments --- esp-hal/src/hmac.rs | 2 +- esp-hal/src/system.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/esp-hal/src/hmac.rs b/esp-hal/src/hmac.rs index bd40a18d8df..5946220a904 100644 --- a/esp-hal/src/hmac.rs +++ b/esp-hal/src/hmac.rs @@ -349,6 +349,6 @@ impl<'d> Hmac<'d> { impl Drop for Hmac<'_> { fn drop(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Hmac, true); + PeripheralClockControl::enable(PeripheralEnable::Hmac, false); } } diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 15e977db374..d61d790b5dd 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -193,6 +193,8 @@ impl PeripheralClockControl { return false; } }; + } else if !enable { + PERIPHERAL_REF_COUNT[peripheral as usize].store(0, Ordering::Relaxed); } if !enable { @@ -600,6 +602,8 @@ impl PeripheralClockControl { return false; } }; + } else if !enable { + PERIPHERAL_REF_COUNT[peripheral as usize].store(0, Ordering::Relaxed); } if !enable { From d2f9cc1eb391a12564ca8ba7ab9572ff87d0c1b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 13:48:24 +0100 Subject: [PATCH 06/14] Have dedicated guards for CAM and LCD --- esp-hal/src/lcd_cam/cam.rs | 6 ++++++ esp-hal/src/lcd_cam/lcd/mod.rs | 4 +++- esp-hal/src/lcd_cam/mod.rs | 16 +++++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index 358643e871e..f52473f2bc0 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -82,6 +82,7 @@ use crate::{ lcd_cam::{calculate_clkm, BitOrder, ByteOrder}, peripheral::{Peripheral, PeripheralRef}, peripherals::LCD_CAM, + system::PeripheralGuard, Blocking, }; @@ -121,12 +122,14 @@ pub enum VsyncFilterThreshold { pub struct Cam<'d> { /// The LCD_CAM peripheral reference for managing the camera functionality. pub(crate) lcd_cam: PeripheralRef<'d, LCD_CAM>, + pub(super) _guard: PeripheralGuard, } /// Represents the camera interface with DMA support. pub struct Camera<'d> { lcd_cam: PeripheralRef<'d, LCD_CAM>, rx_channel: ChannelRx<'d, Blocking, ::Dma>, + _guard: PeripheralGuard, } impl<'d> Camera<'d> { @@ -141,6 +144,8 @@ impl<'d> Camera<'d> { CH: DmaChannelConvert<::Dma>, P: RxPins, { + let guard = PeripheralGuard::new(crate::system::Peripheral::LcdCam); + let lcd_cam = cam.lcd_cam; let clocks = Clocks::get(); @@ -187,6 +192,7 @@ impl<'d> Camera<'d> { Self { lcd_cam, rx_channel: channel.degrade(), + _guard: guard, } } } diff --git a/esp-hal/src/lcd_cam/lcd/mod.rs b/esp-hal/src/lcd_cam/lcd/mod.rs index 7727400fa15..f780f855385 100644 --- a/esp-hal/src/lcd_cam/lcd/mod.rs +++ b/esp-hal/src/lcd_cam/lcd/mod.rs @@ -10,7 +10,7 @@ //! ## Implementation State //! - RGB is not supported yet -use crate::{peripheral::PeripheralRef, peripherals::LCD_CAM}; +use crate::{peripheral::PeripheralRef, peripherals::LCD_CAM, system::PeripheralGuard}; pub mod dpi; pub mod i8080; @@ -22,6 +22,8 @@ pub struct Lcd<'d, DM: crate::Mode> { /// A marker for the mode of operation (blocking or asynchronous). pub(crate) _mode: core::marker::PhantomData, + + pub(super) _guard: PeripheralGuard, } #[derive(Debug, Clone, Copy, PartialEq, Default)] diff --git a/esp-hal/src/lcd_cam/mod.rs b/esp-hal/src/lcd_cam/mod.rs index 5a993833c62..6593783c42b 100644 --- a/esp-hal/src/lcd_cam/mod.rs +++ b/esp-hal/src/lcd_cam/mod.rs @@ -31,8 +31,6 @@ pub struct LcdCam<'d, DM: crate::Mode> { pub lcd: Lcd<'d, DM>, /// The Camera interface. pub cam: Cam<'d>, - - _guard: PeripheralGuard, } impl<'d> LcdCam<'d, Blocking> { @@ -40,15 +38,19 @@ impl<'d> LcdCam<'d, Blocking> { pub fn new(lcd_cam: impl Peripheral

+ 'd) -> Self { crate::into_ref!(lcd_cam); - let guard = PeripheralGuard::new(system::Peripheral::LcdCam); + let lcd_guard = PeripheralGuard::new(system::Peripheral::LcdCam); + let cam_guard = PeripheralGuard::new(system::Peripheral::LcdCam); Self { lcd: Lcd { lcd_cam: unsafe { lcd_cam.clone_unchecked() }, _mode: PhantomData, + _guard: lcd_guard, + }, + cam: Cam { + lcd_cam, + _guard: cam_guard, }, - cam: Cam { lcd_cam }, - _guard: guard, } } @@ -59,9 +61,9 @@ impl<'d> LcdCam<'d, Blocking> { lcd: Lcd { lcd_cam: self.lcd.lcd_cam, _mode: PhantomData, + _guard: self.lcd._guard, }, cam: self.cam, - _guard: self._guard, } } } @@ -90,9 +92,9 @@ impl<'d> LcdCam<'d, Async> { lcd: Lcd { lcd_cam: self.lcd.lcd_cam, _mode: PhantomData, + _guard: self.lcd._guard, }, cam: self.cam, - _guard: self._guard, } } } From 71f819c92f9fe09bc66c1572ac0fcda4beba967f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 15:01:27 +0100 Subject: [PATCH 07/14] Re-use `Cam`'s guard --- esp-hal/src/lcd_cam/cam.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index f52473f2bc0..a91dcdc95f8 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -144,8 +144,6 @@ impl<'d> Camera<'d> { CH: DmaChannelConvert<::Dma>, P: RxPins, { - let guard = PeripheralGuard::new(crate::system::Peripheral::LcdCam); - let lcd_cam = cam.lcd_cam; let clocks = Clocks::get(); @@ -192,7 +190,7 @@ impl<'d> Camera<'d> { Self { lcd_cam, rx_channel: channel.degrade(), - _guard: guard, + _guard: cam._guard, } } } From 97d16242619a60189f7fb51212e3029a6421ab30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 15:05:04 +0100 Subject: [PATCH 08/14] De-duplicate, assert --- esp-hal/src/system.rs | 400 ++++++++++++++++++++---------------------- 1 file changed, 192 insertions(+), 208 deletions(-) diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index d61d790b5dd..94c26a4184c 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -176,31 +176,11 @@ pub(crate) struct PeripheralClockControl; #[cfg(not(any(esp32c6, esp32h2)))] impl PeripheralClockControl { - pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool { - debug!("Enable {:?} {} {}", peripheral, enable, force); - critical_section::with(|_cs| { - if !force { - if enable { - let prev = - PERIPHERAL_REF_COUNT[peripheral as usize].fetch_add(1, Ordering::Relaxed); - if prev > 0 { - return false; - } - } else { - let prev = - PERIPHERAL_REF_COUNT[peripheral as usize].fetch_sub(1, Ordering::Relaxed); - if prev > 1 { - return false; - } - }; - } else if !enable { - PERIPHERAL_REF_COUNT[peripheral as usize].store(0, Ordering::Relaxed); - } - if !enable { - Self::reset(peripheral); - } + fn enable_internal(peripheral: Peripheral, enable: bool) { + debug!("Enable {:?} {}", peripheral, enable); + critical_section::with(|_cs| { let system = unsafe { &*SYSTEM::PTR }; #[cfg(esp32)] @@ -367,8 +347,6 @@ impl PeripheralClockControl { perip_clk_en0.modify(|_, w| w.systimer_clk_en().bit(enable)); } } - - true }) } @@ -585,194 +563,169 @@ impl PeripheralClockControl { #[cfg(any(esp32c6, esp32h2))] impl PeripheralClockControl { - pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool { - debug!("Enable {:?} {} {}", peripheral, enable, force); - critical_section::with(|_| { - if !force { - if enable { - let prev = - PERIPHERAL_REF_COUNT[peripheral as usize].fetch_add(1, Ordering::Relaxed); - if prev > 0 { - return false; - } - } else { - let prev = - PERIPHERAL_REF_COUNT[peripheral as usize].fetch_sub(1, Ordering::Relaxed); - if prev > 1 { - return false; - } - }; - } else if !enable { - PERIPHERAL_REF_COUNT[peripheral as usize].store(0, Ordering::Relaxed); - } + fn enable_internal(peripheral: Peripheral, enable: bool) { + debug!("Enable {:?} {}", peripheral, enable); + let system = unsafe { &*SYSTEM::PTR }; - if !enable { - Self::reset(peripheral); + match peripheral { + #[cfg(spi2)] + Peripheral::Spi2 => { + system + .spi2_conf() + .modify(|_, w| w.spi2_clk_en().bit(enable)); } + #[cfg(i2c0)] + Peripheral::I2cExt0 => { + system + .i2c0_conf() + .modify(|_, w| w.i2c0_clk_en().bit(enable)); + } + #[cfg(i2c1)] + Peripheral::I2cExt1 => { + system + .i2c1_conf() + .modify(|_, w| w.i2c1_clk_en().bit(enable)); + } + #[cfg(rmt)] + Peripheral::Rmt => { + system.rmt_conf().modify(|_, w| w.rmt_clk_en().bit(enable)); + } + #[cfg(ledc)] + Peripheral::Ledc => { + system + .ledc_conf() + .modify(|_, w| w.ledc_clk_en().bit(enable)); + } + #[cfg(mcpwm0)] + Peripheral::Mcpwm0 => { + system.pwm_conf().modify(|_, w| w.pwm_clk_en().bit(enable)); + } + #[cfg(mcpwm1)] + Peripheral::Mcpwm1 => { + system.pwm_conf.modify(|_, w| w.pwm_clk_en().bit(enable)); + } + #[cfg(apb_saradc)] + Peripheral::ApbSarAdc => { + system + .saradc_conf() + .modify(|_, w| w.saradc_reg_clk_en().bit(enable)); + } + #[cfg(gdma)] + Peripheral::Gdma => { + system + .gdma_conf() + .modify(|_, w| w.gdma_clk_en().bit(enable)); + } + #[cfg(i2s0)] + Peripheral::I2s0 => { + system.i2s_conf().modify(|_, w| w.i2s_clk_en().bit(enable)); + } + #[cfg(twai0)] + Peripheral::Twai0 => { + system + .twai0_conf() + .modify(|_, w| w.twai0_clk_en().bit(enable)); - let system = unsafe { &*SYSTEM::PTR }; - - match peripheral { - #[cfg(spi2)] - Peripheral::Spi2 => { - system - .spi2_conf() - .modify(|_, w| w.spi2_clk_en().bit(enable)); - } - #[cfg(i2c0)] - Peripheral::I2cExt0 => { - system - .i2c0_conf() - .modify(|_, w| w.i2c0_clk_en().bit(enable)); - } - #[cfg(i2c1)] - Peripheral::I2cExt1 => { - system - .i2c1_conf() - .modify(|_, w| w.i2c1_clk_en().bit(enable)); - } - #[cfg(rmt)] - Peripheral::Rmt => { - system.rmt_conf().modify(|_, w| w.rmt_clk_en().bit(enable)); - } - #[cfg(ledc)] - Peripheral::Ledc => { - system - .ledc_conf() - .modify(|_, w| w.ledc_clk_en().bit(enable)); - } - #[cfg(mcpwm0)] - Peripheral::Mcpwm0 => { - system.pwm_conf().modify(|_, w| w.pwm_clk_en().bit(enable)); - } - #[cfg(mcpwm1)] - Peripheral::Mcpwm1 => { - system.pwm_conf.modify(|_, w| w.pwm_clk_en().bit(enable)); - } - #[cfg(apb_saradc)] - Peripheral::ApbSarAdc => { - system - .saradc_conf() - .modify(|_, w| w.saradc_reg_clk_en().bit(enable)); - } - #[cfg(gdma)] - Peripheral::Gdma => { - system - .gdma_conf() - .modify(|_, w| w.gdma_clk_en().bit(enable)); - } - #[cfg(i2s0)] - Peripheral::I2s0 => { - system.i2s_conf().modify(|_, w| w.i2s_clk_en().bit(enable)); - } - #[cfg(twai0)] - Peripheral::Twai0 => { - system - .twai0_conf() - .modify(|_, w| w.twai0_clk_en().bit(enable)); - - if enable { - // use Xtal clk-src - system.twai0_func_clk_conf().modify(|_, w| { - w.twai0_func_clk_en() - .set_bit() - .twai0_func_clk_sel() - .variant(false) - }); - } - } - #[cfg(twai1)] - Peripheral::Twai1 => { - system - .twai1_conf() - .modify(|_, w| w.twai1_clk_en().bit(enable)); - } - #[cfg(aes)] - Peripheral::Aes => { - system.aes_conf().modify(|_, w| w.aes_clk_en().bit(enable)); - } - #[cfg(pcnt)] - Peripheral::Pcnt => { - system - .pcnt_conf() - .modify(|_, w| w.pcnt_clk_en().bit(enable)); - } - #[cfg(timg0)] - Peripheral::Timg0 => { - system - .timergroup0_timer_clk_conf() - .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().bit(enable)); - } - #[cfg(sha)] - Peripheral::Sha => { - system.sha_conf().modify(|_, w| w.sha_clk_en().bit(enable)); - } - #[cfg(usb_device)] - Peripheral::UsbDevice => { - system - .usb_device_conf() - .modify(|_, w| w.usb_device_clk_en().bit(enable)); - } - #[cfg(uart0)] - Peripheral::Uart0 => { - system - .uart0_conf() - .modify(|_, w| w.uart0_clk_en().bit(enable)); - } - #[cfg(uart1)] - Peripheral::Uart1 => { - system - .uart1_conf() - .modify(|_, w| w.uart1_clk_en().bit(enable)); - } - #[cfg(rsa)] - Peripheral::Rsa => { - system.rsa_conf().modify(|_, w| w.rsa_clk_en().bit(enable)); - 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().bit(enable)); - } - #[cfg(hmac)] - Peripheral::Hmac => { - system - .hmac_conf() - .modify(|_, w| w.hmac_clk_en().bit(enable)); - } - #[cfg(ecc)] - Peripheral::Ecc => { - system.ecc_conf().modify(|_, w| w.ecc_clk_en().bit(enable)); - } - #[cfg(soc_etm)] - Peripheral::Etm => { - system.etm_conf().modify(|_, w| w.etm_clk_en().bit(enable)); - } - #[cfg(trace0)] - Peripheral::Trace0 => { - system - .trace_conf() - .modify(|_, w| w.trace_clk_en().bit(enable)); - } - #[cfg(systimer)] - Peripheral::Systimer => { - system - .systimer_conf() - .modify(|_, w| w.systimer_clk_en().bit(enable)); + if enable { + // use Xtal clk-src + system.twai0_func_clk_conf().modify(|_, w| { + w.twai0_func_clk_en() + .set_bit() + .twai0_func_clk_sel() + .variant(false) + }); } } - true - }) + #[cfg(twai1)] + Peripheral::Twai1 => { + system + .twai1_conf() + .modify(|_, w| w.twai1_clk_en().bit(enable)); + } + #[cfg(aes)] + Peripheral::Aes => { + system.aes_conf().modify(|_, w| w.aes_clk_en().bit(enable)); + } + #[cfg(pcnt)] + Peripheral::Pcnt => { + system + .pcnt_conf() + .modify(|_, w| w.pcnt_clk_en().bit(enable)); + } + #[cfg(timg0)] + Peripheral::Timg0 => { + system + .timergroup0_timer_clk_conf() + .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().bit(enable)); + } + #[cfg(sha)] + Peripheral::Sha => { + system.sha_conf().modify(|_, w| w.sha_clk_en().bit(enable)); + } + #[cfg(usb_device)] + Peripheral::UsbDevice => { + system + .usb_device_conf() + .modify(|_, w| w.usb_device_clk_en().bit(enable)); + } + #[cfg(uart0)] + Peripheral::Uart0 => { + system + .uart0_conf() + .modify(|_, w| w.uart0_clk_en().bit(enable)); + } + #[cfg(uart1)] + Peripheral::Uart1 => { + system + .uart1_conf() + .modify(|_, w| w.uart1_clk_en().bit(enable)); + } + #[cfg(rsa)] + Peripheral::Rsa => { + system.rsa_conf().modify(|_, w| w.rsa_clk_en().bit(enable)); + 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().bit(enable)); + } + #[cfg(hmac)] + Peripheral::Hmac => { + system + .hmac_conf() + .modify(|_, w| w.hmac_clk_en().bit(enable)); + } + #[cfg(ecc)] + Peripheral::Ecc => { + system.ecc_conf().modify(|_, w| w.ecc_clk_en().bit(enable)); + } + #[cfg(soc_etm)] + Peripheral::Etm => { + system.etm_conf().modify(|_, w| w.etm_clk_en().bit(enable)); + } + #[cfg(trace0)] + Peripheral::Trace0 => { + system + .trace_conf() + .modify(|_, w| w.trace_clk_en().bit(enable)); + } + #[cfg(systimer)] + Peripheral::Systimer => { + system + .systimer_conf() + .modify(|_, w| w.systimer_clk_en().bit(enable)); + } + } } /// Resets the given peripheral @@ -988,6 +941,37 @@ impl PeripheralClockControl { pub(crate) fn enable(peripheral: Peripheral, enable: bool) -> bool { Self::enable_forced(peripheral, enable, false) } + + pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool { + critical_section::with(|_cs| { + if !force { + if enable { + let prev = + PERIPHERAL_REF_COUNT[peripheral as usize].fetch_add(1, Ordering::Relaxed); + if prev > 0 { + return false; + } + } else { + let prev = + PERIPHERAL_REF_COUNT[peripheral as usize].fetch_sub(1, Ordering::Relaxed); + assert!(prev != 0); + if prev > 1 { + return false; + } + }; + } else if !enable { + assert!(PERIPHERAL_REF_COUNT[peripheral as usize].swap(0, Ordering::Relaxed) == 0); + } + + if !enable { + Self::reset(peripheral); + } + + Self::enable_internal(peripheral, enable); + + true + }) + } } /// Enumeration of the available radio peripherals for this chip. From f8446fc606d6ea17c910a6fed7f8570aae2a6049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 15:27:10 +0100 Subject: [PATCH 09/14] fmt --- esp-hal/src/system.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 94c26a4184c..323c33ddee6 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -176,7 +176,6 @@ pub(crate) struct PeripheralClockControl; #[cfg(not(any(esp32c6, esp32h2)))] impl PeripheralClockControl { - fn enable_internal(peripheral: Peripheral, enable: bool) { debug!("Enable {:?} {}", peripheral, enable); From 518a0a40cc4e95a24afbf90b3b154f04f50e7c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 15:44:12 +0100 Subject: [PATCH 10/14] Require CriticalSection --- esp-hal/src/system.rs | 333 +++++++++++++++++++++--------------------- 1 file changed, 166 insertions(+), 167 deletions(-) diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 323c33ddee6..299ba7522ab 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -7,6 +7,7 @@ use core::sync::atomic::Ordering; +use critical_section::CriticalSection; use portable_atomic::AtomicUsize; use strum::{EnumCount, EnumIter, IntoEnumIterator}; @@ -176,177 +177,175 @@ pub(crate) struct PeripheralClockControl; #[cfg(not(any(esp32c6, esp32h2)))] impl PeripheralClockControl { - fn enable_internal(peripheral: Peripheral, enable: bool) { + fn enable_internal(peripheral: Peripheral, enable: bool, _cs: &CriticalSection<'_>) { debug!("Enable {:?} {}", peripheral, enable); - critical_section::with(|_cs| { - let system = unsafe { &*SYSTEM::PTR }; + let system = unsafe { &*SYSTEM::PTR }; - #[cfg(esp32)] - let (perip_clk_en0, peri_clk_en) = { (&system.perip_clk_en(), &system.peri_clk_en()) }; - #[cfg(not(esp32))] - let perip_clk_en0 = &system.perip_clk_en0(); + #[cfg(esp32)] + let (perip_clk_en0, peri_clk_en) = { (&system.perip_clk_en(), &system.peri_clk_en()) }; + #[cfg(not(esp32))] + let perip_clk_en0 = &system.perip_clk_en0(); - #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] - let perip_clk_en1 = &system.perip_clk_en1(); + #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] + let perip_clk_en1 = &system.perip_clk_en1(); - match peripheral { - #[cfg(spi2)] - Peripheral::Spi2 => { - perip_clk_en0.modify(|_, w| w.spi2_clk_en().bit(enable)); - } - #[cfg(spi3)] - Peripheral::Spi3 => { - perip_clk_en0.modify(|_, w| w.spi3_clk_en().bit(enable)); - } - #[cfg(all(i2c0, esp32))] - Peripheral::I2cExt0 => { - perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().bit(enable)); - } - #[cfg(all(i2c0, not(esp32)))] - Peripheral::I2cExt0 => { - perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().bit(enable)); - } - #[cfg(i2c1)] - Peripheral::I2cExt1 => { - perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().bit(enable)); - } - #[cfg(rmt)] - Peripheral::Rmt => { - perip_clk_en0.modify(|_, w| w.rmt_clk_en().bit(enable)); - } - #[cfg(ledc)] - Peripheral::Ledc => { - perip_clk_en0.modify(|_, w| w.ledc_clk_en().bit(enable)); - } - #[cfg(mcpwm0)] - Peripheral::Mcpwm0 => { - perip_clk_en0.modify(|_, w| w.pwm0_clk_en().bit(enable)); - } - #[cfg(mcpwm1)] - Peripheral::Mcpwm1 => { - perip_clk_en0.modify(|_, w| w.pwm1_clk_en().bit(enable)); - } - #[cfg(pcnt)] - Peripheral::Pcnt => { - perip_clk_en0.modify(|_, w| w.pcnt_clk_en().bit(enable)); - } - #[cfg(apb_saradc)] - Peripheral::ApbSarAdc => { - perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().bit(enable)); - } - #[cfg(gdma)] - Peripheral::Gdma => { - perip_clk_en1.modify(|_, w| w.dma_clk_en().bit(enable)); - } - #[cfg(esp32)] - Peripheral::Dma => { - perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().bit(enable)); - } - #[cfg(esp32s2)] - Peripheral::Dma => { - perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().bit(enable)); - perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().bit(enable)); - } - #[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().bit(enable)); - } - #[cfg(any(esp32s3, esp32, esp32s2))] - Peripheral::I2s0 => { - perip_clk_en0.modify(|_, w| w.i2s0_clk_en().bit(enable)); - } - #[cfg(any(esp32s3, esp32))] - Peripheral::I2s1 => { - perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable)); - } - #[cfg(usb0)] - Peripheral::Usb => { - perip_clk_en0.modify(|_, w| w.usb_clk_en().bit(enable)); - } - #[cfg(twai0)] - Peripheral::Twai0 => { - perip_clk_en0.modify(|_, w| w.twai_clk_en().bit(enable)); - } - #[cfg(esp32)] - Peripheral::Aes => { - peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | enable as u32) }); - } + match peripheral { + #[cfg(spi2)] + Peripheral::Spi2 => { + perip_clk_en0.modify(|_, w| w.spi2_clk_en().bit(enable)); + } + #[cfg(spi3)] + Peripheral::Spi3 => { + perip_clk_en0.modify(|_, w| w.spi3_clk_en().bit(enable)); + } + #[cfg(all(i2c0, esp32))] + Peripheral::I2cExt0 => { + perip_clk_en0.modify(|_, w| w.i2c0_ext0_clk_en().bit(enable)); + } + #[cfg(all(i2c0, not(esp32)))] + Peripheral::I2cExt0 => { + perip_clk_en0.modify(|_, w| w.i2c_ext0_clk_en().bit(enable)); + } + #[cfg(i2c1)] + Peripheral::I2cExt1 => { + perip_clk_en0.modify(|_, w| w.i2c_ext1_clk_en().bit(enable)); + } + #[cfg(rmt)] + Peripheral::Rmt => { + perip_clk_en0.modify(|_, w| w.rmt_clk_en().bit(enable)); + } + #[cfg(ledc)] + Peripheral::Ledc => { + perip_clk_en0.modify(|_, w| w.ledc_clk_en().bit(enable)); + } + #[cfg(mcpwm0)] + Peripheral::Mcpwm0 => { + perip_clk_en0.modify(|_, w| w.pwm0_clk_en().bit(enable)); + } + #[cfg(mcpwm1)] + Peripheral::Mcpwm1 => { + perip_clk_en0.modify(|_, w| w.pwm1_clk_en().bit(enable)); + } + #[cfg(pcnt)] + Peripheral::Pcnt => { + perip_clk_en0.modify(|_, w| w.pcnt_clk_en().bit(enable)); + } + #[cfg(apb_saradc)] + Peripheral::ApbSarAdc => { + perip_clk_en0.modify(|_, w| w.apb_saradc_clk_en().bit(enable)); + } + #[cfg(gdma)] + Peripheral::Gdma => { + perip_clk_en1.modify(|_, w| w.dma_clk_en().bit(enable)); + } + #[cfg(esp32)] + Peripheral::Dma => { + perip_clk_en0.modify(|_, w| w.spi_dma_clk_en().bit(enable)); + } + #[cfg(esp32s2)] + Peripheral::Dma => { + perip_clk_en0.modify(|_, w| w.spi2_dma_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.spi3_dma_clk_en().bit(enable)); + } + #[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().bit(enable)); + } + #[cfg(any(esp32s3, esp32, esp32s2))] + Peripheral::I2s0 => { + perip_clk_en0.modify(|_, w| w.i2s0_clk_en().bit(enable)); + } + #[cfg(any(esp32s3, esp32))] + Peripheral::I2s1 => { + perip_clk_en0.modify(|_, w| w.i2s1_clk_en().bit(enable)); + } + #[cfg(usb0)] + Peripheral::Usb => { + perip_clk_en0.modify(|_, w| w.usb_clk_en().bit(enable)); + } + #[cfg(twai0)] + Peripheral::Twai0 => { + perip_clk_en0.modify(|_, w| w.twai_clk_en().bit(enable)); + } + #[cfg(esp32)] + Peripheral::Aes => { + peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | enable as u32) }); + } + #[cfg(any(esp32c3, esp32s2, esp32s3))] + Peripheral::Aes => { + perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().bit(enable)); + } + #[cfg(timg0)] + Peripheral::Timg0 => { #[cfg(any(esp32c3, esp32s2, esp32s3))] - Peripheral::Aes => { - perip_clk_en1.modify(|_, w| w.crypto_aes_clk_en().bit(enable)); - } - #[cfg(timg0)] - Peripheral::Timg0 => { - #[cfg(any(esp32c3, esp32s2, esp32s3))] - perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); - perip_clk_en0.modify(|_, w| w.timergroup_clk_en().bit(enable)); - } - #[cfg(timg1)] - Peripheral::Timg1 => { - #[cfg(any(esp32c3, esp32s2, esp32s3))] - perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); - perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().bit(enable)); - } - #[cfg(sha)] - Peripheral::Sha => { - #[cfg(not(esp32))] - perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().bit(enable)); - } - #[cfg(esp32c3)] - Peripheral::UsbDevice => { - perip_clk_en0.modify(|_, w| w.usb_device_clk_en().bit(enable)); - } - #[cfg(esp32s3)] - Peripheral::UsbDevice => { - perip_clk_en1.modify(|_, w| w.usb_device_clk_en().bit(enable)); - } - #[cfg(uart0)] - Peripheral::Uart0 => { - perip_clk_en0.modify(|_, w| w.uart_clk_en().bit(enable)); - } - #[cfg(uart1)] - Peripheral::Uart1 => { - perip_clk_en0.modify(|_, w| w.uart1_clk_en().bit(enable)); - } - #[cfg(all(uart2, esp32s3))] - Peripheral::Uart2 => { - perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit()); - } - #[cfg(all(uart2, esp32))] - Peripheral::Uart2 => { - perip_clk_en0.modify(|_, w| w.uart2_clk_en().bit(enable)); - } - #[cfg(all(rsa, esp32))] - Peripheral::Rsa => { - peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | (enable as u32) << 2) }); - } - #[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))] - Peripheral::Rsa => { - perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().bit(enable)); - system - .rsa_pd_ctrl() - .modify(|_, w| w.rsa_mem_pd().bit(!enable)); - } - #[cfg(hmac)] - Peripheral::Hmac => { - perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().bit(enable)); - } - #[cfg(ecc)] - Peripheral::Ecc => { - perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().bit(enable)); - } - #[cfg(lcd_cam)] - Peripheral::LcdCam => { - perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().bit(enable)); - } - #[cfg(systimer)] - Peripheral::Systimer => { - perip_clk_en0.modify(|_, w| w.systimer_clk_en().bit(enable)); - } + perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.timergroup_clk_en().bit(enable)); } - }) + #[cfg(timg1)] + Peripheral::Timg1 => { + #[cfg(any(esp32c3, esp32s2, esp32s3))] + perip_clk_en0.modify(|_, w| w.timers_clk_en().bit(enable)); + perip_clk_en0.modify(|_, w| w.timergroup1_clk_en().bit(enable)); + } + #[cfg(sha)] + Peripheral::Sha => { + #[cfg(not(esp32))] + perip_clk_en1.modify(|_, w| w.crypto_sha_clk_en().bit(enable)); + } + #[cfg(esp32c3)] + Peripheral::UsbDevice => { + perip_clk_en0.modify(|_, w| w.usb_device_clk_en().bit(enable)); + } + #[cfg(esp32s3)] + Peripheral::UsbDevice => { + perip_clk_en1.modify(|_, w| w.usb_device_clk_en().bit(enable)); + } + #[cfg(uart0)] + Peripheral::Uart0 => { + perip_clk_en0.modify(|_, w| w.uart_clk_en().bit(enable)); + } + #[cfg(uart1)] + Peripheral::Uart1 => { + perip_clk_en0.modify(|_, w| w.uart1_clk_en().bit(enable)); + } + #[cfg(all(uart2, esp32s3))] + Peripheral::Uart2 => { + perip_clk_en1.modify(|_, w| w.uart2_clk_en().set_bit()); + } + #[cfg(all(uart2, esp32))] + Peripheral::Uart2 => { + perip_clk_en0.modify(|_, w| w.uart2_clk_en().bit(enable)); + } + #[cfg(all(rsa, esp32))] + Peripheral::Rsa => { + peri_clk_en.modify(|r, w| unsafe { w.bits(r.bits() | (enable as u32) << 2) }); + } + #[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))] + Peripheral::Rsa => { + perip_clk_en1.modify(|_, w| w.crypto_rsa_clk_en().bit(enable)); + system + .rsa_pd_ctrl() + .modify(|_, w| w.rsa_mem_pd().bit(!enable)); + } + #[cfg(hmac)] + Peripheral::Hmac => { + perip_clk_en1.modify(|_, w| w.crypto_hmac_clk_en().bit(enable)); + } + #[cfg(ecc)] + Peripheral::Ecc => { + perip_clk_en1.modify(|_, w| w.crypto_ecc_clk_en().bit(enable)); + } + #[cfg(lcd_cam)] + Peripheral::LcdCam => { + perip_clk_en1.modify(|_, w| w.lcd_cam_clk_en().bit(enable)); + } + #[cfg(systimer)] + Peripheral::Systimer => { + perip_clk_en0.modify(|_, w| w.systimer_clk_en().bit(enable)); + } + } } /// Resets the given peripheral @@ -562,7 +561,7 @@ impl PeripheralClockControl { #[cfg(any(esp32c6, esp32h2))] impl PeripheralClockControl { - fn enable_internal(peripheral: Peripheral, enable: bool) { + fn enable_internal(peripheral: Peripheral, enable: bool, _cs: &CriticalSection<'_>) { debug!("Enable {:?} {}", peripheral, enable); let system = unsafe { &*SYSTEM::PTR }; @@ -942,7 +941,7 @@ impl PeripheralClockControl { } pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool { - critical_section::with(|_cs| { + critical_section::with(|cs| { if !force { if enable { let prev = @@ -966,7 +965,7 @@ impl PeripheralClockControl { Self::reset(peripheral); } - Self::enable_internal(peripheral, enable); + Self::enable_internal(peripheral, enable, &cs); true }) From 3a20d373fb87a9302d5c718dc5fd49b66a449787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 17:54:08 +0100 Subject: [PATCH 11/14] Address comments --- esp-hal/src/i2s/master.rs | 10 ++++------ esp-hal/src/parl_io.rs | 21 ++++++++------------- esp-hal/src/rmt.rs | 7 +------ esp-hal/src/system.rs | 1 + 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index 8c89ebf52a7..5a8e4a84b26 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -259,7 +259,6 @@ where pub i2s_rx: RxCreator<'d, M, T>, /// Handles the transmission (TX) side of the I2S peripheral. pub i2s_tx: TxCreator<'d, M, T>, - guard: PeripheralGuard, } impl<'d, DmaMode, T> I2s<'d, DmaMode, T> @@ -287,7 +286,8 @@ where // make sure the peripheral is enabled before configuring it let peripheral = i2s.peripheral(); - let guard = PeripheralGuard::new(peripheral); + let rx_guard = PeripheralGuard::new(peripheral); + let tx_guard = PeripheralGuard::new(peripheral); i2s.set_clock(calculate_clock(sample_rate, 2, data_format.channel_bits())); i2s.configure(&standard, &data_format); @@ -300,15 +300,14 @@ where i2s: unsafe { i2s.clone_unchecked() }, rx_channel: channel.rx, descriptors: rx_descriptors, - guard, + guard: rx_guard, }, i2s_tx: TxCreator { i2s, tx_channel: channel.tx, descriptors: tx_descriptors, - guard: PeripheralGuard::new(peripheral), + guard: tx_guard, }, - guard: PeripheralGuard::new(peripheral), } } } @@ -446,7 +445,6 @@ where descriptors: self.i2s_tx.descriptors, guard: self.i2s_tx.guard, }, - guard: self.guard, } } } diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 797b102369c..a67e6ba19f5 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -1005,8 +1005,6 @@ where /// The receiver (RX) channel responsible for handling DMA transfers in the /// parallel I/O full-duplex operation. pub rx: RxCreatorFullDuplex<'d, DM>, - - _guard: PeripheralGuard, } impl<'d> ParlIoFullDuplex<'d, Blocking> { @@ -1023,7 +1021,8 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> { CH: DmaChannelConvert<::Dma>, Channel<'d, Blocking, CH>: From>, { - let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + let tx_guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + let rx_guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); let dma_channel = Channel::::from(dma_channel); internal_init(frequency)?; @@ -1031,14 +1030,13 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> { tx: TxCreatorFullDuplex { tx_channel: dma_channel.tx.degrade(), descriptors: tx_descriptors, - _guard: PeripheralGuard::new(crate::system::Peripheral::ParlIo), + _guard: tx_guard, }, rx: RxCreatorFullDuplex { rx_channel: dma_channel.rx.degrade(), descriptors: rx_descriptors, - _guard: PeripheralGuard::new(crate::system::Peripheral::ParlIo), + _guard: rx_guard, }, - _guard: guard, }) } @@ -1055,7 +1053,6 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> { descriptors: self.rx.descriptors, _guard: self.rx._guard, }, - _guard: self._guard, } } @@ -1110,7 +1107,6 @@ impl<'d> ParlIoFullDuplex<'d, Async> { descriptors: self.rx.descriptors, _guard: self.rx._guard, }, - _guard: self._guard, } } } @@ -1123,7 +1119,6 @@ where /// The transmitter (TX) channel responsible for handling DMA transfers in /// the parallel I/O operation. pub tx: TxCreator<'d, DM>, - _guard: PeripheralGuard, } impl<'d, DM> ParlIoTxOnly<'d, DM> @@ -1148,8 +1143,8 @@ where tx: TxCreator { tx_channel: dma_channel.tx.degrade(), descriptors, + _guard: guard, }, - _guard: guard, }) } } @@ -1200,8 +1195,6 @@ where /// The receiver (RX) channel responsible for handling DMA transfers in the /// parallel I/O operation. pub rx: RxCreator<'d, DM>, - - _guard: PeripheralGuard, } impl<'d, DM> ParlIoRxOnly<'d, DM> @@ -1226,8 +1219,8 @@ where rx: RxCreator { rx_channel: dma_channel.rx.degrade(), descriptors, + _guard: guard, }, - _guard: guard, }) } } @@ -1488,6 +1481,7 @@ where { tx_channel: ChannelTx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], + _guard: PeripheralGuard, } /// Creates a RX channel @@ -1497,6 +1491,7 @@ where { rx_channel: ChannelRx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], + _guard: PeripheralGuard, } /// Creates a TX channel diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 78777be15e8..78020de33e4 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -1016,6 +1016,7 @@ mod impl_for_chip { } /// RMT Channel +#[derive(Debug)] #[non_exhaustive] pub struct Channel where @@ -1025,12 +1026,6 @@ where _guard: PeripheralGuard, } -impl core::fmt::Debug for Channel { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "Rmt Channel {}", CHANNEL) - } -} - /// Channel in TX mode pub trait TxChannel: TxChannelInternal { /// Start transmitting the given pulse code sequence. diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 299ba7522ab..b3019ed50aa 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -150,6 +150,7 @@ pub(crate) fn disable_peripherals() { } } +#[derive(Debug)] pub(crate) struct PeripheralGuard { peripheral: Peripheral, } From 698c9e3ac142069cdabd2830a9a5d532271aad32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Fri, 15 Nov 2024 17:56:23 +0100 Subject: [PATCH 12/14] Remove redundant guard --- esp-hal/src/rmt.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 78020de33e4..6df8756a038 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -620,7 +620,6 @@ mod impl_for_chip { /// RMT Channel 3. pub channel3: ChannelCreator, phantom: PhantomData, - _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -632,8 +631,6 @@ mod impl_for_chip { ) -> Self { crate::into_ref!(peripheral); - let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); - Self { peripheral, channel0: ChannelCreator { @@ -653,7 +650,6 @@ mod impl_for_chip { _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, - _guard: guard, } } } @@ -712,7 +708,6 @@ mod impl_for_chip { /// RMT Channel 7. pub channel7: ChannelCreator, phantom: PhantomData, - _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -723,8 +718,6 @@ mod impl_for_chip { peripheral: impl Peripheral

+ 'd, ) -> Self { crate::into_ref!(peripheral); - let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); - Self { peripheral, channel0: ChannelCreator { @@ -760,7 +753,6 @@ mod impl_for_chip { _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, - _guard: guard, } } } @@ -835,7 +827,6 @@ mod impl_for_chip { /// RMT Channel 3. pub channel3: ChannelCreator, phantom: PhantomData, - _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -866,7 +857,6 @@ mod impl_for_chip { _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), } } } @@ -933,7 +923,6 @@ mod impl_for_chip { /// RMT Channel 7. pub channel7: ChannelCreator, phantom: PhantomData, - _guard: PeripheralGuard, } impl<'d, M> Rmt<'d, M> @@ -980,7 +969,6 @@ mod impl_for_chip { _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), }, phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), } } } From beddf0ca1254dd2096ea4ceac8063fed06e51352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Mon, 18 Nov 2024 10:50:46 +0100 Subject: [PATCH 13/14] Use `GenericPeripheralGuard` --- esp-hal/src/aes/mod.rs | 13 ++---- esp-hal/src/analog/adc/riscv.rs | 14 ++---- esp-hal/src/analog/adc/xtensa.rs | 15 ++----- esp-hal/src/ecc.rs | 14 ++---- esp-hal/src/etm.rs | 12 +++-- esp-hal/src/hmac.rs | 14 ++---- esp-hal/src/lcd_cam/cam.rs | 6 +-- esp-hal/src/lcd_cam/lcd/mod.rs | 9 +++- esp-hal/src/lcd_cam/mod.rs | 6 +-- esp-hal/src/otg_fs.rs | 14 ++---- esp-hal/src/parl_io.rs | 36 +++++++-------- esp-hal/src/pcnt/channel.rs | 6 +-- esp-hal/src/pcnt/mod.rs | 6 +-- esp-hal/src/pcnt/unit.rs | 6 +-- esp-hal/src/rmt.rs | 76 ++++++++++++++++---------------- esp-hal/src/rsa/mod.rs | 6 +-- esp-hal/src/sha.rs | 16 ++----- esp-hal/src/system.rs | 33 ++++++++++++++ esp-hal/src/trace.rs | 18 ++------ 19 files changed, 148 insertions(+), 172 deletions(-) diff --git a/esp-hal/src/aes/mod.rs b/esp-hal/src/aes/mod.rs index f64b4acb769..5112ebbd2c1 100644 --- a/esp-hal/src/aes/mod.rs +++ b/esp-hal/src/aes/mod.rs @@ -59,6 +59,7 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::AES, reg_access::{AlignmentHelper, NativeEndianess}, + system::GenericPeripheralGuard, }; #[cfg_attr(esp32, path = "esp32.rs")] @@ -136,6 +137,7 @@ pub enum Mode { pub struct Aes<'d> { aes: PeripheralRef<'d, AES>, alignment_helper: AlignmentHelper, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Aes as u8 }>, } impl<'d> Aes<'d> { @@ -143,13 +145,12 @@ impl<'d> Aes<'d> { pub fn new(aes: impl Peripheral

+ 'd) -> Self { crate::into_ref!(aes); - if crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Aes, true) { - crate::system::PeripheralClockControl::reset(crate::system::Peripheral::Aes); - } + let guard = GenericPeripheralGuard::new(); let mut ret = Self { aes, alignment_helper: AlignmentHelper::native_endianess(), + _guard: guard, }; ret.init(); @@ -191,12 +192,6 @@ impl<'d> Aes<'d> { } } -impl Drop for Aes<'_> { - fn drop(&mut self) { - crate::system::PeripheralClockControl::enable(crate::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 63b592857e6..c228502e4e2 100644 --- a/esp-hal/src/analog/adc/riscv.rs +++ b/esp-hal/src/analog/adc/riscv.rs @@ -8,7 +8,7 @@ use crate::efuse::Efuse; use crate::{ peripheral::PeripheralRef, peripherals::APB_SARADC, - system::{Peripheral, PeripheralClockControl}, + system::{GenericPeripheralGuard, Peripheral}, }; mod calibration; @@ -396,6 +396,7 @@ pub struct Adc<'d, ADCI> { _adc: PeripheralRef<'d, ADCI>, attenuations: [Option; NUM_ATTENS], active_channel: Option, + _guard: GenericPeripheralGuard<{ Peripheral::ApbSarAdc as u8 }>, } impl<'d, ADCI> Adc<'d, ADCI> @@ -408,9 +409,7 @@ where adc_instance: impl crate::peripheral::Peripheral

+ 'd, config: AdcConfig, ) -> Self { - if PeripheralClockControl::enable(Peripheral::ApbSarAdc, true) { - PeripheralClockControl::reset(Peripheral::ApbSarAdc); - } + let guard = GenericPeripheralGuard::new(); unsafe { &*APB_SARADC::PTR }.ctrl().modify(|_, w| unsafe { w.start_force().set_bit(); @@ -423,6 +422,7 @@ where _adc: adc_instance.into_ref(), attenuations: config.attenuations, active_channel: None, + _guard: guard, } } @@ -501,12 +501,6 @@ where } } -impl Drop for Adc<'_, ADCI> { - fn drop(&mut self) { - PeripheralClockControl::enable(Peripheral::ApbSarAdc, false); - } -} - #[cfg(any(esp32c2, esp32c3, esp32c6))] impl super::AdcCalEfuse for crate::peripherals::ADC1 { fn init_code(atten: Attenuation) -> Option { diff --git a/esp-hal/src/analog/adc/xtensa.rs b/esp-hal/src/analog/adc/xtensa.rs index b60a76c0f6d..c8f547dce5a 100644 --- a/esp-hal/src/analog/adc/xtensa.rs +++ b/esp-hal/src/analog/adc/xtensa.rs @@ -6,7 +6,7 @@ use crate::efuse::Efuse; use crate::{ peripheral::PeripheralRef, peripherals::{APB_SARADC, SENS}, - system::{Peripheral, PeripheralClockControl}, + system::{GenericPeripheralGuard, Peripheral}, }; mod calibration; @@ -389,6 +389,7 @@ pub struct Adc<'d, ADC> { _adc: PeripheralRef<'d, ADC>, active_channel: Option, last_init_code: u16, + _guard: GenericPeripheralGuard<{ Peripheral::ApbSarAdc as u8 }>, } impl<'d, ADCI> Adc<'d, ADCI> @@ -401,10 +402,7 @@ where adc_instance: impl crate::peripheral::Peripheral

+ 'd, config: AdcConfig, ) -> Self { - if PeripheralClockControl::enable(Peripheral::ApbSarAdc, true) { - PeripheralClockControl::reset(Peripheral::ApbSarAdc); - } - + let guard = GenericPeripheralGuard::new(); let sensors = unsafe { &*SENS::ptr() }; // Set attenuation for pins @@ -473,6 +471,7 @@ where _adc: adc_instance.into_ref(), active_channel: None, last_init_code: 0, + _guard: guard, } } @@ -561,12 +560,6 @@ where } } -impl Drop for Adc<'_, ADCI> { - fn drop(&mut self) { - PeripheralClockControl::enable(Peripheral::ApbSarAdc, false); - } -} - #[cfg(esp32s3)] impl super::AdcCalEfuse for crate::peripherals::ADC1 { fn init_code(atten: Attenuation) -> Option { diff --git a/esp-hal/src/ecc.rs b/esp-hal/src/ecc.rs index 74a31ff671c..6130d986891 100644 --- a/esp-hal/src/ecc.rs +++ b/esp-hal/src/ecc.rs @@ -32,7 +32,7 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::{Interrupt, ECC}, reg_access::{AlignmentHelper, SocDependentEndianess}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, + system::{self, GenericPeripheralGuard}, InterruptConfigurable, }; @@ -41,6 +41,7 @@ pub struct Ecc<'d, DM: crate::Mode> { ecc: PeripheralRef<'d, ECC>, alignment_helper: AlignmentHelper, phantom: PhantomData, + _guard: GenericPeripheralGuard<{ system::Peripheral::Ecc as u8 }>, } /// ECC interface error @@ -102,14 +103,13 @@ impl<'d> Ecc<'d, crate::Blocking> { pub fn new(ecc: impl Peripheral

+ 'd) -> Self { crate::into_ref!(ecc); - if PeripheralClockControl::enable(PeripheralEnable::Ecc, true) { - PeripheralClockControl::reset(PeripheralEnable::Ecc); - } + let guard = GenericPeripheralGuard::new(); Self { ecc, alignment_helper: AlignmentHelper::default(), phantom: PhantomData, + _guard: guard, } } } @@ -965,9 +965,3 @@ impl Ecc<'_, DM> { } } } - -impl Drop for Ecc<'_, DM> { - fn drop(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Ecc, false); - } -} diff --git a/esp-hal/src/etm.rs b/esp-hal/src/etm.rs index a2590cdeab7..b39d865730a 100644 --- a/esp-hal/src/etm.rs +++ b/esp-hal/src/etm.rs @@ -59,7 +59,7 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, - system::PeripheralClockControl, + system::GenericPeripheralGuard, }; /// Unconfigured EtmChannel. @@ -75,11 +75,8 @@ impl EtmChannel { E: EtmEvent, T: EtmTask, { - if PeripheralClockControl::enable(crate::system::Peripheral::Etm, true) { - PeripheralClockControl::reset(crate::system::Peripheral::Etm); - } - let etm = unsafe { crate::peripherals::SOC_ETM::steal() }; + let guard = GenericPeripheralGuard::new(); etm.ch(C as usize) .evt_id() @@ -96,6 +93,7 @@ impl EtmChannel { EtmConfiguredChannel { _event: event, _task: task, + _guard: guard, } } } @@ -121,6 +119,7 @@ where { _event: &'a E, _task: &'a T, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Etm as u8 }>, } impl Drop for EtmConfiguredChannel<'_, E, T, C> @@ -131,7 +130,6 @@ where fn drop(&mut self) { debug!("Drop ETM channel {}", C); disable_channel(C); - PeripheralClockControl::enable(crate::system::Peripheral::Etm, false); } } @@ -156,7 +154,7 @@ macro_rules! create_etm { Self { _peripheral: peripheral, - $([< channel $num >]: EtmChannel {},)+ + $([< channel $num >]: EtmChannel { },)+ } } } diff --git a/esp-hal/src/hmac.rs b/esp-hal/src/hmac.rs index 5946220a904..67b5e262074 100644 --- a/esp-hal/src/hmac.rs +++ b/esp-hal/src/hmac.rs @@ -40,7 +40,7 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::HMAC, reg_access::{AlignmentHelper, SocDependentEndianess}, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, + system::{GenericPeripheralGuard, Peripheral as PeripheralEnable}, }; /// Provides an interface for interacting with the HMAC hardware peripheral. @@ -51,6 +51,7 @@ pub struct Hmac<'d> { alignment_helper: AlignmentHelper, byte_written: usize, next_command: NextCommand, + _guard: GenericPeripheralGuard<{ PeripheralEnable::Hmac as u8 }>, } /// HMAC interface error @@ -107,15 +108,14 @@ impl<'d> Hmac<'d> { pub fn new(hmac: impl Peripheral

+ 'd) -> Self { crate::into_ref!(hmac); - if PeripheralClockControl::enable(PeripheralEnable::Hmac, true) { - PeripheralClockControl::reset(PeripheralEnable::Hmac); - } + let guard = GenericPeripheralGuard::new(); Self { hmac, alignment_helper: AlignmentHelper::default(), byte_written: 64, next_command: NextCommand::None, + _guard: guard, } } @@ -346,9 +346,3 @@ impl<'d> Hmac<'d> { while self.is_busy() {} } } - -impl Drop for Hmac<'_> { - fn drop(&mut self) { - PeripheralClockControl::enable(PeripheralEnable::Hmac, false); - } -} diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs index a91dcdc95f8..e22ab286864 100644 --- a/esp-hal/src/lcd_cam/cam.rs +++ b/esp-hal/src/lcd_cam/cam.rs @@ -82,7 +82,7 @@ use crate::{ lcd_cam::{calculate_clkm, BitOrder, ByteOrder}, peripheral::{Peripheral, PeripheralRef}, peripherals::LCD_CAM, - system::PeripheralGuard, + system::{self, GenericPeripheralGuard}, Blocking, }; @@ -122,14 +122,14 @@ pub enum VsyncFilterThreshold { pub struct Cam<'d> { /// The LCD_CAM peripheral reference for managing the camera functionality. pub(crate) lcd_cam: PeripheralRef<'d, LCD_CAM>, - pub(super) _guard: PeripheralGuard, + pub(super) _guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>, } /// Represents the camera interface with DMA support. pub struct Camera<'d> { lcd_cam: PeripheralRef<'d, LCD_CAM>, rx_channel: ChannelRx<'d, Blocking, ::Dma>, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>, } impl<'d> Camera<'d> { diff --git a/esp-hal/src/lcd_cam/lcd/mod.rs b/esp-hal/src/lcd_cam/lcd/mod.rs index f780f855385..66bd82a65c8 100644 --- a/esp-hal/src/lcd_cam/lcd/mod.rs +++ b/esp-hal/src/lcd_cam/lcd/mod.rs @@ -10,7 +10,12 @@ //! ## Implementation State //! - RGB is not supported yet -use crate::{peripheral::PeripheralRef, peripherals::LCD_CAM, system::PeripheralGuard}; +use super::GenericPeripheralGuard; +use crate::{ + peripheral::PeripheralRef, + peripherals::LCD_CAM, + system::{self}, +}; pub mod dpi; pub mod i8080; @@ -23,7 +28,7 @@ pub struct Lcd<'d, DM: crate::Mode> { /// A marker for the mode of operation (blocking or asynchronous). pub(crate) _mode: core::marker::PhantomData, - pub(super) _guard: PeripheralGuard, + pub(super) _guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>, } #[derive(Debug, Clone, Copy, PartialEq, Default)] diff --git a/esp-hal/src/lcd_cam/mod.rs b/esp-hal/src/lcd_cam/mod.rs index 6593783c42b..7e22c22992f 100644 --- a/esp-hal/src/lcd_cam/mod.rs +++ b/esp-hal/src/lcd_cam/mod.rs @@ -18,7 +18,7 @@ use crate::{ macros::handler, peripheral::Peripheral, peripherals::{Interrupt, LCD_CAM}, - system::{self, PeripheralGuard}, + system::GenericPeripheralGuard, Async, Blocking, Cpu, @@ -38,8 +38,8 @@ impl<'d> LcdCam<'d, Blocking> { pub fn new(lcd_cam: impl Peripheral

+ 'd) -> Self { crate::into_ref!(lcd_cam); - let lcd_guard = PeripheralGuard::new(system::Peripheral::LcdCam); - let cam_guard = PeripheralGuard::new(system::Peripheral::LcdCam); + let lcd_guard = GenericPeripheralGuard::new(); + let cam_guard = GenericPeripheralGuard::new(); Self { lcd: Lcd { diff --git a/esp-hal/src/otg_fs.rs b/esp-hal/src/otg_fs.rs index dc8a91b0e27..6b680b50208 100644 --- a/esp-hal/src/otg_fs.rs +++ b/esp-hal/src/otg_fs.rs @@ -43,7 +43,7 @@ use crate::{ gpio::InputSignal, peripheral::{Peripheral, PeripheralRef}, peripherals, - system::{Peripheral as PeripheralEnable, PeripheralClockControl}, + system::{GenericPeripheralGuard, Peripheral as PeripheralEnable}, }; #[doc(hidden)] @@ -57,6 +57,7 @@ pub trait UsbDm: crate::private::Sealed {} /// USB peripheral. pub struct Usb<'d> { _usb0: PeripheralRef<'d, peripherals::USB0>, + _guard: GenericPeripheralGuard<{ PeripheralEnable::Usb as u8 }>, } impl<'d> Usb<'d> { @@ -70,12 +71,11 @@ impl<'d> Usb<'d> { P: UsbDp + Send + Sync, M: UsbDm + Send + Sync, { - if PeripheralClockControl::enable(PeripheralEnable::Usb, true) { - PeripheralClockControl::reset(PeripheralEnable::Usb); - } + let guard = GenericPeripheralGuard::new(); Self { _usb0: usb0.into_ref(), + _guard: guard, } } @@ -111,12 +111,6 @@ impl<'d> Usb<'d> { } } -impl Drop for Usb<'_> { - 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 a67e6ba19f5..e2badab6131 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -54,7 +54,7 @@ use crate::{ interrupt::InterruptHandler, peripheral::{self, Peripheral}, peripherals::{self, Interrupt, PARL_IO}, - system::PeripheralGuard, + system::{self, GenericPeripheralGuard}, Async, Blocking, InterruptConfigurable, @@ -757,8 +757,6 @@ where P: FullDuplex + TxPins + ConfigurePins, CP: TxClkPin, { - let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); - tx_pins.configure()?; clk_pin.configure(); @@ -769,7 +767,7 @@ where Ok(ParlIoTx { tx_channel: self.tx_channel, tx_chain: DescriptorChain::new(self.descriptors), - _guard: guard, + _guard: self._guard, }) } } @@ -791,8 +789,6 @@ where P: TxPins + ConfigurePins, CP: TxClkPin, { - let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); - tx_pins.configure()?; clk_pin.configure(); @@ -803,7 +799,7 @@ where Ok(ParlIoTx { tx_channel: self.tx_channel, tx_chain: DescriptorChain::new(self.descriptors), - _guard: guard, + _guard: self._guard, }) } } @@ -815,7 +811,7 @@ where { tx_channel: ChannelTx<'d, DM, ::Dma>, tx_chain: DescriptorChain, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>, } impl core::fmt::Debug for ParlIoTx<'_, DM> @@ -843,7 +839,7 @@ where P: FullDuplex + RxPins + ConfigurePins, CP: RxClkPin, { - let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + let guard = GenericPeripheralGuard::new(); rx_pins.configure()?; clk_pin.configure(); @@ -875,8 +871,6 @@ where P: RxPins + ConfigurePins, CP: RxClkPin, { - let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); - rx_pins.configure()?; clk_pin.configure(); @@ -886,7 +880,7 @@ where Ok(ParlIoRx { rx_channel: self.rx_channel, rx_chain: DescriptorChain::new(self.descriptors), - _guard: guard, + _guard: self._guard, }) } } @@ -898,7 +892,7 @@ where { rx_channel: ChannelRx<'d, DM, ::Dma>, rx_chain: DescriptorChain, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>, } impl core::fmt::Debug for ParlIoRx<'_, DM> @@ -1021,8 +1015,8 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> { CH: DmaChannelConvert<::Dma>, Channel<'d, Blocking, CH>: From>, { - let tx_guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); - let rx_guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + let tx_guard = GenericPeripheralGuard::new(); + let rx_guard = GenericPeripheralGuard::new(); let dma_channel = Channel::::from(dma_channel); internal_init(frequency)?; @@ -1136,7 +1130,7 @@ where where CH: DmaChannelConvert<::Dma>, { - let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + let guard = GenericPeripheralGuard::new(); internal_init(frequency)?; Ok(Self { @@ -1212,7 +1206,7 @@ where where CH: DmaChannelConvert<::Dma>, { - let guard = PeripheralGuard::new(crate::system::Peripheral::ParlIo); + let guard = GenericPeripheralGuard::new(); internal_init(frequency)?; Ok(Self { @@ -1481,7 +1475,7 @@ where { tx_channel: ChannelTx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>, } /// Creates a RX channel @@ -1491,7 +1485,7 @@ where { rx_channel: ChannelRx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>, } /// Creates a TX channel @@ -1501,7 +1495,7 @@ where { tx_channel: ChannelTx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>, } /// Creates a RX channel @@ -1511,7 +1505,7 @@ where { rx_channel: ChannelRx<'d, DM, ::Dma>, descriptors: &'static mut [DmaDescriptor], - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>, } #[doc(hidden)] diff --git a/esp-hal/src/pcnt/channel.rs b/esp-hal/src/pcnt/channel.rs index 9bc7bf1c442..677c792f6d0 100644 --- a/esp-hal/src/pcnt/channel.rs +++ b/esp-hal/src/pcnt/channel.rs @@ -13,7 +13,7 @@ pub use crate::peripherals::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE use crate::{ gpio::{interconnect::PeripheralInput, InputSignal}, peripheral::Peripheral, - system::PeripheralGuard, + system::GenericPeripheralGuard, }; /// Represents a channel within a pulse counter unit. @@ -21,13 +21,13 @@ pub struct Channel<'d, const UNIT: usize, const NUM: usize> { _phantom: PhantomData<&'d ()>, // Individual channels are not Send, since they share registers. _not_send: PhantomData<*const ()>, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>, } impl Channel<'_, UNIT, NUM> { /// return a new Channel pub(super) fn new() -> Self { - let guard = PeripheralGuard::new(crate::system::Peripheral::Pcnt); + let guard = GenericPeripheralGuard::new(); Self { _phantom: PhantomData, diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index c5aad52e3e5..e0072619a6d 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -25,7 +25,7 @@ use crate::{ interrupt::{self, InterruptHandler}, peripheral::{Peripheral, PeripheralRef}, peripherals::{self, Interrupt}, - system::PeripheralGuard, + system::GenericPeripheralGuard, InterruptConfigurable, }; @@ -57,7 +57,7 @@ pub struct Pcnt<'d> { /// Unit 7 pub unit7: Unit<'d, 7>, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>, } impl<'d> Pcnt<'d> { @@ -65,7 +65,7 @@ impl<'d> Pcnt<'d> { pub fn new(_instance: impl Peripheral

+ 'd) -> Self { crate::into_ref!(_instance); - let guard = PeripheralGuard::new(crate::system::Peripheral::Pcnt); + let guard = GenericPeripheralGuard::new(); let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() }; // disable filter, all events, and channel settings diff --git a/esp-hal/src/pcnt/unit.rs b/esp-hal/src/pcnt/unit.rs index 9a2aad15bef..ee3d3584a51 100644 --- a/esp-hal/src/pcnt/unit.rs +++ b/esp-hal/src/pcnt/unit.rs @@ -13,7 +13,7 @@ use core::marker::PhantomData; use critical_section::CriticalSection; -use crate::{pcnt::channel::Channel, system::PeripheralGuard}; +use crate::{pcnt::channel::Channel, system::GenericPeripheralGuard}; /// Invalid filter threshold value #[derive(Debug, Clone, Copy, PartialEq)] @@ -83,13 +83,13 @@ pub struct Unit<'d, const NUM: usize> { /// The second channel in PCNT unit. pub channel1: Channel<'d, NUM, 1>, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Pcnt as u8 }>, } impl Unit<'_, NUM> { /// return a new Unit pub(super) fn new() -> Self { - let guard = PeripheralGuard::new(crate::system::Peripheral::Pcnt); + let guard = GenericPeripheralGuard::new(); Self { counter: Counter::new(), diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 6df8756a038..1cb83b368f8 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -94,7 +94,7 @@ use crate::{ peripheral::Peripheral, peripherals::Interrupt, soc::constants, - system::PeripheralGuard, + system::{self, GenericPeripheralGuard}, Async, Blocking, InterruptConfigurable, @@ -602,7 +602,7 @@ mod impl_for_chip { use crate::{ peripheral::{Peripheral, PeripheralRef}, - system::PeripheralGuard, + system::GenericPeripheralGuard, }; /// RMT Instance @@ -635,19 +635,19 @@ mod impl_for_chip { peripheral, channel0: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel1: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel2: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel3: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, phantom: PhantomData, } @@ -660,7 +660,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, } impl_tx_channel_creator!(0); @@ -682,7 +682,7 @@ mod impl_for_chip { use crate::{ peripheral::{Peripheral, PeripheralRef}, - system::PeripheralGuard, + system::GenericPeripheralGuard, }; /// RMT Instance @@ -722,35 +722,35 @@ mod impl_for_chip { peripheral, channel0: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel1: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel2: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel3: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel4: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel5: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel6: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel7: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, phantom: PhantomData, } @@ -763,7 +763,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, } impl_tx_channel_creator!(0); @@ -809,7 +809,7 @@ mod impl_for_chip { use crate::{ peripheral::{Peripheral, PeripheralRef}, - system::PeripheralGuard, + system::GenericPeripheralGuard, }; /// RMT Instance @@ -842,19 +842,19 @@ mod impl_for_chip { peripheral, channel0: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel1: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel2: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel3: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, phantom: PhantomData, } @@ -867,7 +867,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, } impl_tx_channel_creator!(0); @@ -897,7 +897,7 @@ mod impl_for_chip { use crate::{ peripheral::{Peripheral, PeripheralRef}, - system::PeripheralGuard, + system::GenericPeripheralGuard, }; /// RMT Instance @@ -938,35 +938,35 @@ mod impl_for_chip { peripheral, channel0: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel1: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel2: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel3: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel4: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel5: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel6: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, channel7: ChannelCreator { phantom: PhantomData, - _guard: PeripheralGuard::new(crate::system::Peripheral::Rmt), + _guard: GenericPeripheralGuard::new(), }, phantom: PhantomData, } @@ -979,7 +979,7 @@ mod impl_for_chip { M: crate::Mode, { phantom: PhantomData, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Rmt as u8 }>, } impl_tx_channel_creator!(0); @@ -1011,7 +1011,7 @@ where M: crate::Mode, { phantom: PhantomData, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ system::Peripheral::Rmt as u8 }>, } /// Channel in TX mode @@ -1631,7 +1631,7 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { - let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); + let guard = GenericPeripheralGuard::new(); Self { phantom: core::marker::PhantomData, _guard: guard, @@ -1794,7 +1794,7 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { - let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); + let guard = GenericPeripheralGuard::new(); Self { phantom: core::marker::PhantomData, _guard: guard, @@ -1985,7 +1985,7 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { - let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); + let guard = GenericPeripheralGuard::new(); Self { phantom: core::marker::PhantomData, _guard: guard, @@ -2138,7 +2138,7 @@ mod chip_specific { const CHANNEL: u8 = $ch_num; fn new() -> Self { - let guard = PeripheralGuard::new(crate::system::Peripheral::Rmt); + let guard = GenericPeripheralGuard::new(); Self { phantom: core::marker::PhantomData, _guard: guard, diff --git a/esp-hal/src/rsa/mod.rs b/esp-hal/src/rsa/mod.rs index 77211cedfd8..6734589451b 100644 --- a/esp-hal/src/rsa/mod.rs +++ b/esp-hal/src/rsa/mod.rs @@ -27,7 +27,7 @@ use crate::{ interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, peripherals::{Interrupt, RSA}, - system::{Peripheral as PeripheralEnable, PeripheralGuard}, + system::{GenericPeripheralGuard, Peripheral as PeripheralEnable}, Async, Blocking, Cpu, @@ -48,7 +48,7 @@ pub use rsa_spec_impl::operand_sizes; pub struct Rsa<'d, DM: crate::Mode> { rsa: PeripheralRef<'d, RSA>, phantom: PhantomData, - _guard: PeripheralGuard, + _guard: GenericPeripheralGuard<{ PeripheralEnable::Rsa as u8 }>, } impl<'d> Rsa<'d, Blocking> { @@ -98,7 +98,7 @@ impl<'d, DM: crate::Mode> Rsa<'d, DM> { fn new_internal(rsa: impl Peripheral

+ 'd) -> Self { crate::into_ref!(rsa); - let guard = PeripheralGuard::new(PeripheralEnable::Rsa); + let guard = GenericPeripheralGuard::new(); Self { rsa, diff --git a/esp-hal/src/sha.rs b/esp-hal/src/sha.rs index e5b333070f9..91526b09c4e 100644 --- a/esp-hal/src/sha.rs +++ b/esp-hal/src/sha.rs @@ -68,24 +68,22 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::SHA, reg_access::{AlignmentHelper, SocDependentEndianess}, - system::PeripheralClockControl, + system::GenericPeripheralGuard, }; /// The SHA Accelerator driver instance pub struct Sha<'d> { sha: PeripheralRef<'d, SHA>, + _guard: GenericPeripheralGuard<{ crate::system::Peripheral::Sha as u8 }>, } impl<'d> Sha<'d> { /// Create a new instance of the SHA Accelerator driver. pub fn new(sha: impl Peripheral

+ 'd) -> Self { crate::into_ref!(sha); + let guard = GenericPeripheralGuard::new(); - if PeripheralClockControl::enable(crate::system::Peripheral::Sha, true) { - PeripheralClockControl::reset(crate::system::Peripheral::Sha); - } - - Self { sha } + Self { sha, _guard: guard } } /// Start a new digest. @@ -103,12 +101,6 @@ impl<'d> Sha<'d> { impl crate::private::Sealed for Sha<'_> {} -impl Drop for Sha<'_> { - fn drop(&mut self) { - PeripheralClockControl::enable(crate::system::Peripheral::Sha, false); - } -} - #[cfg(not(esp32))] impl crate::InterruptConfigurable for Sha<'_> { fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) { diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index b3019ed50aa..1c677df4dcf 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -135,6 +135,16 @@ pub enum Peripheral { Systimer, } +impl Peripheral { + pub fn try_from(value: u8) -> Option { + if value >= Peripheral::COUNT as u8 { + return None; + } + + Some(unsafe { core::mem::transmute::(value) }) + } +} + static PERIPHERAL_REF_COUNT: [AtomicUsize; Peripheral::COUNT] = [const { AtomicUsize::new(0) }; Peripheral::COUNT]; @@ -173,6 +183,29 @@ impl Drop for PeripheralGuard { } } +#[derive(Debug)] +pub(crate) struct GenericPeripheralGuard {} + +impl GenericPeripheralGuard

{ + pub(crate) fn new() -> Self { + let peripheral = unwrap!(Peripheral::try_from(P)); + if !KEEP_ENABLED.contains(&peripheral) && PeripheralClockControl::enable(peripheral, true) { + PeripheralClockControl::reset(peripheral); + } + + Self {} + } +} + +impl Drop for GenericPeripheralGuard

{ + fn drop(&mut self) { + let peripheral = unwrap!(Peripheral::try_from(P)); + if !KEEP_ENABLED.contains(&peripheral) { + PeripheralClockControl::enable(peripheral, false); + } + } +} + /// Controls the enablement of peripheral clocks. pub(crate) struct PeripheralClockControl; diff --git a/esp-hal/src/trace.rs b/esp-hal/src/trace.rs index f093b525e89..09777515764 100644 --- a/esp-hal/src/trace.rs +++ b/esp-hal/src/trace.rs @@ -36,7 +36,7 @@ use crate::{ peripheral::{Peripheral, PeripheralRef}, peripherals::trace::RegisterBlock, - system::PeripheralClockControl, + system::PeripheralGuard, }; /// Errors returned from [Trace::stop_trace] @@ -62,6 +62,7 @@ where { peripheral: PeripheralRef<'d, T>, buffer: Option<&'d mut [u8]>, + _guard: PeripheralGuard, } impl<'d, T> Trace<'d, T> @@ -71,14 +72,12 @@ where /// Construct a new instance pub fn new(peripheral: impl Peripheral

+ 'd) -> Self { crate::into_ref!(peripheral); - - if PeripheralClockControl::enable(peripheral.peripheral(), true) { - PeripheralClockControl::reset(peripheral.peripheral()); - } + let guard = PeripheralGuard::new(peripheral.peripheral()); Self { peripheral, buffer: None, + _guard: guard, } } @@ -207,15 +206,6 @@ where } } -impl Drop for Trace<'_, T> -where - T: Instance, -{ - fn drop(&mut self) { - PeripheralClockControl::enable(self.peripheral.peripheral(), false); - } -} - /// Trace peripheral instance pub trait Instance: crate::private::Sealed { /// Get a reference to the peripheral's underlying register block From 2cd70ec47672b933e1e58b578430a4412c7beeb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Quentin?= Date: Wed, 20 Nov 2024 12:39:36 +0100 Subject: [PATCH 14/14] Renaming --- esp-hal/src/dma/gdma.rs | 2 +- esp-hal/src/dma/pdma.rs | 2 +- esp-hal/src/i2c/master/mod.rs | 4 ++-- esp-hal/src/ledc/mod.rs | 2 +- esp-hal/src/system.rs | 29 +++++++++++++++++++---------- esp-hal/src/timer/systimer.rs | 2 +- esp-hal/src/timer/timg.rs | 4 ++-- esp-hal/src/usb_serial_jtag.rs | 2 +- 8 files changed, 28 insertions(+), 19 deletions(-) diff --git a/esp-hal/src/dma/gdma.rs b/esp-hal/src/dma/gdma.rs index 581a8f9564f..c53a5f5a9ee 100644 --- a/esp-hal/src/dma/gdma.rs +++ b/esp-hal/src/dma/gdma.rs @@ -753,7 +753,7 @@ impl<'d> Dma<'d> { ) -> Dma<'d> { crate::into_ref!(dma); - if PeripheralClockControl::enable(Peripheral::Gdma, true) { + if PeripheralClockControl::enable(Peripheral::Gdma) { PeripheralClockControl::reset(Peripheral::Gdma); } dma.misc_conf().modify(|_, w| w.ahbm_rst_inter().set_bit()); diff --git a/esp-hal/src/dma/pdma.rs b/esp-hal/src/dma/pdma.rs index 0023f007b98..738e486d945 100644 --- a/esp-hal/src/dma/pdma.rs +++ b/esp-hal/src/dma/pdma.rs @@ -942,7 +942,7 @@ impl<'d> Dma<'d> { pub fn new( dma: impl crate::peripheral::Peripheral

+ 'd, ) -> Dma<'d> { - if PeripheralClockControl::enable(Peripheral::Dma, true) { + if PeripheralClockControl::enable(Peripheral::Dma) { PeripheralClockControl::reset(Peripheral::Dma); } diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index dff8d9f1832..bfb102af5d7 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -353,8 +353,8 @@ where } fn internal_recover(&self) { - PeripheralClockControl::enable(self.driver().info.peripheral, false); - PeripheralClockControl::enable(self.driver().info.peripheral, true); + PeripheralClockControl::disable(self.driver().info.peripheral); + PeripheralClockControl::enable(self.driver().info.peripheral); PeripheralClockControl::reset(self.driver().info.peripheral); // We know the configuration is valid, we can ignore the result. diff --git a/esp-hal/src/ledc/mod.rs b/esp-hal/src/ledc/mod.rs index 83e90a6e11b..1c4b5c58c3d 100644 --- a/esp-hal/src/ledc/mod.rs +++ b/esp-hal/src/ledc/mod.rs @@ -111,7 +111,7 @@ impl<'d> Ledc<'d> { pub fn new(_instance: impl Peripheral

+ 'd) -> Self { crate::into_ref!(_instance); - if PeripheralClockControl::enable(PeripheralEnable::Ledc, true) { + if PeripheralClockControl::enable(PeripheralEnable::Ledc) { PeripheralClockControl::reset(PeripheralEnable::Ledc); } diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index 1c677df4dcf..40f0a69b31b 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -167,7 +167,7 @@ pub(crate) struct PeripheralGuard { impl PeripheralGuard { pub(crate) fn new(p: Peripheral) -> Self { - if !KEEP_ENABLED.contains(&p) && PeripheralClockControl::enable(p, true) { + if !KEEP_ENABLED.contains(&p) && PeripheralClockControl::enable(p) { PeripheralClockControl::reset(p); } @@ -178,7 +178,7 @@ impl PeripheralGuard { impl Drop for PeripheralGuard { fn drop(&mut self) { if !KEEP_ENABLED.contains(&self.peripheral) { - PeripheralClockControl::enable(self.peripheral, false); + PeripheralClockControl::disable(self.peripheral); } } } @@ -189,7 +189,7 @@ pub(crate) struct GenericPeripheralGuard {} impl GenericPeripheralGuard

{ pub(crate) fn new() -> Self { let peripheral = unwrap!(Peripheral::try_from(P)); - if !KEEP_ENABLED.contains(&peripheral) && PeripheralClockControl::enable(peripheral, true) { + if !KEEP_ENABLED.contains(&peripheral) && PeripheralClockControl::enable(peripheral) { PeripheralClockControl::reset(peripheral); } @@ -201,7 +201,7 @@ impl Drop for GenericPeripheralGuard

{ fn drop(&mut self) { let peripheral = unwrap!(Peripheral::try_from(P)); if !KEEP_ENABLED.contains(&peripheral) { - PeripheralClockControl::enable(peripheral, false); + PeripheralClockControl::disable(peripheral); } } } @@ -961,17 +961,26 @@ impl PeripheralClockControl { } impl PeripheralClockControl { - /// Enables/disables the given peripheral. + /// Enables the given peripheral. /// - /// This keeps track of enabling/disabling a peripheral - i.e. a peripheral - /// is only enabled with the first call attempt to enable it. It only + /// This keeps track of enabling a peripheral - i.e. a peripheral + /// is only enabled with the first call attempt to enable it. + /// + /// Returns `true` if it actually enabled the peripheral. + pub(crate) fn enable(peripheral: Peripheral) -> bool { + Self::enable_forced(peripheral, true, false) + } + + /// Disables the given peripheral. + /// + /// This keeps track of disabling a peripheral - i.e. it only /// gets disabled when the number of enable/disable attempts is balanced. /// - /// Returns `true` if it actually enabled/disabled the peripheral. + /// Returns `true` if it actually disabled the peripheral. /// /// Before disabling a peripheral it will also get reset - pub(crate) fn enable(peripheral: Peripheral, enable: bool) -> bool { - Self::enable_forced(peripheral, enable, false) + pub(crate) fn disable(peripheral: Peripheral) -> bool { + Self::enable_forced(peripheral, false, false) } pub(crate) fn enable_forced(peripheral: Peripheral, enable: bool, force: bool) -> bool { diff --git a/esp-hal/src/timer/systimer.rs b/esp-hal/src/timer/systimer.rs index f54aeb44eab..d640502041e 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, true); + PeripheralClockControl::enable(PeripheralEnable::Systimer); #[cfg(soc_etm)] etm::enable_etm(); diff --git a/esp-hal/src/timer/timg.rs b/esp-hal/src/timer/timg.rs index 77924fb87bb..bcbfc619391 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() { - PeripheralClockControl::enable(crate::system::Peripheral::Timg0, true); + PeripheralClockControl::enable(crate::system::Peripheral::Timg0); } fn reset_peripheral() { @@ -215,7 +215,7 @@ impl TimerGroupInstance for crate::peripherals::TIMG1 { } fn enable_peripheral() { - PeripheralClockControl::enable(crate::system::Peripheral::Timg1, true); + PeripheralClockControl::enable(crate::system::Peripheral::Timg1); } fn reset_peripheral() { diff --git a/esp-hal/src/usb_serial_jtag.rs b/esp-hal/src/usb_serial_jtag.rs index c76d714a828..c94c2be6c93 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, true); + PeripheralClockControl::enable(crate::system::Peripheral::UsbDevice); USB_DEVICE::disable_tx_interrupts(); USB_DEVICE::disable_rx_interrupts();