Skip to main content

gd32c1x3_hal/timer/
counter.rs

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