stm32 adc: use fn blocking_delay_us(us: u32)

This commit is contained in:
Andres Vahter 2024-04-10 16:47:58 +03:00
parent fd901fc7e0
commit 6e24dc58c6
7 changed files with 28 additions and 56 deletions

View File

@ -4,6 +4,7 @@ use core::task::Poll;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use super::blocking_delay_us;
use crate::adc::{Adc, AdcPin, Instance, SampleTime}; use crate::adc::{Adc, AdcPin, Instance, SampleTime};
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, Peripheral}; 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) // 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. // for at least two ADC clock cycles.
let us = (1_000_000 * 2) / Self::freq().0 + 1; blocking_delay_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 // Reset calibration
T::regs().cr2().modify(|reg| reg.set_rstcal(true)); T::regs().cr2().modify(|reg| reg.set_rstcal(true));
@ -73,11 +70,7 @@ impl<'d, T: Instance> Adc<'d, T> {
} }
// One cycle after calibration // One cycle after calibration
let us = (1_000_000 * 1) / Self::freq().0 + 1; blocking_delay_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 { Self {
adc, adc,

View File

@ -4,6 +4,7 @@ use core::task::Poll;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use super::blocking_delay_us;
use crate::adc::{Adc, AdcPin, Instance, SampleTime}; use crate::adc::{Adc, AdcPin, Instance, SampleTime};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::time::Hertz; 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)); T::regs().cr().modify(|w| w.set_advregen(vals::Advregen::ENABLED));
// Wait for the regulator to stabilize // Wait for the regulator to stabilize
#[cfg(time)] blocking_delay_us(10);
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()); assert!(!T::regs().cr().read().aden());
@ -83,11 +81,7 @@ impl<'d, T: Instance> Adc<'d, T> {
while T::regs().cr().read().adcal() {} while T::regs().cr().read().adcal() {}
// Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223). // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223).
let us = (1_000_000 * 4) / Self::freq().0 + 1; blocking_delay_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 // Enable the adc
T::regs().cr().modify(|w| w.set_aden(true)); T::regs().cr().modify(|w| w.set_aden(true));

View File

@ -69,6 +69,15 @@ trait SealedInternalChannel<T> {
fn channel(&self) -> u8; 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. /// 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)))] #[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)] #[allow(private_bounds)]

View File

@ -6,6 +6,7 @@ use embassy_hal_internal::into_ref;
#[cfg(adc_l0)] #[cfg(adc_l0)]
use stm32_metapac::adc::vals::Ckmode; use stm32_metapac::adc::vals::Ckmode;
use super::blocking_delay_us;
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::peripherals::ADC; use crate::peripherals::ADC;
@ -72,10 +73,7 @@ impl<'d, T: Instance> Adc<'d, T> {
// //
// Table 57. ADC characteristics // Table 57. ADC characteristics
// tstab = 14 * 1/fadc // tstab = 14 * 1/fadc
#[cfg(time)] blocking_delay_us(1);
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 // set default PCKL/2 on L0s because HSI is disabled in the default clock config
#[cfg(adc_l0)] #[cfg(adc_l0)]
@ -128,10 +126,7 @@ impl<'d, T: Instance> Adc<'d, T> {
// Table 28. Embedded internal reference voltage // Table 28. Embedded internal reference voltage
// tstart = 10μs // tstart = 10μs
T::regs().ccr().modify(|reg| reg.set_vrefen(true)); T::regs().ccr().modify(|reg| reg.set_vrefen(true));
#[cfg(time)] blocking_delay_us(10);
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 Vref
} }
@ -142,10 +137,7 @@ impl<'d, T: Instance> Adc<'d, T> {
// tstart ≤ 10μs // tstart ≤ 10μs
// ts_temp ≥ 4μs // ts_temp ≥ 4μs
T::regs().ccr().modify(|reg| reg.set_tsen(true)); T::regs().ccr().modify(|reg| reg.set_tsen(true));
#[cfg(time)] blocking_delay_us(10);
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 Temperature
} }

View File

@ -1,5 +1,6 @@
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use super::blocking_delay_us;
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
use crate::peripherals::ADC1; use crate::peripherals::ADC1;
use crate::time::Hertz; use crate::time::Hertz;
@ -103,10 +104,7 @@ where
reg.set_adon(true); reg.set_adon(true);
}); });
#[cfg(time)] blocking_delay_us(3);
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 { Self {
adc, adc,

View File

@ -1,6 +1,7 @@
use cfg_if::cfg_if; use cfg_if::cfg_if;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use super::blocking_delay_us;
use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime}; use crate::adc::{Adc, AdcPin, Instance, Resolution, SampleTime};
use crate::Peripheral; use crate::Peripheral;
@ -87,10 +88,7 @@ impl<'d, T: Instance> Adc<'d, T> {
reg.set_chselrmod(false); reg.set_chselrmod(false);
}); });
#[cfg(time)] blocking_delay_us(20);
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| { T::regs().cr().modify(|reg| {
reg.set_adcal(true); reg.set_adcal(true);
@ -100,10 +98,7 @@ impl<'d, T: Instance> Adc<'d, T> {
// spin // spin
} }
#[cfg(time)] blocking_delay_us(1);
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 { Self {
adc, 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 // "Table 24. Embedded internal voltage reference" states that it takes a maximum of 12 us
// to stabilize the internal voltage reference. // to stabilize the internal voltage reference.
#[cfg(time)] blocking_delay_us(15);
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 {} VrefInt {}
} }

View File

@ -2,7 +2,7 @@
use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel}; use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
use pac::adccommon::vals::Presc; 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::time::Hertz;
use crate::{pac, Peripheral}; use crate::{pac, Peripheral};
@ -164,10 +164,7 @@ impl<'d, T: Instance> Adc<'d, T> {
s.configure_differential_inputs(); s.configure_differential_inputs();
s.calibrate(); s.calibrate();
#[cfg(time)] blocking_delay_us(1);
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.enable();
s.configure(); s.configure();
@ -181,10 +178,7 @@ impl<'d, T: Instance> Adc<'d, T> {
reg.set_advregen(true); reg.set_advregen(true);
}); });
#[cfg(time)] blocking_delay_us(10);
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) { fn configure_differential_inputs(&mut self) {