stm32f1_hal/common/timer/
delay.rs

1//! Delays
2
3use super::{FTimer, GeneralTimer};
4use core::ops::{Deref, DerefMut};
5use fugit::TimerDurationU32;
6
7/// Periodic non-blocking timer that imlements [embedded_hal_02::blocking::delay] traits
8pub struct Delay<TIM, const FREQ: u32>(pub(super) FTimer<TIM, FREQ>);
9
10impl<T, const FREQ: u32> Deref for Delay<T, FREQ> {
11    type Target = FTimer<T, FREQ>;
12    fn deref(&self) -> &Self::Target {
13        &self.0
14    }
15}
16
17impl<T, const FREQ: u32> DerefMut for Delay<T, FREQ> {
18    fn deref_mut(&mut self) -> &mut Self::Target {
19        &mut self.0
20    }
21}
22
23/// `Delay` with precision of 1 μs (1 MHz sampling)
24pub type DelayUs<TIM> = Delay<TIM, 1_000_000>;
25
26/// `Delay` with precision of 1 ms (1 kHz sampling)
27///
28/// NOTE: don't use this if your system frequency more than 65 MHz
29pub type DelayMs<TIM> = Delay<TIM, 1_000>;
30
31impl<TIM: GeneralTimer, const FREQ: u32> Delay<TIM, FREQ> {
32    /// Sleep for given time
33    pub fn delay(&mut self, time: TimerDurationU32<FREQ>) {
34        let mut ticks = time.ticks().max(1) - 1;
35        while ticks != 0 {
36            let reload = ticks.min(TIM::max_auto_reload());
37
38            // Write Auto-Reload Register (ARR)
39            unsafe {
40                self.tim.set_auto_reload_unchecked(reload);
41            }
42
43            // Trigger update event (UEV) in the event generation register (EGR)
44            // in order to immediately apply the config
45            self.tim.trigger_update();
46
47            // Configure the counter in one-pulse mode (counter stops counting at
48            // the next updateevent, clearing the CEN bit) and enable the counter.
49            self.tim.start_one_pulse();
50
51            // Update the tracking variable while we are waiting...
52            ticks -= reload;
53            // Wait for CEN bit to clear
54            while self.tim.is_counter_enabled() { /* wait */ }
55        }
56    }
57
58    pub fn max_delay(&self) -> TimerDurationU32<FREQ> {
59        TimerDurationU32::from_ticks(TIM::max_auto_reload())
60    }
61
62    /// Releases the TIM peripheral
63    pub fn release(mut self) -> FTimer<TIM, FREQ> {
64        // stop counter
65        self.tim.reset_config();
66        self.0
67    }
68}
69
70impl<TIM: GeneralTimer, const FREQ: u32> fugit_timer::Delay<FREQ> for Delay<TIM, FREQ> {
71    type Error = core::convert::Infallible;
72
73    fn delay(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> {
74        self.delay(duration);
75        Ok(())
76    }
77}
78
79// ----------------------------------------------------------------------------
80
81use embedded_hal::delay::DelayNs;
82use fugit::ExtU32Ceil;
83
84impl<TIM: GeneralTimer, const FREQ: u32> DelayNs for Delay<TIM, FREQ> {
85    fn delay_ns(&mut self, ns: u32) {
86        self.delay(ns.micros_at_least());
87    }
88
89    fn delay_us(&mut self, us: u32) {
90        self.delay(us.micros_at_least());
91    }
92
93    fn delay_ms(&mut self, ms: u32) {
94        self.delay(ms.millis_at_least());
95    }
96}