From 6e24dc58c6395cc5d733d676986d3b336ce7a220 Mon Sep 17 00:00:00 2001
From: Andres Vahter <andres@vahter.me>
Date: Wed, 10 Apr 2024 16:47:58 +0300
Subject: [PATCH] stm32 adc: use fn blocking_delay_us(us: u32)

---
 embassy-stm32/src/adc/f1.rs  | 13 +++----------
 embassy-stm32/src/adc/f3.rs  | 12 +++---------
 embassy-stm32/src/adc/mod.rs |  9 +++++++++
 embassy-stm32/src/adc/v1.rs  | 16 ++++------------
 embassy-stm32/src/adc/v2.rs  |  6 ++----
 embassy-stm32/src/adc/v3.rs  | 16 ++++------------
 embassy-stm32/src/adc/v4.rs  | 12 +++---------
 7 files changed, 28 insertions(+), 56 deletions(-)

diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index dd4b3489b..80eaecc14 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -4,6 +4,7 @@ use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
 
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcPin, Instance, SampleTime};
 use crate::time::Hertz;
 use crate::{interrupt, Peripheral};
@@ -54,11 +55,7 @@ impl<'d, T: Instance> Adc<'d, T> {
 
         // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’)
         // for at least two ADC clock cycles.
-        let us = (1_000_000 * 2) / Self::freq().0 + 1;
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(us));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / (1000_000 / us));
+        blocking_delay_us((1_000_000 * 2) / Self::freq().0 + 1);
 
         // Reset calibration
         T::regs().cr2().modify(|reg| reg.set_rstcal(true));
@@ -73,11 +70,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         }
 
         // One cycle after calibration
-        let us = (1_000_000 * 1) / Self::freq().0 + 1;
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(us));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / (1000_000 / us));
+        blocking_delay_us((1_000_000 * 1) / Self::freq().0 + 1);
 
         Self {
             adc,
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 1a62b7707..c22a3fe4a 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -4,6 +4,7 @@ use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
 
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcPin, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::time::Hertz;
@@ -69,10 +70,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::ENABLED));
 
         // Wait for the regulator to stabilize
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(10));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 100_000);
+        blocking_delay_us(10);
 
         assert!(!T::regs().cr().read().aden());
 
@@ -83,11 +81,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         while T::regs().cr().read().adcal() {}
 
         // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223).
-        let us = (1_000_000 * 4) / Self::freq().0 + 1;
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(us));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / (1000_000 / us));
+        blocking_delay_us((1_000_000 * 4) / Self::freq().0 + 1);
 
         // Enable the adc
         T::regs().cr().modify(|w| w.set_aden(true));
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index ead2357ce..24dd7cc3c 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -69,6 +69,15 @@ trait SealedInternalChannel<T> {
     fn channel(&self) -> u8;
 }
 
+/// Performs a busy-wait delay for a specified number of microseconds.
+#[allow(unused)]
+pub(crate) fn blocking_delay_us(us: u32) {
+    #[cfg(time)]
+    embassy_time::block_for(embassy_time::Duration::from_micros(us));
+    #[cfg(not(time))]
+    cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 * us / 1_000_000);
+}
+
 /// ADC instance.
 #[cfg(not(any(adc_f1, adc_v1, adc_l0, adc_v2, adc_v3, adc_v4, adc_f3, adc_f3_v1_1, adc_g0, adc_h5)))]
 #[allow(private_bounds)]
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index 960990c39..1dda28cf2 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -6,6 +6,7 @@ use embassy_hal_internal::into_ref;
 #[cfg(adc_l0)]
 use stm32_metapac::adc::vals::Ckmode;
 
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
 use crate::peripherals::ADC;
@@ -72,10 +73,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         //
         // Table 57. ADC characteristics
         // tstab = 14 * 1/fadc
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(1));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 1000_000);
+        blocking_delay_us(1);
 
         // set default PCKL/2 on L0s because HSI is disabled in the default clock config
         #[cfg(adc_l0)]
@@ -128,10 +126,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         // Table 28. Embedded internal reference voltage
         // tstart = 10μs
         T::regs().ccr().modify(|reg| reg.set_vrefen(true));
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(10));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 100_000);
+        blocking_delay_us(10);
         Vref
     }
 
@@ -142,10 +137,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         // tstart ≤ 10μs
         // ts_temp ≥ 4μs
         T::regs().ccr().modify(|reg| reg.set_tsen(true));
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(10));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 100_000);
+        blocking_delay_us(10);
         Temperature
     }
 
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 1ac119508..7771cf768 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,5 +1,6 @@
 use embassy_hal_internal::into_ref;
 
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
 use crate::peripherals::ADC1;
 use crate::time::Hertz;
@@ -103,10 +104,7 @@ where
             reg.set_adon(true);
         });
 
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(5));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 200_000);
+        blocking_delay_us(3);
 
         Self {
             adc,
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index a5e09646a..4fd8558ba 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,6 +1,7 @@
 use cfg_if::cfg_if;
 use embassy_hal_internal::into_ref;
 
+use super::blocking_delay_us;
 use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
 use crate::Peripheral;
 
@@ -87,10 +88,7 @@ impl<'d, T: Instance> Adc<'d, T> {
             reg.set_chselrmod(false);
         });
 
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(20));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 50_000);
+        blocking_delay_us(20);
 
         T::regs().cr().modify(|reg| {
             reg.set_adcal(true);
@@ -100,10 +98,7 @@ impl<'d, T: Instance> Adc<'d, T> {
             // spin
         }
 
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(1));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 1000_000);
+        blocking_delay_us(1);
 
         Self {
             adc,
@@ -123,10 +118,7 @@ impl<'d, T: Instance> Adc<'d, T> {
 
         // "Table 24. Embedded internal voltage reference" states that it takes a maximum of 12 us
         // to stabilize the internal voltage reference.
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(20));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 50_000);
+        blocking_delay_us(15);
 
         VrefInt {}
     }
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 018104dd6..ca87b41ee 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -2,7 +2,7 @@
 use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
 use pac::adccommon::vals::Presc;
 
-use super::{Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
+use super::{blocking_delay_us, Adc, AdcPin, Instance, InternalChannel, Resolution, SampleTime};
 use crate::time::Hertz;
 use crate::{pac, Peripheral};
 
@@ -164,10 +164,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         s.configure_differential_inputs();
 
         s.calibrate();
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(1));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 1000_000);
+        blocking_delay_us(1);
 
         s.enable();
         s.configure();
@@ -181,10 +178,7 @@ impl<'d, T: Instance> Adc<'d, T> {
             reg.set_advregen(true);
         });
 
-        #[cfg(time)]
-        embassy_time::block_for(embassy_time::Duration::from_micros(10));
-        #[cfg(not(time))]
-        cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 100_000);
+        blocking_delay_us(10);
     }
 
     fn configure_differential_inputs(&mut self) {