stm32f1_hal/common/timer/
counter.rs

1use super::{Error, Event, FTimer, GeneralTimer};
2use crate::common::fugit::{HertzU32, MicrosDurationU32, TimerDurationU32, TimerInstantU32};
3use core::ops::{Deref, DerefMut};
4
5/// Hardware timers
6pub struct CounterHz<TIM> {
7    pub(crate) tim: TIM,
8    pub(crate) clk: HertzU32,
9}
10
11impl<TIM: GeneralTimer> CounterHz<TIM> {
12    pub fn start(&mut self, timeout: HertzU32) -> 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
102pub struct Counter<TIM, const FREQ: u32>(pub(super) FTimer<TIM, FREQ>);
103
104impl<T, const FREQ: u32> Deref for Counter<T, FREQ> {
105    type Target = FTimer<T, FREQ>;
106    fn deref(&self) -> &Self::Target {
107        &self.0
108    }
109}
110
111impl<T, const FREQ: u32> DerefMut for Counter<T, FREQ> {
112    fn deref_mut(&mut self) -> &mut Self::Target {
113        &mut self.0
114    }
115}
116
117/// `Counter` with precision of 1 μs (1 MHz sampling)
118pub type CounterUs<TIM> = Counter<TIM, 1_000_000>;
119
120/// `Counter` with precision of of 1 ms (1 kHz sampling)
121///
122/// NOTE: don't use this if your system frequency more than 65 MHz
123pub type CounterMs<TIM> = Counter<TIM, 1_000>;
124
125impl<TIM: GeneralTimer, const FREQ: u32> Counter<TIM, FREQ> {
126    /// Releases the TIM peripheral
127    pub fn release(mut self) -> FTimer<TIM, FREQ> {
128        // stop counter
129        self.tim.reset_config();
130        self.0
131    }
132
133    pub fn now(&self) -> TimerInstantU32<FREQ> {
134        TimerInstantU32::from_ticks(self.tim.read_count())
135    }
136
137    pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> {
138        // pause
139        self.tim.disable_counter();
140
141        self.tim.clear_interrupt_flag(Event::Update);
142
143        // reset counter
144        self.tim.reset_counter();
145
146        self.tim.set_auto_reload(timeout.ticks() - 1)?;
147
148        // Trigger update event to load the registers
149        self.tim.trigger_update();
150
151        // start counter
152        self.tim.enable_counter();
153
154        Ok(())
155    }
156
157    pub fn wait(&mut self) -> nb::Result<(), Error> {
158        if self.tim.get_interrupt_flag().contains(Event::Update) {
159            self.tim.clear_interrupt_flag(Event::Update);
160            Ok(())
161        } else {
162            Err(nb::Error::WouldBlock)
163        }
164    }
165
166    pub fn cancel(&mut self) -> Result<(), Error> {
167        if !self.tim.is_counter_enabled() {
168            return Err(Error::Disabled);
169        }
170
171        // disable counter
172        self.tim.disable_counter();
173        Ok(())
174    }
175}
176
177impl<TIM: GeneralTimer, const FREQ: u32> fugit_timer::Timer<FREQ> for Counter<TIM, FREQ> {
178    type Error = Error;
179
180    fn now(&mut self) -> TimerInstantU32<FREQ> {
181        Self::now(self)
182    }
183
184    fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> {
185        self.start(duration)
186    }
187
188    fn cancel(&mut self) -> Result<(), Self::Error> {
189        self.cancel()
190    }
191
192    fn wait(&mut self) -> nb::Result<(), Self::Error> {
193        self.wait()
194    }
195}