From bfbecdf93acd6f05f9d02477729defbd84a9bdeb Mon Sep 17 00:00:00 2001 From: Thomas Giesel Date: Sun, 29 Jun 2025 21:28:26 +0200 Subject: [PATCH] Use proper RCC clock enable for opamps new() now resets the opamp and enables its clock. The clock is disabled when the opamp is dropped. On families that use SYSCFGEN (F3 and G4), this is not done because this clock is always on in Embassy. This change makes use of the RCC driver, which uses a reference counter to prevent conflicts. The opamp itself is still disabled when its output is dropped. --- embassy-stm32/src/opamp.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs index 0467dbce3..e36719ef3 100644 --- a/embassy-stm32/src/opamp.rs +++ b/embassy-stm32/src/opamp.rs @@ -4,6 +4,8 @@ use embassy_hal_internal::PeripheralType; use crate::pac::opamp::vals::*; +#[cfg(not(any(stm32g4, stm32f3)))] +use crate::rcc::RccInfo; use crate::Peri; /// Performs a busy-wait delay for a specified number of microseconds. @@ -68,6 +70,8 @@ impl<'d, T: Instance> OpAmp<'d, T> { /// /// Does not enable the opamp, but does set the speed mode on some families. pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_v5)] speed: OpAmpSpeed) -> Self { + #[cfg(not(any(stm32g4, stm32f3)))] + T::info().rcc.enable_and_reset(); #[cfg(opamp_v5)] T::regs().csr().modify(|w| { w.set_opahsm(speed == OpAmpSpeed::HighSpeed); @@ -452,6 +456,13 @@ impl<'d, T: Instance> OpAmp<'d, T> { } } +#[cfg(not(any(stm32g4, stm32f3)))] +impl<'d, T: Instance> Drop for OpAmp<'d, T> { + fn drop(&mut self) { + T::info().rcc.disable(); + } +} + impl<'d, T: Instance> Drop for OpAmpOutput<'d, T> { fn drop(&mut self) { T::regs().csr().modify(|w| { @@ -469,7 +480,14 @@ impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> { } } +#[cfg(not(any(stm32g4, stm32f3)))] +pub(crate) struct Info { + rcc: RccInfo, +} + pub(crate) trait SealedInstance { + #[cfg(not(any(stm32g4, stm32f3)))] + fn info() -> &'static Info; fn regs() -> crate::pac::opamp::Opamp; } @@ -600,6 +618,15 @@ foreach_peripheral!( foreach_peripheral! { (opamp, $inst:ident) => { impl SealedInstance for crate::peripherals::$inst { + // G4 and F3 use SYSCFGEN, which is always enabled + #[cfg(not(any(stm32g4, stm32f3)))] + fn info() -> &'static Info { + use crate::rcc::SealedRccPeripheral; + static INFO: Info = Info { + rcc: crate::peripherals::$inst::RCC_INFO, + }; + &INFO + } fn regs() -> crate::pac::opamp::Opamp { crate::pac::$inst }