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