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