diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index 2dbce8043..dd4b3489b 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -3,7 +3,6 @@ use core::marker::PhantomData;
 use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
-use embedded_hal_1::delay::DelayNs;
 
 use crate::adc::{Adc, AdcPin, Instance, SampleTime};
 use crate::time::Hertz;
@@ -48,14 +47,18 @@ impl<T: Instance> super::SealedAdcPin<T> for Temperature {
 }
 
 impl<'d, T: Instance> Adc<'d, T> {
-    pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayNs) -> Self {
+    pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
         into_ref!(adc);
         T::enable_and_reset();
         T::regs().cr2().modify(|reg| reg.set_adon(true));
 
         // 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
-        delay.delay_us((1_000_000 * 2) / Self::freq().0 + 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));
 
         // Reset calibration
         T::regs().cr2().modify(|reg| reg.set_rstcal(true));
@@ -70,7 +73,11 @@ impl<'d, T: Instance> Adc<'d, T> {
         }
 
         // One cycle after calibration
-        delay.delay_us((1_000_000) / Self::freq().0 + 1);
+        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));
 
         Self {
             adc,
@@ -95,7 +102,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         }
     }
 
-    pub fn enable_vref(&self, _delay: &mut impl DelayNs) -> Vref {
+    pub fn enable_vref(&self) -> Vref {
         T::regs().cr2().modify(|reg| {
             reg.set_tsvrefe(true);
         });
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 4ffbe5bf1..1a62b7707 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -3,7 +3,6 @@ use core::marker::PhantomData;
 use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
-use embedded_hal_1::delay::DelayNs;
 
 use crate::adc::{Adc, AdcPin, Instance, SampleTime};
 use crate::interrupt::typelevel::Interrupt;
@@ -58,7 +57,6 @@ impl<'d, T: Instance> Adc<'d, T> {
     pub fn new(
         adc: impl Peripheral<P = T> + 'd,
         _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
-        delay: &mut impl DelayNs,
     ) -> Self {
         use crate::pac::adc::vals;
 
@@ -71,7 +69,10 @@ impl<'d, T: Instance> Adc<'d, T> {
         T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::ENABLED));
 
         // Wait for the regulator to stabilize
-        delay.delay_us(10);
+        #[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);
 
         assert!(!T::regs().cr().read().aden());
 
@@ -81,8 +82,12 @@ 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)
-        delay.delay_us(1 + (6 * 1_000_000 / Self::freq().0));
+        // 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));
 
         // Enable the adc
         T::regs().cr().modify(|w| w.set_aden(true));
@@ -117,7 +122,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         }
     }
 
