stm32f1_hal/timer/
syst.rs1use super::*;
4use crate::{Mcu, 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 struct SystemTimer {
11 pub(super) syst: SYST,
12 pub(super) clk: Hertz,
13}
14impl SystemTimer {
15 pub fn syst(mut syst: SYST, mcu: &Mcu) -> Self {
17 syst.set_clock_source(SystClkSource::Core);
18 Self {
19 syst,
20 clk: mcu.rcc.clocks.hclk(),
21 }
22 }
23
24 pub fn syst_external(mut syst: SYST, mcu: &Mcu) -> Self {
26 syst.set_clock_source(SystClkSource::External);
27 Self {
28 syst,
29 clk: mcu.rcc.clocks.hclk() / 8,
30 }
31 }
32
33 pub fn release(self) -> SYST {
34 self.syst
35 }
36
37 pub fn listen(&mut self, event: SysEvent) {
39 match event {
40 SysEvent::Update => self.syst.enable_interrupt(),
41 }
42 }
43
44 pub fn unlisten(&mut self, event: SysEvent) {
46 match event {
47 SysEvent::Update => self.syst.disable_interrupt(),
48 }
49 }
50
51 pub fn reset(&mut self) {
53 self.syst.clear_current();
56 }
57}
58
59pub trait SysTimerInit: Sized {
60 fn counter_hz(self, mcu: &Mcu) -> SysCounterHz;
62
63 fn counter<const FREQ: u32>(self, mcu: &Mcu) -> SysCounter<FREQ>;
65 fn counter_us(self, mcu: &Mcu) -> SysCounterUs {
67 self.counter::<1_000_000>(mcu)
68 }
69 fn delay(self, mcu: &Mcu) -> SysDelay;
71}
72
73impl SysTimerInit for SYST {
74 fn counter_hz(self, mcu: &Mcu) -> SysCounterHz {
75 SystemTimer::syst(self, mcu).counter_hz()
76 }
77 fn counter<const FREQ: u32>(self, mcu: &Mcu) -> SysCounter<FREQ> {
78 SystemTimer::syst(self, mcu).counter()
79 }
80 fn delay(self, mcu: &Mcu) -> SysDelay {
81 SystemTimer::syst_external(self, mcu).delay()
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}