stm32f1_hal/timer/
syst.rs1use super::*;
4use crate::{Mcu, os::*, time::Hertz};
5use core::ops::{Deref, DerefMut};
6use cortex_m::peripheral::{SYST, syst::SystClkSource};
7use embedded_hal::delay::DelayNs;
8use fugit::{ExtU32Ceil, MicrosDurationU32, TimerDurationU32, TimerInstantU32};
9
10pub trait SysTimerInit: Sized {
11 fn counter_hz(self, mcu: &Mcu) -> SysCounterHz;
13
14 fn counter<const FREQ: u32>(self, mcu: &Mcu) -> SysCounter<FREQ>;
16 fn counter_us(self, mcu: &Mcu) -> SysCounterUs {
18 self.counter::<1_000_000>(mcu)
19 }
20 fn delay(self, mcu: &Mcu) -> SysDelay;
22}
23
24impl SysTimerInit for SYST {
25 fn counter_hz(self, mcu: &Mcu) -> SysCounterHz {
26 SystemTimer::syst(self, mcu).counter_hz()
27 }
28 fn counter<const FREQ: u32>(self, mcu: &Mcu) -> SysCounter<FREQ> {
29 SystemTimer::syst(self, mcu).counter()
30 }
31 fn delay(self, mcu: &Mcu) -> SysDelay {
32 SystemTimer::syst_external(self, mcu).delay()
33 }
34}
35
36pub struct SystemTimer {
37 pub(super) syst: SYST,
38 pub(super) clk: Hertz,
39}
40impl SystemTimer {
41 pub fn syst(mut syst: SYST, mcu: &Mcu) -> Self {
43 syst.set_clock_source(SystClkSource::Core);
44 Self {
45 syst,
46 clk: mcu.rcc.clocks.hclk(),
47 }
48 }
49
50 pub fn syst_external(mut syst: SYST, mcu: &Mcu) -> Self {
52 syst.set_clock_source(SystClkSource::External);
53 Self {
54 syst,
55 clk: mcu.rcc.clocks.hclk() / 8,
56 }
57 }
58
59 pub fn release(self) -> SYST {
60 self.syst
61 }
62
63 pub fn listen(&mut self, event: SysEvent) {
65 match event {
66 SysEvent::Update => self.syst.enable_interrupt(),
67 }
68 }
69
70 pub fn unlisten(&mut self, event: SysEvent) {
72 match event {
73 SysEvent::Update => self.syst.disable_interrupt(),
74 }
75 }
76
77 pub fn reset(&mut self) {
79 self.syst.clear_current();
82 }
83}
84
85impl SystemTimer {
88 pub fn counter_hz(self) -> SysCounterHz {
90 SysCounterHz(self)
91 }
92
93 pub fn counter<const FREQ: u32>(self) -> SysCounter<FREQ> {
95 SysCounter(self)
96 }
97
98 pub fn counter_us(self) -> SysCounterUs {
100 SysCounter(self)
101 }
102}
103
104pub struct SysCounterHz(SystemTimer);
106
107impl Deref for SysCounterHz {
108 type Target = SystemTimer;
109 fn deref(&self) -> &Self::Target {
110 &self.0
111 }
112}
113
114impl DerefMut for SysCounterHz {
115 fn deref_mut(&mut self) -> &mut Self::Target {
116 &mut self.0
117 }
118}
119
120impl SysCounterHz {
121 pub fn start(&mut self, timeout: Hertz) -> Result<(), Error> {
122 let rvr = self.clk.raw() / timeout.raw() - 1;
123
124 if rvr >= (1 << 24) {
125 return Err(Error::WrongAutoReload);
126 }
127
128 self.syst.set_reload(rvr);
129 self.syst.clear_current();
130 self.syst.enable_counter();
131
132 Ok(())
133 }
134
135 pub fn wait(&mut self) -> nb::Result<(), Error> {
136 if self.syst.has_wrapped() {
137 Ok(())
138 } else {
139 Err(nb::Error::WouldBlock)
140 }
141 }
142
143 pub fn cancel(&mut self) -> Result<(), Error> {
144 if !self.syst.is_counter_enabled() {
145 return Err(Error::Disabled);
146 }
147
148 self.syst.disable_counter();
149 Ok(())
150 }
151}
152
153pub type SysCounterUs = SysCounter<1_000_000>;
154
155pub struct SysCounter<const FREQ: u32>(SystemTimer);
157
158impl<const FREQ: u32> Deref for SysCounter<FREQ> {
159 type Target = SystemTimer;
160 fn deref(&self) -> &Self::Target {
161 &self.0
162 }
163}
164
165impl<const FREQ: u32> DerefMut for SysCounter<FREQ> {
166 fn deref_mut(&mut self) -> &mut Self::Target {
167 &mut self.0
168 }
169}
170
171impl<const FREQ: u32> SysCounter<FREQ> {
172 pub fn listen(&mut self, event: SysEvent) {
174 match event {
175 SysEvent::Update => self.syst.enable_interrupt(),
176 }
177 }
178
179 pub fn unlisten(&mut self, event: SysEvent) {
181 match event {
182 SysEvent::Update => self.syst.disable_interrupt(),
183 }
184 }
185
186 pub fn now(&self) -> TimerInstantU32<FREQ> {
187 TimerInstantU32::from_ticks(SYST::get_current() / (self.clk.raw() / FREQ))
188 }
189
190 pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> {
191 let rvr = timeout.ticks() * (self.clk.raw() / FREQ) - 1;
192
193 if rvr >= (1 << 24) {
194 return Err(Error::WrongAutoReload);
195 }
196
197 self.syst.set_reload(rvr);
198 self.syst.clear_current();
199 self.syst.enable_counter();
200
201 Ok(())
202 }
203
204 pub fn wait(&mut self) -> nb::Result<(), Error> {
205 if self.syst.has_wrapped() {
206 Ok(())
207 } else {
208 Err(nb::Error::WouldBlock)
209 }
210 }
211
212 pub fn cancel(&mut self) -> Result<(), Error> {
213 if !self.syst.is_counter_enabled() {
214 return Err(Error::Disabled);
215 }
216
217 self.syst.disable_counter();
218 Ok(())
219 }
220}
221
222impl<const FREQ: u32> fugit_timer::Timer<FREQ> for SysCounter<FREQ> {
223 type Error = Error;
224
225 fn now(&mut self) -> TimerInstantU32<FREQ> {
226 Self::now(self)
227 }
228
229 fn start(&mut self, duration: TimerDurationU32<FREQ>) -> Result<(), Self::Error> {
230 self.start(duration)
231 }
232
233 fn wait(&mut self) -> nb::Result<(), Self::Error> {
234 self.wait()
235 }
236
237 fn cancel(&mut self) -> Result<(), Self::Error> {
238 self.cancel()
239 }
240}
241
242pub struct SysDelay(SystemTimer);
246
247impl Deref for SysDelay {
248 type Target = SystemTimer;
249 fn deref(&self) -> &Self::Target {
250 &self.0
251 }
252}
253
254impl DerefMut for SysDelay {
255 fn deref_mut(&mut self) -> &mut Self::Target {
256 &mut self.0
257 }
258}
259
260impl SysDelay {
261 pub fn release(self) -> SystemTimer {
263 self.0
264 }
265}
266
267impl SystemTimer {
268 pub fn delay(self) -> SysDelay {
269 SysDelay(self)
270 }
271}
272
273impl SysDelay {
274 pub fn delay(&mut self, us: MicrosDurationU32) {
275 const MAX_RVR: u32 = 0x00FF_FFFF;
277
278 let mut total_rvr = us.ticks() * (self.clk.raw() / 1_000_000);
279
280 while total_rvr != 0 {
281 let current_rvr = total_rvr.min(MAX_RVR);
282
283 self.syst.set_reload(current_rvr);
284 self.syst.clear_current();
285 self.syst.enable_counter();
286
287 total_rvr -= current_rvr;
289
290 while !self.syst.has_wrapped() {}
291
292 self.syst.disable_counter();
293 }
294 }
295}
296
297impl fugit_timer::Delay<1_000_000> for SysDelay {
298 type Error = core::convert::Infallible;
299
300 fn delay(&mut self, duration: MicrosDurationU32) -> Result<(), Self::Error> {
301 self.delay(duration);
302 Ok(())
303 }
304}
305
306impl DelayNs for SysDelay {
307 fn delay_ns(&mut self, ns: u32) {
308 self.delay(ns.nanos_at_least());
309 }
310
311 fn delay_ms(&mut self, ms: u32) {
312 self.delay(ms.millis_at_least());
313 }
314}
315
316pub struct SysTickTimeout {
320 timeout_us: usize,
321}
322impl SysTickTimeout {
323 pub fn new(timeout_us: usize) -> Self {
324 Self { timeout_us }
325 }
326}
327impl Timeout for SysTickTimeout {
328 fn start(&mut self) -> impl TimeoutInstance {
329 let now = SYST::get_current() as usize;
330 let reload = SYST::get_reload() as usize;
331 let round = self.timeout_us / 1000;
332 let us = self.timeout_us % 1000;
333
334 SysTickTimeoutInstance {
335 former_tick: now,
336 timeout_tick: us * reload / 1000,
337 elapsed_tick: 0,
338 round_backup: round,
339 round,
340 }
341 }
342}
343
344pub struct SysTickTimeoutInstance {
345 former_tick: usize,
346 timeout_tick: usize,
347 elapsed_tick: usize,
348 round: usize,
349 round_backup: usize,
350}
351impl SysTickTimeoutInstance {
352 fn elapsed(&mut self) -> usize {
353 let now = SYST::get_current() as usize;
354 let elapsed = if now <= self.former_tick {
355 self.former_tick - now
356 } else {
357 self.former_tick + (SYST::get_reload() as usize - now)
358 };
359 self.former_tick = now;
360 elapsed
361 }
362}
363impl TimeoutInstance for SysTickTimeoutInstance {
364 fn timeout(&mut self) -> bool {
365 self.elapsed_tick += self.elapsed();
366
367 if self.round == 0 {
368 if self.elapsed_tick >= self.timeout_tick {
369 self.elapsed_tick -= self.timeout_tick;
370 self.round = self.round_backup;
371 return true;
372 }
373 } else {
374 let reload = SYST::get_reload() as usize;
375 if self.elapsed_tick >= reload {
376 self.elapsed_tick -= reload;
377 self.round -= 1;
378 }
379 }
380 false
381 }
382
383 #[inline(always)]
384 fn restart(&mut self) {
385 self.round = self.round_backup;
386 self.elapsed_tick = 0;
387 }
388
389 #[inline(always)]
390 fn interval(&self) {}
391}