diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 0174e29d9d0..2ae37b2f933 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added touch pad support for esp32 (#1873) - Allow configuration of period updating method for MCPWM timers (#1898) - Add self-testing mode for TWAI peripheral. (#1929) +- Added a `PeripheralClockControl::reset` to the driver constructors where missing (#1893) ### Changed @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow DMA to/from psram for esp32s3 (#1827) - DMA buffers now don't require a static lifetime. Make sure to never `mem::forget` an in-progress DMA transfer (consider using `#[deny(clippy::mem_forget)]`) (#1837) +- Peripherals (where possible) are now explicitly reset and enabled in their constructors (#1893) ### Fixed diff --git a/esp-hal/src/aes/mod.rs b/esp-hal/src/aes/mod.rs index c955c51e5fd..f7892f8ed89 100644 --- a/esp-hal/src/aes/mod.rs +++ b/esp-hal/src/aes/mod.rs @@ -135,6 +135,10 @@ impl<'d> Aes<'d> { /// Constructs a new `Aes` instance. 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); + let mut ret = Self { aes, alignment_helper: AlignmentHelper::native_endianess(), diff --git a/esp-hal/src/analog/adc/riscv.rs b/esp-hal/src/analog/adc/riscv.rs index 428acea3327..45952dfe78c 100644 --- a/esp-hal/src/analog/adc/riscv.rs +++ b/esp-hal/src/analog/adc/riscv.rs @@ -408,6 +408,7 @@ where adc_instance: impl crate::peripheral::Peripheral

+ 'd, config: AdcConfig, ) -> Self { + PeripheralClockControl::reset(Peripheral::ApbSarAdc); PeripheralClockControl::enable(Peripheral::ApbSarAdc); unsafe { &*APB_SARADC::PTR }.ctrl().modify(|_, w| unsafe { diff --git a/esp-hal/src/analog/adc/xtensa.rs b/esp-hal/src/analog/adc/xtensa.rs index 65e51d75ff9..631466f526e 100644 --- a/esp-hal/src/analog/adc/xtensa.rs +++ b/esp-hal/src/analog/adc/xtensa.rs @@ -6,6 +6,7 @@ use crate::efuse::Efuse; use crate::{ peripheral::PeripheralRef, peripherals::{APB_SARADC, SENS}, + system::{Peripheral, PeripheralClockControl}, }; mod calibration; @@ -400,6 +401,9 @@ where adc_instance: impl crate::peripheral::Peripheral

+ 'd, config: AdcConfig, ) -> Self { + PeripheralClockControl::reset(Peripheral::ApbSarAdc); + PeripheralClockControl::enable(Peripheral::ApbSarAdc); + let sensors = unsafe { &*SENS::ptr() }; // Set attenuation for pins diff --git a/esp-hal/src/ecc.rs b/esp-hal/src/ecc.rs index 43424bad9e6..f2139ff48ee 100644 --- a/esp-hal/src/ecc.rs +++ b/esp-hal/src/ecc.rs @@ -85,6 +85,7 @@ 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); Self { diff --git a/esp-hal/src/etm.rs b/esp-hal/src/etm.rs index ea35a9cc70e..e5e83fe6e4c 100644 --- a/esp-hal/src/etm.rs +++ b/esp-hal/src/etm.rs @@ -149,6 +149,7 @@ 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 { diff --git a/esp-hal/src/hmac.rs b/esp-hal/src/hmac.rs index f2b37a83048..ea5bf77568f 100644 --- a/esp-hal/src/hmac.rs +++ b/esp-hal/src/hmac.rs @@ -96,7 +96,7 @@ impl<'d> Hmac<'d> { pub fn new(hmac: impl Peripheral

+ 'd) -> Self { crate::into_ref!(hmac); - PeripheralClockControl::enable(PeripheralEnable::Sha); + PeripheralClockControl::reset(PeripheralEnable::Hmac); PeripheralClockControl::enable(PeripheralEnable::Hmac); Self { diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index 4a53db16452..469231ca5be 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -330,6 +330,7 @@ where // the targets the same and force same configuration for both, TX and RX channel.tx.init_channel(); + PeripheralClockControl::reset(I::get_peripheral()); PeripheralClockControl::enable(I::get_peripheral()); I::set_clock(calculate_clock( sample_rate, diff --git a/esp-hal/src/lcd_cam/mod.rs b/esp-hal/src/lcd_cam/mod.rs index ec1b2b3b334..c7450d86d73 100644 --- a/esp-hal/src/lcd_cam/mod.rs +++ b/esp-hal/src/lcd_cam/mod.rs @@ -28,6 +28,7 @@ impl<'d> LcdCam<'d, crate::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); Self { diff --git a/esp-hal/src/ledc/mod.rs b/esp-hal/src/ledc/mod.rs index 58a1650eb8f..c1a4fe78a95 100644 --- a/esp-hal/src/ledc/mod.rs +++ b/esp-hal/src/ledc/mod.rs @@ -114,6 +114,8 @@ impl<'d> Ledc<'d> { clock_control_config: &'d Clocks<'d>, ) -> Self { crate::into_ref!(_instance); + + PeripheralClockControl::reset(PeripheralEnable::Ledc); PeripheralClockControl::enable(PeripheralEnable::Ledc); let ledc = unsafe { &*crate::peripherals::LEDC::ptr() }; diff --git a/esp-hal/src/mcpwm/mod.rs b/esp-hal/src/mcpwm/mod.rs index 7ebfedf48ee..4f8c3ad7729 100644 --- a/esp-hal/src/mcpwm/mod.rs +++ b/esp-hal/src/mcpwm/mod.rs @@ -132,6 +132,7 @@ impl<'d, PWM: PwmPeripheral> McPwm<'d, PWM> { ) -> Self { crate::into_ref!(peripheral); + PWM::reset(); PWM::enable(); #[cfg(not(esp32c6))] @@ -312,6 +313,8 @@ pub struct FrequencyError; 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 @@ -324,6 +327,10 @@ impl PwmPeripheral for crate::peripherals::MCPWM0 { PeripheralClockControl::enable(PeripheralEnable::Mcpwm0) } + fn reset() { + PeripheralClockControl::reset(PeripheralEnable::Mcpwm0) + } + fn block() -> *const RegisterBlock { Self::PTR } @@ -347,6 +354,10 @@ impl PwmPeripheral for crate::peripherals::MCPWM1 { PeripheralClockControl::enable(PeripheralEnable::Mcpwm1) } + fn reset() { + PeripheralClockControl::reset(PeripheralEnable::Mcpwm1) + } + fn block() -> *const RegisterBlock { Self::PTR } diff --git a/esp-hal/src/otg_fs.rs b/esp-hal/src/otg_fs.rs index 75c4c0c0b23..235cf9d3c73 100644 --- a/esp-hal/src/otg_fs.rs +++ b/esp-hal/src/otg_fs.rs @@ -66,6 +66,7 @@ impl<'d> Usb<'d> { P: UsbDp + Send + Sync, M: UsbDm + Send + Sync, { + PeripheralClockControl::reset(PeripheralEnable::Usb); PeripheralClockControl::enable(PeripheralEnable::Usb); Self { diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index af1bd40da57..8d0194c904c 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -1381,6 +1381,7 @@ where return Err(Error::UnreachableClockRate); } + PeripheralClockControl::reset(crate::system::Peripheral::ParlIo); PeripheralClockControl::enable(crate::system::Peripheral::ParlIo); let pcr = unsafe { &*crate::peripherals::PCR::PTR }; diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index 8bd28fe33d7..8afae49f92d 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -61,6 +61,7 @@ impl<'d> Pcnt<'d> { /// Return a new PCNT 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); diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index 1d1d288f0ef..eb2b43a277e 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -227,6 +227,7 @@ where return Err(Error::UnreachableTargetFrequency); } + PeripheralClockControl::reset(crate::system::Peripheral::Rmt); PeripheralClockControl::enable(crate::system::Peripheral::Rmt); #[cfg(not(any(esp32, esp32s2)))] diff --git a/esp-hal/src/rsa/mod.rs b/esp-hal/src/rsa/mod.rs index 8a0afd88364..943fd5c3b82 100644 --- a/esp-hal/src/rsa/mod.rs +++ b/esp-hal/src/rsa/mod.rs @@ -101,6 +101,7 @@ 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); Self { diff --git a/esp-hal/src/sha.rs b/esp-hal/src/sha.rs index 7e2b276c9ef..26364ad592b 100644 --- a/esp-hal/src/sha.rs +++ b/esp-hal/src/sha.rs @@ -136,6 +136,7 @@ impl<'d> Sha<'d, crate::Blocking> { pub fn new(sha: impl Peripheral

+ 'd, mode: ShaMode) -> Self { crate::into_ref!(sha); + PeripheralClockControl::reset(crate::system::Peripheral::Sha); PeripheralClockControl::enable(crate::system::Peripheral::Sha); // Setup SHA Mode diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index ef9556c9512..d028837b2a8 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -544,6 +544,7 @@ where mode: SpiMode, clocks: &Clocks<'d>, ) -> Spi<'d, T, FullDuplexMode> { + spi.reset_peripheral(); spi.enable_peripheral(); let mut spi = Spi { @@ -721,6 +722,7 @@ where mode: SpiMode, clocks: &Clocks<'d>, ) -> Spi<'d, T, HalfDuplexMode> { + spi.reset_peripheral(); spi.enable_peripheral(); let mut spi = Spi { @@ -2295,6 +2297,8 @@ pub trait Instance: private::Sealed { fn enable_peripheral(&self); + fn reset_peripheral(&self); + fn spi_num(&self) -> u8; /// Initialize for full-duplex 1 bit mode @@ -3255,6 +3259,11 @@ impl Instance for crate::peripherals::SPI2 { PeripheralClockControl::enable(crate::system::Peripheral::Spi2); } + #[inline(always)] + fn reset_peripheral(&self) { + PeripheralClockControl::reset(crate::system::Peripheral::Spi2); + } + #[inline(always)] fn spi_num(&self) -> u8 { 2 @@ -3332,6 +3341,11 @@ impl Instance for crate::peripherals::SPI2 { PeripheralClockControl::enable(crate::system::Peripheral::Spi2); } + #[inline(always)] + fn reset_peripheral(&self) { + PeripheralClockControl::reset(crate::system::Peripheral::Spi2); + } + #[inline(always)] fn spi_num(&self) -> u8 { 2 @@ -3403,6 +3417,11 @@ impl Instance for crate::peripherals::SPI3 { PeripheralClockControl::enable(crate::system::Peripheral::Spi3) } + #[inline(always)] + fn reset_peripheral(&self) { + PeripheralClockControl::reset(crate::system::Peripheral::Spi3) + } + #[inline(always)] fn spi_num(&self) -> u8 { 3 @@ -3447,6 +3466,11 @@ impl Instance for crate::peripherals::SPI2 { PeripheralClockControl::enable(crate::system::Peripheral::Spi2) } + #[inline(always)] + fn reset_peripheral(&self) { + PeripheralClockControl::reset(crate::system::Peripheral::Spi2) + } + #[inline(always)] fn spi_num(&self) -> u8 { 2 @@ -3524,6 +3548,11 @@ impl Instance for crate::peripherals::SPI3 { PeripheralClockControl::enable(crate::system::Peripheral::Spi3) } + #[inline(always)] + fn reset_peripheral(&self) { + PeripheralClockControl::reset(crate::system::Peripheral::Spi3) + } + #[inline(always)] fn spi_num(&self) -> u8 { 3 diff --git a/esp-hal/src/timer/timg.rs b/esp-hal/src/timer/timg.rs index bfea536f99a..3fb12060b9d 100644 --- a/esp-hal/src/timer/timg.rs +++ b/esp-hal/src/timer/timg.rs @@ -106,6 +106,8 @@ pub trait TimerGroupInstance { fn id() -> u8; fn register_block() -> *const RegisterBlock; fn configure_src_clk(); + fn enable_peripheral(); + fn reset_peripheral(); fn configure_wdt_src_clk(); } @@ -144,6 +146,14 @@ impl TimerGroupInstance for TIMG0 { // ESP32 has only APB clock source, do nothing } + fn enable_peripheral() { + crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Timg0) + } + + fn reset_peripheral() { + // for TIMG0 do nothing for now because the reset breaks `current_time` + } + #[inline(always)] #[cfg(any(esp32c2, esp32c3))] fn configure_wdt_src_clk() { @@ -206,6 +216,16 @@ impl TimerGroupInstance for TIMG1 { // ESP32-C2 and ESP32-C3 don't have t1config only t0config, do nothing } + #[inline(always)] + fn enable_peripheral() { + crate::system::PeripheralClockControl::enable(crate::system::Peripheral::Timg1) + } + + #[inline(always)] + fn reset_peripheral() { + crate::system::PeripheralClockControl::reset(crate::system::Peripheral::Timg1) + } + #[inline(always)] #[cfg(any(esp32c6, esp32h2))] fn configure_wdt_src_clk() { @@ -230,6 +250,9 @@ where pub fn new(_timer_group: impl Peripheral

