stm32f1_hal/common/timer/
counter.rs

1use super::{Error, Event, FTimer, GeneralTimer};
2use core::ops::{Deref, DerefMut};
3use fugit::{HertzU32 as Hertz, MicrosDurationU32, TimerDurationU32, TimerInstantU32};
4
5/// Hardware timers
6pub struct CounterHz<TIM> {
7    pub(crate) tim: TIM,
8    pub(crate) clk: Hertz,
9}
10
11impl<TIM: GeneralTimer> CounterHz<TIM> {
12    pub fn start(&mut self, timeout: Hertz) -> Result<(), Error> {
13        // pause
14        self.tim.disable_counter();
15
16        self.tim.clear_interrupt_flag(Event::Update);
17
18        // reset counter
19        self.tim.reset_counter();
20
21        let clk = self.clk;
22        self.tim.config_freq(clk, timeout);
23
24        // start counter
25        self.tim.enable_counter();
26
27        Ok(())
28    }
29
30    pub fn wait(&mut self) -> nb::Result<(), Error> {
31        if self.tim.get_interrupt_flag().contains(Event::Update) {
32            self.tim.clear_interrupt_flag(Event::Update);
33            Ok(())
34        } else {
35            Err(nb::Error::WouldBlock)
36        }
37    }
38
39    pub fn cancel(&mut self) -> Result<(), Error> {
40        if !self.tim.is_counter_enabled() {
41            return Err(Error::Disabled);
42        }
43
44        // disable counter
45        self.tim.disable_counter();
46        Ok(())
47    }
48
49    /// Restarts the timer in count down mode with user-defined prescaler and auto-reload register
50    pub fn start_raw(&mut self, psc: u16, arr: u16) {
51        // pause
52        self.tim.disable_counter();
53
54        self.tim.set_prescaler(psc);
55
56        self.tim.set_auto_reload(arr as u32).unwrap();
57
58        // Trigger an update event to load the prescaler value to the clock
59        self.tim.trigger_update();
60
61        // start counter
62        self.tim.enable_counter();
63    }
64
65    /// Retrieves the content of the prescaler register. The real prescaler is this value + 1.
66    pub fn psc(&self) -> u16 {
67        self.tim.read_prescaler()
68    }
69
70    /// Retrieves the value of the auto-reload register.
71    pub fn arr(&self) -> u16 {
72        self.tim.read_auto_reload() as u16
73    }
74
75    /// Resets the counter
76    pub fn reset(&mut self) {
77        // Sets the URS bit to prevent an interrupt from being triggered by
78        // the UG bit
79        self.tim.trigger_update();
80    }
81
82    /// Returns the number of microseconds since the last update event.
83    /// *NOTE:* This method is not a very good candidate to keep track of time, because
84    /// it is very easy to lose an update event.
85    pub fn now(&self) -> MicrosDurationU32 {
86        let psc = self.tim.read_prescaler() as u32;
87
88        // freq_divider is always bigger than 0, since (psc + 1) is always less than
89        // timer_clock
90        let freq_divider = (self.clk.raw() / (psc + 1)) as u64;
91        let cnt: u32 = self.tim.read_count();
92        let cnt = cnt as u64;
93
94        // It is safe to make this cast, because the maximum timer period in this HAL is
95        // 1s (1Hz), then 1 second < (2^32 - 1) microseconds
96        MicrosDurationU32::from_ticks(u32::try_from(1_000_000 * cnt / freq_divider).unwrap())
97    }
98}
99
100// ----------------------------------------------------------------------------
101
102/// Periodic non-blocking timer that imlements [embedded_hal_02::timer::CountDown]
103pub struct Counter<TIM, const FREQ: u32>(pub(super) FTimer<TIM, FREQ>);
104
105impl<T, const FREQ: u32> Deref for Counter<T, FREQ> {
106    type Target = FTimer<T, FREQ>;
107    fn deref(&self) -> &Self::Target {
108        &self.0
109    }
110}
111
112impl<T, const FREQ: u32> DerefMut for Counter<T, FREQ> {
113    fn deref_mut(&mut self) -> &mut Self::Target {
114        &mut self.0
115    }
116}
117
118/// `Counter` with precision of 1 μs (1 MHz sampling)
119pub type CounterUs<TIM> = Counter<TIM, 1_000_000>;
120
121/// `Counter` with precision of of 1 ms (1 kHz sampling)
122///
123/// NOTE: don't use this if your system frequency more than 65 MHz
124pub type CounterMs<TIM> = Counter<TIM, 1_000>;
125
126impl<TIM: GeneralTimer, const FREQ: u32> Counter<TIM, FREQ> {
127    /// Releases the TIM peripheral
128    pub fn release(mut self) -> FTimer<TIM, FREQ> {
129        // stop counter
130        self.tim.reset_config();
131        self.0
132    }
133
134    pub fn now(&self) -> TimerInstantU32<FREQ> {
135        TimerInstantU32::from_ticks(self.tim.read_count())
136    }
137
138    pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> {
139        // pause
140        self.tim.disable_counter();
141
142        self.tim.clear_interrupt_flag(Event::Update);
143
144        // reset counter
145        self.tim.reset_counter();
146
147        self.tim.set_auto_reload(timeout.ticks() - 1)?;
148
149        // Trigger update event to load the registers
150        self.tim.trigger_update();
151
152        // start counter
153        self.tim.enable_counter();
154
155        Ok(())
156    }
157
158    pub fn wait(&mut self) -> nb::Result<(), Error> {
159        if self.tim.get_interrupt_flag().contains(Event::Update) {
160            self.tim.clear_interrupt_flag(Event::Update);
161            Ok(())
162        } else {
163            Err(nb::Error::WouldBlock)
164        }
165    }
166
167    pub fn cancel(&mut self) -> Result<(), Error> {
168        if !self.tim.is_counter_enabled() {
169            return Err(Error::Disabled);
170        }
171
172        // disable counter
173        self.tim.disable_counter();
174        Ok(())
175    }
176}
177
178impl<TIM: GeneralTimer, const FREQ: u32> fugit_timer::Timer<FREQ> for Counter<TIM, FREQ> {
179    type Error = Error;
180
181    fn now(&mut self) -> TimerInstantU32<FREQ> {
182        Self::now(self)
183    }
184
185    fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> {
186        self.start(duration)
187    }
188
189    fn cancel(&mut self) -> Result<(), Self::Error> {
190        self.cancel()
191    }
192
193    fn wait(&mut self) -> nb::Result<(), Self::Error> {
194        self.wait()
195    }
196}