stm32f1_hal/timer/
syst.rs1use super::*;
4use crate::Mcu;
5use crate::os_trait::{utils::FrequencyHolder, *};
6use core::ops::{Deref, DerefMut};
7use cortex_m::peripheral::{SYST, syst::SystClkSource};
8use fugit::{HertzU32, TimerDurationU32, TimerInstantU32};
9
10pub trait SysTimerInit: Sized {
11 fn counter_hz(self, mcu: &Mcu) -> SysCounterHz;
13 fn counter<const FREQ: u32>(self, mcu: &Mcu) -> SysCounter<FREQ>;
15 fn counter_us(self, mcu: &Mcu) -> SysCounterUs {
17 self.counter::<1_000_000>(mcu)
18 }
19 fn store_tick_frequency(&mut self, mcu: &Mcu);
21}
22
23impl SysTimerInit for SYST {
24 fn counter_hz(self, mcu: &Mcu) -> SysCounterHz {
25 SystemTimer::syst(self, mcu).counter_hz()
26 }
27 fn counter<const FREQ: u32>(self, mcu: &Mcu) -> SysCounter<FREQ> {
28 SystemTimer::syst(self, mcu).counter()
29 }
30 fn store_tick_frequency(&mut self, mcu: &Mcu) {
31 let clk = match self.get_clock_source() {
32 SystClkSource::Core => mcu.rcc.clocks.hclk(),
33 SystClkSource::External => mcu.rcc.clocks.hclk() / 8,
34 };
35 FREQUENCY.set(KilohertzU32::Hz(clk.to_Hz()));
36 }
37}
38
39pub static FREQUENCY: FrequencyHolder = FrequencyHolder::new(KilohertzU32::MHz(1));
40
41pub struct SystemTimer {
42 pub(super) syst: SYST,
43 pub(super) clk: HertzU32,
44}
45impl SystemTimer {
46 pub fn syst(mut syst: SYST, mcu: &Mcu) -> Self {
48 syst.set_clock_source(SystClkSource::Core);
49 let clk = mcu.rcc.clocks.hclk();
50 FREQUENCY.set(KilohertzU32::Hz(clk.to_Hz()));
51 Self { syst, clk }
52 }
53
54 pub fn syst_external(mut syst: SYST, mcu: &Mcu) -> Self {
56 syst.set_clock_source(SystClkSource::External);
57 let clk = mcu.rcc.clocks.hclk() / 8;
58 FREQUENCY.set(KilohertzU32::Hz(clk.to_Hz()));
59 Self { syst, clk }
60 }
61
62 pub fn release(self) -> SYST {
63 self.syst
64 }
65
66 pub fn listen(&mut self, event: SysEvent) {
68 match event {
69 SysEvent::Update => self.syst.enable_interrupt(),
70 }
71 }
72
73 pub fn unlisten(&mut self, event: SysEvent) {
75 match event {
76 SysEvent::Update => self.syst.disable_interrupt(),
77 }
78 }
79
80 pub fn reset(&mut self) {
82 self.syst.clear_current();
85 }
86}
87
88impl SystemTimer {
91 pub fn counter_hz(self) -> SysCounterHz {
93 SysCounterHz(self)
94 }
95
96 pub fn counter<const FREQ: u32>(self) -> SysCounter<FREQ> {
98 SysCounter(self)
99 }
100
101 pub fn counter_us(self) -> SysCounterUs {
103 SysCounter(self)
104 }
105}
106
107pub struct SysCounterHz(SystemTimer);
109
110impl Deref for SysCounterHz {
111 type Target = SystemTimer;
112 fn deref(&self) -> &Self::Target {
113 &self.0
114 }
115}
116
117impl DerefMut for SysCounterHz {
118 fn deref_mut(&mut self) -> &mut Self::Target {
119 &mut self.0
120 }
121}
122
123impl SysCounterHz {
124 pub fn start(&mut self, timeout: HertzU32) -> Result<(), Error> {
125 let rvr = self.clk.raw() / timeout.raw() - 1;
126
127 if rvr >= (1 << 24) {
128 return Err(Error::WrongAutoReload);
129 }
130
131 self.syst.set_reload(rvr);
132 self.syst.clear_current();
133 self.syst.enable_counter();
134
135 Ok(())
136 }
137
138 pub fn wait(&mut self) -> nb::Result<(), Error> {
139 if self.syst.has_wrapped() {
140 Ok(())
141 } else {
142 Err(nb::Error::WouldBlock)
143 }
144 }
145
146 pub fn cancel(&mut self) -> Result<(), Error> {
147 if !self.syst.is_counter_enabled() {
148 return Err(Error::Disabled);
149 }
150
151 self.syst.disable_counter();
152 Ok(())
153 }
154}
155
156pub type SysCounterUs = SysCounter<1_000_000>;
157
158pub struct SysCounter<const FREQ: u32>(SystemTimer);
160
161impl<const FREQ: u32> Deref for SysCounter<FREQ> {
162 type Target = SystemTimer;
163 fn deref(&self) -> &Self::Target {
164 &self.0
165 }
166}
167
168impl<const FREQ: u32> DerefMut for SysCounter<FREQ> {
169 fn deref_mut(&mut self) -> &mut Self::Target {
170 &mut self.0
171 }
172}
173
174impl<const FREQ: u32> SysCounter<FREQ> {
175 pub fn listen(&mut self, event: SysEvent) {
177 match event {
178 SysEvent::Update => self.syst.enable_interrupt(),
179 }
180 }
181
182 pub fn unlisten(&mut self, event: SysEvent) {
184 match event {
185 SysEvent::Update => self.syst.disable_interrupt(),
186 }
187 }
188
189 pub fn now(&self) -> TimerInstantU32<FREQ> {
190 TimerInstantU32::from_ticks(SYST::get_current() / (self.clk.raw() / FREQ))
191 }
192
193 pub fn start(&mut self, timeout: TimerDurationU32<FREQ>) -> Result<(), Error> {
194 let rvr = timeout.ticks() * (self.clk.raw() / FREQ) - 1;
195
196 if rvr >= (1 << 24) {
197 return Err(Error::WrongAutoReload);
198 }
199
200 self.syst.set_reload(rvr);
201 self.syst.clear_current();
202 self.syst.enable_counter();
203
204 Ok(())
205 }
206
207 pub fn wait(&mut self) -> nb::Result<(), Error> {
208 if self.syst.has_wrapped() {
209 Ok(())
210 } else {
211 Err(nb::Error::WouldBlock)
212 }
213 }
214
215 pub fn cancel(&mut self) -> Result<(), Error> {
216 if !self.syst.is_counter_enabled() {
217 return Err(Error::Disabled);
218 }
219
220 self.syst.disable_counter();
221 Ok(())
222 }
223}
224
225#[derive(Copy, Clone)]
229pub struct SysTickInstant {
230 tick: u32,
231}
232impl TickInstant for SysTickInstant {
233 fn frequency() -> KilohertzU32 {
234 FREQUENCY.get()
235 }
236
237 #[inline(always)]
238 fn now() -> Self {
239 Self {
240 tick: SYST::get_current(),
241 }
242 }
243
244 #[inline(always)]
245 fn tick_since(self, earlier: Self) -> u32 {
246 if self.tick <= earlier.tick {
247 earlier.tick - self.tick
248 } else {
249 earlier.tick + (SYST::get_reload() - self.tick + 1)
250 }
251 }
252}