aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/opamp.rs
diff options
context:
space:
mode:
authorThomas Giesel <[email protected]>2025-06-29 21:28:26 +0200
committerThomas Giesel <[email protected]>2025-07-05 22:47:24 +0200
commitbfbecdf93acd6f05f9d02477729defbd84a9bdeb (patch)
treed2e3588c5d2575c9feed04e7de4a0548ee75ced8 /embassy-stm32/src/opamp.rs
parent06b160ac83b70b292ea92446a1eb69096b1c86ea (diff)
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.
Diffstat (limited to 'embassy-stm32/src/opamp.rs')
-rw-r--r--embassy-stm32/src/opamp.rs27
1 files changed, 27 insertions, 0 deletions
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 @@
4use embassy_hal_internal::PeripheralType; 4use embassy_hal_internal::PeripheralType;
5 5
6use crate::pac::opamp::vals::*; 6use crate::pac::opamp::vals::*;
7#[cfg(not(any(stm32g4, stm32f3)))]
8use crate::rcc::RccInfo;
7use crate::Peri; 9use crate::Peri;
8 10
9/// Performs a busy-wait delay for a specified number of microseconds. 11/// Performs a busy-wait delay for a specified number of microseconds.
@@ -68,6 +70,8 @@ impl<'d, T: Instance> OpAmp<'d, T> {
68 /// 70 ///
69 /// Does not enable the opamp, but does set the speed mode on some families. 71 /// Does not enable the opamp, but does set the speed mode on some families.
70 pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_v5)] speed: OpAmpSpeed) -> Self { 72 pub fn new(opamp: Peri<'d, T>, #[cfg(opamp_v5)] speed: OpAmpSpeed) -> Self {
73 #[cfg(not(any(stm32g4, stm32f3)))]
74 T::info().rcc.enable_and_reset();
71 #[cfg(opamp_v5)] 75 #[cfg(opamp_v5)]
72 T::regs().csr().modify(|w| { 76 T::regs().csr().modify(|w| {
73 w.set_opahsm(speed == OpAmpSpeed::HighSpeed); 77 w.set_opahsm(speed == OpAmpSpeed::HighSpeed);
@@ -452,6 +456,13 @@ impl<'d, T: Instance> OpAmp<'d, T> {
452 } 456 }
453} 457}
454 458
459#[cfg(not(any(stm32g4, stm32f3)))]
460impl<'d, T: Instance> Drop for OpAmp<'d, T> {
461 fn drop(&mut self) {
462 T::info().rcc.disable();
463 }
464}
465
455impl<'d, T: Instance> Drop for OpAmpOutput<'d, T> { 466impl<'d, T: Instance> Drop for OpAmpOutput<'d, T> {
456 fn drop(&mut self) { 467 fn drop(&mut self) {
457 T::regs().csr().modify(|w| { 468 T::regs().csr().modify(|w| {
@@ -469,7 +480,14 @@ impl<'d, T: Instance> Drop for OpAmpInternalOutput<'d, T> {
469 } 480 }
470} 481}
471 482
483#[cfg(not(any(stm32g4, stm32f3)))]
484pub(crate) struct Info {
485 rcc: RccInfo,
486}
487
472pub(crate) trait SealedInstance { 488pub(crate) trait SealedInstance {
489 #[cfg(not(any(stm32g4, stm32f3)))]
490 fn info() -> &'static Info;
473 fn regs() -> crate::pac::opamp::Opamp; 491 fn regs() -> crate::pac::opamp::Opamp;
474} 492}
475 493
@@ -600,6 +618,15 @@ foreach_peripheral!(
600foreach_peripheral! { 618foreach_peripheral! {
601 (opamp, $inst:ident) => { 619 (opamp, $inst:ident) => {
602 impl SealedInstance for crate::peripherals::$inst { 620 impl SealedInstance for crate::peripherals::$inst {
621 // G4 and F3 use SYSCFGEN, which is always enabled
622 #[cfg(not(any(stm32g4, stm32f3)))]
623 fn info() -> &'static Info {
624 use crate::rcc::SealedRccPeripheral;
625 static INFO: Info = Info {
626 rcc: crate::peripherals::$inst::RCC_INFO,
627 };
628 &INFO
629 }
603 fn regs() -> crate::pac::opamp::Opamp { 630 fn regs() -> crate::pac::opamp::Opamp {
604 crate::pac::$inst 631 crate::pac::$inst
605 } 632 }