stm32f1xx_hal/timer/
counter.rs

1use super::{compute_arr_presc, Error, Event, FTimer, Instance, SysEvent, Timer};
2use crate::pac::SYST;
3use core::convert::TryFrom;
4use core::ops::{Deref, DerefMut};
5use fugit::{HertzU32 as Hertz, MicrosDurationU32, TimerDurationU32, TimerInstantU32};
6
7/// Hardware timers
8pub struct CounterHz<TIM>(pub(super) Timer<TIM>);
9
10impl<T> Deref for CounterHz<T> {
11    type Target = Timer<T>;
12    fn deref(&self) -> &Self::Target {
13        &self.0
14    }
15}
16
17impl<T> DerefMut for CounterHz<T> {
18    fn deref_mut(&mut self) -> &mut Self::Target {
19        &mut self.0
20    }
21}
22
23impl<TIM: Instance> CounterHz<TIM> {
24    /// Releases the TIM peripheral
25    pub fn release(mut self) -> Timer<TIM> {
26        // stop timer
27        self.tim.cr1_reset();
28        self.0
29    }
30}
31
32impl<TIM: Instance> CounterHz<TIM> {
33    pub fn start(&mut self, timeout: Hertz) -> Result<(), Error> {
34        // pause
35        self.tim.disable_counter();
36
37        self.tim.clear_interrupt_flag(Event::Update);
38
39        // reset counter
40        self.tim.reset_counter();
41
42        let (psc, arr) = compute_arr_presc(timeout.raw(), self.clk.raw());
43        self.tim.set_prescaler(psc);
44        self.tim.set_auto_reload(arr)?;
45
46        // Trigger update event to load the registers
47        self.tim.trigger_update();
48
49        // start counter
50        self.tim.enable_counter();
51
52        Ok(())
53    }
54
55    pub fn wait(&mut self) -> nb::Result<(), Error> {
56        if self.tim.get_interrupt_flag().contains(Event::Update) {
57            self.tim.clear_interrupt_flag(Event::Update);
58            Ok(())
59        } else {
60            Err(nb::Error::WouldBlock)
61        }
62    }
63
64    pub fn cancel(&mut self) -> Result<(), Error> {
65        if !self.tim.is_counter_enabled() {
66            return Err(Error::Disabled);
67        }
68
69        // disable counter
70        self.tim.disable_counter();
71        Ok(())
72    }
73
74    /// Restarts the timer in count down mode with user-defined prescaler and auto-reload register
75    pub fn start_raw(&mut self, psc: u16, arr: u16) {
76        // pause
77        self.tim.disable_counter();
78
79        self.tim.set_prescaler(psc);
80
81        self.tim.set_auto_reload(arr as u32).unwrap();
82
83        // Trigger an update event to load the prescaler value to the clock
84        self.tim.trigger_update();
85
86        // start counter
87        self.tim.enable_counter();
88    }
89
90    /// Retrieves the content of the prescaler register. The real prescaler is this value + 1.
91    pub fn psc(&self) -> u16 {
92        self.tim.read_prescaler()
93    }
94
95    /// Retrieves the value of the auto-reload register.
96    pub fn arr(&self) -> u16 {
97        TIM::read_auto_reload() as u16
98    }
99
100    /// Resets the counter
101    pub fn reset(&mut self) {
102        // Sets the URS bit to prevent an interrupt from being triggered by
103        // the UG bit
104        self.tim.trigger_update();
105    }
106
107    /// Returns the number of microseconds since the last update event.
108    /// *NOTE:* This method is not a very good candidate to keep track of time, because
109    /// it is very easy to lose an update event.
110    pub fn now(&self) -> MicrosDurationU32 {
111        let psc = self.tim.read_prescaler() as u32;
112
113        // freq_divider is always bigger than 0, since (psc + 1) is always less than
114        // timer_clock
115        let freq_divider = (self.clk.raw() / (psc + 1)) as u64;
116        let cnt: u32 = self.tim.read_count().into();
117        let cnt = cnt as u64;
118
119        // It is safe to make this cast, because the maximum timer period in this HAL is
120        // 1s (1Hz), then 1 second < (2^32 - 1) microseconds
121        MicrosDurationU32::from_ticks(u32::try_from(1_000_000 * cnt / freq_divider).unwrap())
122    }
123}
124
125/// Periodic non-blocking timer that imlements [embedded_hal_02::timer::CountDown]
126pub struct Counter<TIM, const FREQ: u32>(pub(super) FTimer<TIM, FREQ>);
127
128impl<T, const FREQ: u32> Deref for Counter<T, FREQ> {
129    type Target = FTimer<T, FREQ>;
130    fn deref(&self) -> &Self::Target {
131        &self.0
132    }
133}
134
135impl<T, const FREQ: u32> DerefMut for Counter<T, FREQ> {
136    fn deref_mut(&mut self) -> &mut Self::Target {
137        &mut self.0
138    }
139}
140
141/// `Counter` with precision of 1 μs (1 MHz sampling)
142pub type CounterUs<TIM> = Counter<TIM, 1_000_000>;
143
144/// `Counter` with precision of of 1 ms (1 kHz sampling)
145///
146/// NOTE: don't use this if your system frequency more than 65 MHz
147pub type CounterMs<TIM> = Counter<TIM, 1_000>;
148
149impl<TIM: Instance, const FREQ: u32> Counter<TIM, FREQ> {
150    /// Releases the TIM peripheral
151    pub fn release(mut self) -> FTimer<TIM, FREQ> {
152        // stop counter
153        self.tim.cr1_reset();
154        self.0
155    }
156
157    pub fn now(&self) -> TimerInstantU32<FREQ> {
158        TimerInstantU32::from_ticks(self.tim.read_count().into())
159    }
160
161    pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> {
162        // pause
163        self.tim.disable_counter();
164
165        self.tim.clear_interrupt_flag(Event::Update);
166
167        // reset counter
168        self.tim.reset_counter();
169
170        self.tim.set_auto_reload(timeout.ticks() - 1)?;
171
172        // Trigger update event to load the registers
173        self.tim.trigger_update();
174
175        // start counter
176        self.tim.enable_counter();
177
178        Ok(())
179    }
180
181    pub fn wait(&mut self) -> nb::Result<(), Error> {
182        if self.tim.get_interrupt_flag().contains(Event::Update) {
183            self.tim.clear_interrupt_flag(Event::Update);
184            Ok(())
185        } else {
186            Err(nb::Error::WouldBlock)
187        }
188    }
189
190    pub fn cancel(&mut self) -> Result<(), Error> {
191        if !self.tim.is_counter_enabled() {
192            return Err(Error::Disabled);
193        }
194
195        // disable counter
196        self.tim.disable_counter();
197        Ok(())
198    }
199}
200
201impl<TIM: Instance, const FREQ: u32> fugit_timer::Timer<FREQ> for Counter<TIM, FREQ> {
202    type Error = Error;
203
204    fn now(&mut self) -> TimerInstantU32<FREQ> {
205        Self::now(self)
206    }
207
208    fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> {
209        self.start(duration)
210    }
211
212    fn cancel(&mut self) -> Result<(), Self::Error> {
213        self.cancel()
214    }
215
216    fn wait(&mut self) -> nb::Result<(), Self::Error> {
217        self.wait()
218    }
219}
220
221impl Timer<SYST> {
222    /// Creates [SysCounterHz] which takes [Hertz] as Duration
223    pub fn counter_hz(self) -> SysCounterHz {
224        SysCounterHz(self)
225    }
226
227    /// Creates [SysCounter] with custom precision (core frequency recommended is known)
228    pub fn counter<const FREQ: u32>(self) -> SysCounter<FREQ> {
229        SysCounter(self)
230    }
231
232    /// Creates [SysCounter] 1 microsecond precision
233    pub fn counter_us(self) -> SysCounterUs {
234        SysCounter(self)
235    }
236}
237
238/// Hardware timers
239pub struct SysCounterHz(Timer<SYST>);
240
241impl Deref for SysCounterHz {
242    type Target = Timer<SYST>;
243    fn deref(&self) -> &Self::Target {
244        &self.0
245    }
246}
247
248impl DerefMut for SysCounterHz {
249    fn deref_mut(&mut self) -> &mut Self::Target {
250        &mut self.0
251    }
252}
253
254impl SysCounterHz {
255    pub fn start(&mut self, timeout: Hertz) -> Result<(), Error> {
256        let rvr = self.clk.raw() / timeout.raw() - 1;
257
258        if rvr >= (1 << 24) {
259            return Err(Error::WrongAutoReload);
260        }
261
262        self.tim.set_reload(rvr);
263        self.tim.clear_current();
264        self.tim.enable_counter();
265
266        Ok(())
267    }
268
269    pub fn wait(&mut self) -> nb::Result<(), Error> {
270        if self.tim.has_wrapped() {
271            Ok(())
272        } else {
273            Err(nb::Error::WouldBlock)
274        }
275    }
276
277    pub fn cancel(&mut self) -> Result<(), Error> {
278        if !self.tim.is_counter_enabled() {
279            return Err(Error::Disabled);
280        }
281
282        self.tim.disable_counter();
283        Ok(())
284    }
285}
286
287pub type SysCounterUs = SysCounter<1_000_000>;
288
289/// SysTick timer with precision of 1 μs (1 MHz sampling)
290pub struct SysCounter<const FREQ: u32>(Timer<SYST>);
291
292impl<const FREQ: u32> Deref for SysCounter<FREQ> {
293    type Target = Timer<SYST>;
294    fn deref(&self) -> &Self::Target {
295        &self.0
296    }
297}
298
299impl<const FREQ: u32> DerefMut for SysCounter<FREQ> {
300    fn deref_mut(&mut self) -> &mut Self::Target {
301        &mut self.0
302    }
303}
304
305impl<const FREQ: u32> SysCounter<FREQ> {
306    /// Starts listening for an `event`
307    pub fn listen(&mut self, event: SysEvent) {
308        match event {
309            SysEvent::Update => self.tim.enable_interrupt(),
310        }
311    }
312
313    /// Stops listening for an `event`
314    pub fn unlisten(&mut self, event: SysEvent) {
315        match event {
316            SysEvent::Update => self.tim.disable_interrupt(),
317        }
318    }
319
320    pub fn now(&self) -> TimerInstantU32<FREQ> {
321        TimerInstantU32::from_ticks(SYST::get_current() / (self.clk.raw() / FREQ))
322    }
323
324    pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> {
325        let rvr = timeout.ticks() * (self.clk.raw() / FREQ) - 1;
326
327        if rvr >= (1 << 24) {
328            return Err(Error::WrongAutoReload);
329        }
330
331        self.tim.set_reload(rvr);
332        self.tim.clear_current();
333        self.tim.enable_counter();
334
335        Ok(())
336    }
337
338    pub fn wait(&mut self) -> nb::Result<(), Error> {
339        if self.tim.has_wrapped() {
340            Ok(())
341        } else {
342            Err(nb::Error::WouldBlock)
343        }
344    }
345
346    pub fn cancel(&mut self) -> Result<(), Error> {
347        if !self.tim.is_counter_enabled() {
348            return Err(Error::Disabled);
349        }
350
351        self.tim.disable_counter();
352        Ok(())
353    }
354}
355
356impl<const FREQ: u32> fugit_timer::Timer<FREQ> for SysCounter<FREQ> {
357    type Error = Error;
358
359    fn now(&mut self) -> TimerInstantU32<FREQ> {
360        Self::now(self)
361    }
362
363    fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> {
364        self.start(duration)
365    }
366
367    fn wait(&mut self) -> nb::Result<(), Self::Error> {
368        self.wait()
369    }
370
371    fn cancel(&mut self) -> Result<(), Self::Error> {
372        self.cancel()
373    }
374}