-    pub fn enable_vref(&self, _delay: &mut impl DelayNs) -> Vref {
+    pub fn enable_vref(&self) -> Vref {
         T::common_regs().ccr().modify(|w| w.set_vrefen(true));
 
         Vref {}
diff --git a/embassy-stm32/src/adc/v1.rs b/embassy-stm32/src/adc/v1.rs
index 3099b47d1..960990c39 100644
--- a/embassy-stm32/src/adc/v1.rs
+++ b/embassy-stm32/src/adc/v1.rs
@@ -3,7 +3,6 @@ use core::marker::PhantomData;
 use core::task::Poll;
 
 use embassy_hal_internal::into_ref;
-use embedded_hal_1::delay::DelayNs;
 #[cfg(adc_l0)]
 use stm32_metapac::adc::vals::Ckmode;
 
@@ -65,7 +64,6 @@ impl<'d, T: Instance> Adc<'d, T> {
     pub fn new(
         adc: impl Peripheral<P = T> + 'd,
         _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
-        delay: &mut impl DelayNs,
     ) -> Self {
         into_ref!(adc);
         T::enable_and_reset();
@@ -74,7 +72,10 @@ impl<'d, T: Instance> Adc<'d, T> {
         //
         // Table 57. ADC characteristics
         // tstab = 14 * 1/fadc
-        delay.delay_us(1);
+        #[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);
 
         // set default PCKL/2 on L0s because HSI is disabled in the default clock config
         #[cfg(adc_l0)]
@@ -114,7 +115,7 @@ impl<'d, T: Instance> Adc<'d, T> {
     }
 
     #[cfg(not(adc_l0))]
-    pub fn enable_vbat(&self, _delay: &mut impl DelayNs) -> Vbat {
+    pub fn enable_vbat(&self) -> Vbat {
         // SMP must be ≥ 56 ADC clock cycles when using HSI14.
         //
         // 6.3.20 Vbat monitoring characteristics
@@ -123,22 +124,28 @@ impl<'d, T: Instance> Adc<'d, T> {
         Vbat
     }
 
-    pub fn enable_vref(&self, delay: &mut impl DelayNs) -> Vref {
+    pub fn enable_vref(&self) -> Vref {
         // Table 28. Embedded internal reference voltage
         // tstart = 10μs
         T::regs().ccr().modify(|reg| reg.set_vrefen(true));
-        delay.delay_us(10);
+        #[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);
         Vref
     }
 
-    pub fn enable_temperature(&self, delay: &mut impl DelayNs) -> Temperature {
+    pub fn enable_temperature(&self) -> Temperature {
         // SMP must be ≥ 56 ADC clock cycles when using HSI14.
         //
         // 6.3.19 Temperature sensor characteristics
         // tstart ≤ 10μs
         // ts_temp ≥ 4μs
         T::regs().ccr().modify(|reg| reg.set_tsen(true));
-        delay.delay_us(10);
+        #[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);
         Temperature
     }
 
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 21782cf89..1ac119508 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -1,5 +1,4 @@
 use embassy_hal_internal::into_ref;
-use embedded_hal_1::delay::DelayNs;
 
 use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
 use crate::peripherals::ADC1;
@@ -11,9 +10,6 @@ pub const VREF_DEFAULT_MV: u32 = 3300;
 /// VREF voltage used for factory calibration of VREFINTCAL register.
 pub const VREF_CALIB_MV: u32 = 3300;
 
-/// ADC turn-on time
-pub const ADC_POWERUP_TIME_US: u32 = 3;
-
 pub struct VrefInt;
 impl AdcPin<ADC1> for VrefInt {}
 impl super::SealedAdcPin<ADC1> for VrefInt {
@@ -97,7 +93,7 @@ impl<'d, T> Adc<'d, T>
 where
     T: Instance,
 {
-    pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayNs) -> Self {
+    pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
         into_ref!(adc);
         T::enable_and_reset();
 
@@ -107,7 +103,10 @@ where
             reg.set_adon(true);
         });
 
-        delay.delay_us(ADC_POWERUP_TIME_US);
+        #[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);
 
         Self {
             adc,
diff --git a/embassy-stm32/src/adc/v3.rs b/embassy-stm32/src/adc/v3.rs
index ba01e71fd..a5e09646a 100644
--- a/embassy-stm32/src/adc/v3.rs
+++ b/embassy-stm32/src/adc/v3.rs
@@ -1,6 +1,5 @@
 use cfg_if::cfg_if;
 use embassy_hal_internal::into_ref;
-use embedded_hal_1::delay::DelayNs;
 
 use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
 use crate::Peripheral;
@@ -74,7 +73,7 @@ cfg_if! {
 }
 
 impl<'d, T: Instance> Adc<'d, T> {
-    pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayNs) -> Self {
+    pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
         into_ref!(adc);
         T::enable_and_reset();
         T::regs().cr().modify(|reg| {
@@ -88,7 +87,10 @@ impl<'d, T: Instance> Adc<'d, T> {
             reg.set_chselrmod(false);
         });
 
-        delay.delay_us(20);
+        #[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);
 
         T::regs().cr().modify(|reg| {
             reg.set_adcal(true);
@@ -98,7 +100,10 @@ impl<'d, T: Instance> Adc<'d, T> {
             // spin
         }
 
-        delay.delay_us(1);
+        #[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);
 
         Self {
             adc,
@@ -106,7 +111,7 @@ impl<'d, T: Instance> Adc<'d, T> {
         }
     }
 
-    pub fn enable_vrefint(&self, delay: &mut impl DelayNs) -> VrefInt {
+    pub fn enable_vrefint(&self) -> VrefInt {
         #[cfg(not(adc_g0))]
         T::common_regs().ccr().modify(|reg| {
             reg.set_vrefen(true);
@@ -117,10 +122,11 @@ 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, we wait a little more.
-        // TODO: delay 15us
-        //cortex_m::asm::delay(20_000_000);
-        delay.delay_us(15);
+        // 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);
 
         VrefInt {}
     }
diff --git a/embassy-stm32/src/adc/v4.rs b/embassy-stm32/src/adc/v4.rs
index 4320de714..018104dd6 100644
--- a/embassy-stm32/src/adc/v4.rs
+++ b/embassy-stm32/src/adc/v4.rs
@@ -1,4 +1,3 @@
-use embedded_hal_1::delay::DelayNs;
 #[allow(unused)]
 use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
 use pac::adccommon::vals::Presc;
@@ -129,7 +128,7 @@ impl Prescaler {
 
 impl<'d, T: Instance> Adc<'d, T> {
     /// Create a new ADC driver.
-    pub fn new(adc: impl Peripheral<P = T> + 'd, delay: &mut impl DelayNs) -> Self {
+    pub fn new(adc: impl Peripheral<P = T> + 'd) -> Self {
         embassy_hal_internal::into_ref!(adc);
         T::enable_and_reset();
 
@@ -161,11 +160,14 @@ impl<'d, T: Instance> Adc<'d, T> {
             adc,
             sample_time: SampleTime::from_bits(0),
         };
-        s.power_up(delay);
+        s.power_up();
         s.configure_differential_inputs();
 
         s.calibrate();
-        delay.delay_us(1);
+        #[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);
 
         s.enable();
         s.configure();
@@ -173,13 +175,16 @@ impl<'d, T: Instance> Adc<'d, T> {
         s
     }
 
-    fn power_up(&mut self, delay: &mut impl DelayNs) {
+    fn power_up(&mut self) {
         T::regs().cr().modify(|reg| {
             reg.set_deeppwd(false);
             reg.set_advregen(true);
         });
 
-        delay.delay_us(10);
+        #[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);
     }
 
     fn configure_differential_inputs(&mut self) {