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