+ 'd, clocks: &Clocks<'d>) -> Self { crate::into_ref!(_timer_group); + T::reset_peripheral(); + T::enable_peripheral(); + T::configure_src_clk(); // ESP32-H2 is using PLL_48M_CLK source instead of APB_CLK @@ -269,6 +292,9 @@ where pub fn new_async(_timer_group: impl Peripheral

+ 'd, clocks: &Clocks<'d>) -> Self { crate::into_ref!(_timer_group); + T::reset_peripheral(); + T::enable_peripheral(); + T::configure_src_clk(); // ESP32-H2 is using PLL_48M_CLK source instead of APB_CLK diff --git a/esp-hal/src/trace.rs b/esp-hal/src/trace.rs index ef6d2a35ca0..3bd26c7b0d3 100644 --- a/esp-hal/src/trace.rs +++ b/esp-hal/src/trace.rs @@ -66,6 +66,7 @@ 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); Self { diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index 9b8350803f4..bf588080c0e 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -735,7 +735,11 @@ where no_transceiver: bool, mode: TwaiMode, ) -> Self { + // Set up the GPIO pins. + crate::into_ref!(tx_pin, rx_pin); + // Enable the peripheral clock for the TWAI peripheral. + T::reset_peripheral(); T::enable_peripheral(); // Set RESET bit to 1 @@ -743,8 +747,6 @@ where .mode() .write(|w| w.reset_mode().set_bit()); - // Set up the GPIO pins. - crate::into_ref!(tx_pin, rx_pin); if no_transceiver { tx_pin.set_to_open_drain_output(crate::private::Internal); } @@ -1285,6 +1287,8 @@ pub trait Instance: crate::private::Sealed { fn enable_peripheral(); + fn reset_peripheral(); + fn enable_interrupts(); } @@ -1475,6 +1479,10 @@ impl Instance for crate::peripherals::TWAI0 { unsafe { &*crate::peripherals::TWAI0::PTR } } + fn reset_peripheral() { + PeripheralClockControl::reset(crate::system::Peripheral::Twai0); + } + fn enable_peripheral() { PeripheralClockControl::enable(crate::system::Peripheral::Twai0); } @@ -1519,6 +1527,10 @@ impl Instance for crate::peripherals::TWAI0 { unsafe { &*crate::peripherals::TWAI0::PTR } } + fn reset_peripheral() { + PeripheralClockControl::enable(crate::system::Peripheral::Twai0); + } + fn enable_peripheral() { PeripheralClockControl::enable(crate::system::Peripheral::Twai0); } @@ -1563,6 +1575,10 @@ impl Instance for crate::peripherals::TWAI1 { unsafe { &*crate::peripherals::TWAI1::PTR } } + fn reset_peripheral() { + PeripheralClockControl::enable(crate::system::Peripheral::Twai1); + } + fn enable_peripheral() { PeripheralClockControl::enable(crate::system::Peripheral::Twai1); } diff --git a/esp-hal/src/usb_serial_jtag.rs b/esp-hal/src/usb_serial_jtag.rs index 70d6d2f06a3..fd615bded62 100644 --- a/esp-hal/src/usb_serial_jtag.rs +++ b/esp-hal/src/usb_serial_jtag.rs @@ -273,6 +273,7 @@ where M: Mode, { fn new_inner(_usb_device: impl Peripheral

+ 'd) -> Self { + PeripheralClockControl::reset(crate::system::Peripheral::UsbDevice); PeripheralClockControl::enable(crate::system::Peripheral::UsbDevice); USB_DEVICE::disable_tx_interrupts();