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