aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-13 20:47:03 +0000
committerGitHub <[email protected]>2025-11-13 20:47:03 +0000
commit578679771eafe93ccc0e8de8fc3f97a5b991b02c (patch)
treecdd70520cbcc10a4b2f01c698723c5fe7d1bff2f
parente18ae87c3ad7ca08d1ee613b5748e51d72fe0681 (diff)
parent64b9c28eca4822a3ba1bd07d20964c2291c01cf5 (diff)
Merge pull request #4881 from xoviat/blocking-delay
stm32: extract block_for_us
-rw-r--r--embassy-stm32/src/adc/c0.rs2
-rw-r--r--embassy-stm32/src/adc/f1.rs4
-rw-r--r--embassy-stm32/src/adc/f3.rs2
-rw-r--r--embassy-stm32/src/adc/mod.rs20
-rw-r--r--embassy-stm32/src/dsihost.rs17
-rw-r--r--embassy-stm32/src/eth/generic_phy.rs14
-rw-r--r--embassy-stm32/src/lib.rs14
-rw-r--r--embassy-stm32/src/opamp.rs13
-rw-r--r--examples/stm32f469/src/bin/dsi_bsp.rs14
9 files changed, 36 insertions, 64 deletions
diff --git a/embassy-stm32/src/adc/c0.rs b/embassy-stm32/src/adc/c0.rs
index 983e7c10d..3bdca7edb 100644
--- a/embassy-stm32/src/adc/c0.rs
+++ b/embassy-stm32/src/adc/c0.rs
@@ -223,7 +223,7 @@ impl<'d, T: AnyInstance> Adc<'d, T> {
223 223
224 // "The software must wait for the ADC voltage regulator startup time." 224 // "The software must wait for the ADC voltage regulator startup time."
225 // See datasheet for the value. 225 // See datasheet for the value.
226 blocking_delay_us(TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US + 1); 226 blocking_delay_us(TIME_ADC_VOLTAGE_REGUALTOR_STARTUP_US as u64 + 1);
227 227
228 T::regs().cfgr1().modify(|reg| reg.set_res(resolution)); 228 T::regs().cfgr1().modify(|reg| reg.set_res(resolution));
229 229
diff --git a/embassy-stm32/src/adc/f1.rs b/embassy-stm32/src/adc/f1.rs
index f6220de78..d6c6f480b 100644
--- a/embassy-stm32/src/adc/f1.rs
+++ b/embassy-stm32/src/adc/f1.rs
@@ -43,7 +43,7 @@ impl<'d, T: Instance> Adc<'d, T> {
43 43
44 // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’) 44 // 11.4: Before starting a calibration, the ADC must have been in power-on state (ADON bit = ‘1’)
45 // for at least two ADC clock cycles. 45 // for at least two ADC clock cycles.
46 blocking_delay_us((1_000_000 * 2) / Self::freq().0 + 1); 46 blocking_delay_us((1_000_000 * 2) / Self::freq().0 as u64 + 1);
47 47
48 // Reset calibration 48 // Reset calibration
49 T::regs().cr2().modify(|reg| reg.set_rstcal(true)); 49 T::regs().cr2().modify(|reg| reg.set_rstcal(true));
@@ -58,7 +58,7 @@ impl<'d, T: Instance> Adc<'d, T> {
58 } 58 }
59 59
60 // One cycle after calibration 60 // One cycle after calibration
61 blocking_delay_us((1_000_000 * 1) / Self::freq().0 + 1); 61 blocking_delay_us((1_000_000 * 1) / Self::freq().0 as u64 + 1);
62 62
63 T::Interrupt::unpend(); 63 T::Interrupt::unpend();
64 unsafe { T::Interrupt::enable() }; 64 unsafe { T::Interrupt::enable() };
diff --git a/embassy-stm32/src/adc/f3.rs b/embassy-stm32/src/adc/f3.rs
index 4a77f3c5b..29bfdac97 100644
--- a/embassy-stm32/src/adc/f3.rs
+++ b/embassy-stm32/src/adc/f3.rs
@@ -62,7 +62,7 @@ impl<'d, T: Instance> Adc<'d, T> {
62 while T::regs().cr().read().adcal() {} 62 while T::regs().cr().read().adcal() {}
63 63
64 // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223). 64 // Wait more than 4 clock cycles after adcal is cleared (RM0364 p. 223).
65 blocking_delay_us((1_000_000 * 4) / Self::freq().0 + 1); 65 blocking_delay_us((1_000_000 * 4) / Self::freq().0 as u64 + 1);
66 66
67 // Enable the adc 67 // Enable the adc
68 T::regs().cr().modify(|w| w.set_aden(true)); 68 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 549f2f5a5..5ec08a22d 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -35,6 +35,8 @@ pub use ringbuffered::RingBufferedAdc;
35#[path = "adc4.rs"] 35#[path = "adc4.rs"]
36pub mod adc4; 36pub mod adc4;
37 37
38#[allow(unused)]
39pub(self) use crate::block_for_us as blocking_delay_us;
38pub use crate::pac::adc::vals; 40pub use crate::pac::adc::vals;
39#[cfg(not(any(adc_f1, adc_f3v3)))] 41#[cfg(not(any(adc_f1, adc_f3v3)))]
40pub use crate::pac::adc::vals::Res as Resolution; 42pub use crate::pac::adc::vals::Res as Resolution;
@@ -140,24 +142,6 @@ impl<T: SealedAnyInstance + Instance> BasicAnyInstance for T {
140))] 142))]
141impl<T: SealedAnyInstance + Instance> AnyInstance for T {} 143impl<T: SealedAnyInstance + Instance> AnyInstance for T {}
142 144
143/// Performs a busy-wait delay for a specified number of microseconds.
144#[allow(unused)]
145pub(crate) fn blocking_delay_us(us: u32) {
146 cfg_if::cfg_if! {
147 // this does strange things on stm32wlx in low power mode depending on exactly when it's called
148 // as in sometimes 15 us (1 tick) would take > 20 seconds.
149 if #[cfg(all(feature = "time", all(not(feature = "low-power"), not(stm32wlex))))] {
150 let duration = embassy_time::Duration::from_micros(us as u64);
151 embassy_time::block_for(duration);
152 } else {
153 let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64;
154 let us = us as u64;
155 let cycles = freq * us / 1_000_000;
156 cortex_m::asm::delay(cycles as u32);
157 }
158 }
159}
160
161#[cfg(any(adc_c0, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5))] 145#[cfg(any(adc_c0, adc_v3, adc_g0, adc_h5, adc_h7rs, adc_u0, adc_v4, adc_u5))]
162/// Number of samples used for averaging. 146/// Number of samples used for averaging.
163#[derive(Copy, Clone, Debug)] 147#[derive(Copy, Clone, Debug)]
diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs
index 59a2cbcdb..b8945820c 100644
--- a/embassy-stm32/src/dsihost.rs
+++ b/embassy-stm32/src/dsihost.rs
@@ -5,18 +5,11 @@ use core::marker::PhantomData;
5use embassy_hal_internal::PeripheralType; 5use embassy_hal_internal::PeripheralType;
6 6
7//use crate::gpio::{AnyPin, SealedPin}; 7//use crate::gpio::{AnyPin, SealedPin};
8use crate::block_for_us;
8use crate::gpio::{AfType, AnyPin, OutputType, Speed}; 9use crate::gpio::{AfType, AnyPin, OutputType, Speed};
9use crate::rcc::{self, RccPeripheral}; 10use crate::rcc::{self, RccPeripheral};
10use crate::{Peri, peripherals}; 11use crate::{Peri, peripherals};
11 12
12/// Performs a busy-wait delay for a specified number of microseconds.
13pub fn blocking_delay_ms(ms: u32) {
14 #[cfg(feature = "time")]
15 embassy_time::block_for(embassy_time::Duration::from_millis(ms as u64));
16 #[cfg(not(feature = "time"))]
17 cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 / 1_000 * ms);
18}
19
20/// PacketTypes extracted from CubeMX 13/// PacketTypes extracted from CubeMX
21#[repr(u8)] 14#[repr(u8)]
22#[allow(dead_code)] 15#[allow(dead_code)]
@@ -334,7 +327,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
334 if T::regs().gpsr().read().cmdfe() { 327 if T::regs().gpsr().read().cmdfe() {
335 return Ok(()); 328 return Ok(());
336 } 329 }
337 blocking_delay_ms(1); 330 block_for_us(1_000);
338 } 331 }
339 Err(Error::FifoTimeout) 332 Err(Error::FifoTimeout)
340 } 333 }
@@ -345,7 +338,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
345 if !T::regs().gpsr().read().cmdff() { 338 if !T::regs().gpsr().read().cmdff() {
346 return Ok(()); 339 return Ok(());
347 } 340 }
348 blocking_delay_ms(1); 341 block_for_us(1_000);
349 } 342 }
350 Err(Error::FifoTimeout) 343 Err(Error::FifoTimeout)
351 } 344 }
@@ -356,7 +349,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
356 if !self.read_busy() { 349 if !self.read_busy() {
357 return Ok(()); 350 return Ok(());
358 } 351 }
359 blocking_delay_ms(1); 352 block_for_us(1_000);
360 } 353 }
361 Err(Error::ReadTimeout) 354 Err(Error::ReadTimeout)
362 } 355 }
@@ -367,7 +360,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
367 if !T::regs().gpsr().read().prdfe() { 360 if !T::regs().gpsr().read().prdfe() {
368 return Ok(()); 361 return Ok(());
369 } 362 }
370 blocking_delay_ms(1); 363 block_for_us(1_000);
371 } 364 }
372 Err(Error::FifoTimeout) 365 Err(Error::FifoTimeout)
373 } 366 }
diff --git a/embassy-stm32/src/eth/generic_phy.rs b/embassy-stm32/src/eth/generic_phy.rs
index 774beef80..947874d7f 100644
--- a/embassy-stm32/src/eth/generic_phy.rs
+++ b/embassy-stm32/src/eth/generic_phy.rs
@@ -8,6 +8,7 @@ use embassy_time::{Duration, Timer};
8use futures_util::FutureExt; 8use futures_util::FutureExt;
9 9
10use super::{Phy, StationManagement}; 10use super::{Phy, StationManagement};
11use crate::block_for_us as blocking_delay_us;
11 12
12#[allow(dead_code)] 13#[allow(dead_code)]
13mod phy_consts { 14mod phy_consts {
@@ -76,19 +77,6 @@ impl GenericPhy {
76 } 77 }
77} 78}
78 79
79// TODO: Factor out to shared functionality
80fn blocking_delay_us(us: u32) {
81 #[cfg(feature = "time")]
82 embassy_time::block_for(Duration::from_micros(us as u64));
83 #[cfg(not(feature = "time"))]
84 {
85 let freq = unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 as u64;
86 let us = us as u64;
87 let cycles = freq * us / 1_000_000;
88 cortex_m::asm::delay(cycles as u32);
89 }
90}
91
92impl Phy for GenericPhy { 80impl Phy for GenericPhy {
93 fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) { 81 fn phy_reset<S: StationManagement>(&mut self, sm: &mut S) {
94 // Detect SMI address 82 // Detect SMI address
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 680edf433..6e492946a 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -658,3 +658,17 @@ fn init_hw(config: Config) -> Peripherals {
658 p 658 p
659 }) 659 })
660} 660}
661
662/// Performs a busy-wait delay for a specified number of microseconds.
663#[allow(unused)]
664pub(crate) fn block_for_us(us: u64) {
665 cfg_if::cfg_if! {
666 // this does strange things on stm32wlx in low power mode depending on exactly when it's called
667 // as in sometimes 15 us (1 tick) would take > 20 seconds.
668 if #[cfg(all(feature = "time", all(not(feature = "low-power"), not(stm32wlex))))] {
669 embassy_time::block_for(embassy_time::Duration::from_micros(us));
670 } else {
671 cortex_m::asm::delay(unsafe { rcc::get_freqs().sys.to_hertz().unwrap().0 as u64 * us / 1_000_000 } as u32);
672 }
673 }
674}
diff --git a/embassy-stm32/src/opamp.rs b/embassy-stm32/src/opamp.rs
index ac8d5de21..4a55f5bd3 100644
--- a/embassy-stm32/src/opamp.rs
+++ b/embassy-stm32/src/opamp.rs
@@ -4,19 +4,12 @@
4use embassy_hal_internal::PeripheralType; 4use embassy_hal_internal::PeripheralType;
5 5
6use crate::Peri; 6use crate::Peri;
7#[cfg(opamp_v5)]
8use crate::block_for_us;
7use crate::pac::opamp::vals::*; 9use crate::pac::opamp::vals::*;
8#[cfg(not(any(stm32g4, stm32f3)))] 10#[cfg(not(any(stm32g4, stm32f3)))]
9use crate::rcc::RccInfo; 11use crate::rcc::RccInfo;
10 12
11/// Performs a busy-wait delay for a specified number of microseconds.
12#[cfg(opamp_v5)]
13fn blocking_delay_ms(ms: u32) {
14 #[cfg(feature = "time")]
15 embassy_time::block_for(embassy_time::Duration::from_millis(ms as u64));
16 #[cfg(not(feature = "time"))]
17 cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.to_hertz().unwrap().0 / 1_000 * ms);
18}
19
20/// Gain 13/// Gain
21#[allow(missing_docs)] 14#[allow(missing_docs)]
22#[derive(Clone, Copy)] 15#[derive(Clone, Copy)]
@@ -439,7 +432,7 @@ impl<'d, T: Instance> OpAmp<'d, T> {
439 432
440 // The closer the trimming value is to the optimum trimming value, the longer it takes to stabilize 433 // The closer the trimming value is to the optimum trimming value, the longer it takes to stabilize
441 // (with a maximum stabilization time remaining below 2 ms in any case) -- RM0440 25.3.7 434 // (with a maximum stabilization time remaining below 2 ms in any case) -- RM0440 25.3.7
442 blocking_delay_ms(2); 435 block_for_us(2_000);
443 436
444 if !T::regs().csr().read().calout() { 437 if !T::regs().csr().read().calout() {
445 if mid == 0 { 438 if mid == 0 {
diff --git a/examples/stm32f469/src/bin/dsi_bsp.rs b/examples/stm32f469/src/bin/dsi_bsp.rs
index d659291ff..7ba4da72b 100644
--- a/examples/stm32f469/src/bin/dsi_bsp.rs
+++ b/examples/stm32f469/src/bin/dsi_bsp.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::dsihost::{DsiHost, PacketType, blocking_delay_ms}; 6use embassy_stm32::dsihost::{DsiHost, PacketType};
7use embassy_stm32::gpio::{Level, Output, Speed}; 7use embassy_stm32::gpio::{Level, Output, Speed};
8use embassy_stm32::ltdc::Ltdc; 8use embassy_stm32::ltdc::Ltdc;
9use embassy_stm32::pac::dsihost::regs::{Ier0, Ier1}; 9use embassy_stm32::pac::dsihost::regs::{Ier0, Ier1};
@@ -13,7 +13,7 @@ use embassy_stm32::rcc::{
13 AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk, 13 AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, PllPreDiv, PllQDiv, PllRDiv, PllSource, Sysclk,
14}; 14};
15use embassy_stm32::time::mhz; 15use embassy_stm32::time::mhz;
16use embassy_time::Timer; 16use embassy_time::{Duration, Timer, block_for};
17use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
18 18
19enum _Orientation { 19enum _Orientation {
@@ -444,7 +444,7 @@ async fn main(_spawner: Spawner) {
444 dsi.enable_wrapper_dsi(); 444 dsi.enable_wrapper_dsi();
445 445
446 // First, delay 120 ms (reason unknown, STM32 Cube Example does it) 446 // First, delay 120 ms (reason unknown, STM32 Cube Example does it)
447 blocking_delay_ms(120); 447 block_for(Duration::from_millis(120));
448 448
449 // 1 to 26 449 // 1 to 26
450 dsi.write_cmd(0, NT35510_WRITES_0[0], &NT35510_WRITES_0[1..]).unwrap(); 450 dsi.write_cmd(0, NT35510_WRITES_0[0], &NT35510_WRITES_0[1..]).unwrap();
@@ -480,7 +480,7 @@ async fn main(_spawner: Spawner) {
480 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); 480 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap();
481 481
482 // Add a delay, otherwise MADCTL not taken 482 // Add a delay, otherwise MADCTL not taken
483 blocking_delay_ms(200); 483 block_for(Duration::from_millis(200));
484 484
485 // Configure orientation as landscape 485 // Configure orientation as landscape
486 dsi.write_cmd(0, NT35510_MADCTL_LANDSCAPE[0], &NT35510_MADCTL_LANDSCAPE[1..]) 486 dsi.write_cmd(0, NT35510_MADCTL_LANDSCAPE[0], &NT35510_MADCTL_LANDSCAPE[1..])
@@ -494,7 +494,7 @@ async fn main(_spawner: Spawner) {
494 dsi.write_cmd(0, NT35510_WRITES_27[0], &NT35510_WRITES_27[1..]).unwrap(); 494 dsi.write_cmd(0, NT35510_WRITES_27[0], &NT35510_WRITES_27[1..]).unwrap();
495 495
496 // Wait for sleep out exit 496 // Wait for sleep out exit
497 blocking_delay_ms(120); 497 block_for(Duration::from_millis(120));
498 498
499 // Configure COLOR_CODING 499 // Configure COLOR_CODING
500 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap(); 500 dsi.write_cmd(0, NT35510_WRITES_37[0], &NT35510_WRITES_37[1..]).unwrap();
@@ -590,7 +590,7 @@ async fn main(_spawner: Spawner) {
590 //LTDC->SRCR = LTDC_SRCR_IMR; 590 //LTDC->SRCR = LTDC_SRCR_IMR;
591 LTDC.srcr().modify(|w| w.set_imr(Imr::RELOAD)); 591 LTDC.srcr().modify(|w| w.set_imr(Imr::RELOAD));
592 592
593 blocking_delay_ms(5000); 593 block_for(Duration::from_millis(5000));
594 594
595 const READ_SIZE: u16 = 1; 595 const READ_SIZE: u16 = 1;
596 let mut data = [1u8; READ_SIZE as usize]; 596 let mut data = [1u8; READ_SIZE as usize];
@@ -606,7 +606,7 @@ async fn main(_spawner: Spawner) {
606 .unwrap(); 606 .unwrap();
607 info!("Display ID3: {:#04x}", data); 607 info!("Display ID3: {:#04x}", data);
608 608
609 blocking_delay_ms(500); 609 block_for(Duration::from_millis(500));
610 610
611 info!("Config done, start blinking LED"); 611 info!("Config done, start blinking LED");
612 loop { 612 loop {