stm32f4xx_hal/timer/
monotonic.rs1use super::{Channel, Event, FTimer, Flag, General, Instance, WithPwm};
3use crate::rcc::Clocks;
4use crate::ReadFlags;
5use core::ops::{Deref, DerefMut};
6pub use fugit::{self, ExtU32};
7use systick_monotonic::Systick;
8
9pub struct MonoTimer<TIM, const FREQ: u32>(FTimer<TIM, FREQ>);
10
11impl<TIM, const FREQ: u32> Deref for MonoTimer<TIM, FREQ> {
12 type Target = FTimer<TIM, FREQ>;
13 fn deref(&self) -> &Self::Target {
14 &self.0
15 }
16}
17
18impl<TIM, const FREQ: u32> DerefMut for MonoTimer<TIM, FREQ> {
19 fn deref_mut(&mut self) -> &mut Self::Target {
20 &mut self.0
21 }
22}
23
24pub type MonoTimerUs<TIM> = MonoTimer<TIM, 1_000_000>;
26pub type MonoTimer64Us<TIM> = MonoTimer64<TIM, 1_000_000>;
27
28impl<TIM: Instance, const FREQ: u32> MonoTimer<TIM, FREQ> {
29 pub fn release(mut self) -> FTimer<TIM, FREQ> {
31 self.tim.cr1_reset();
33 self.0
34 }
35}
36
37pub trait MonoTimerExt: Sized {
38 fn monotonic<const FREQ: u32>(self, clocks: &Clocks) -> MonoTimer<Self, FREQ>;
39 fn monotonic_us(self, clocks: &Clocks) -> MonoTimer<Self, 1_000_000> {
40 self.monotonic::<1_000_000>(clocks)
41 }
42}
43
44impl<TIM> MonoTimerExt for TIM
45where
46 Self: Instance + General<Width = u32> + WithPwm,
47{
48 fn monotonic<const FREQ: u32>(self, clocks: &Clocks) -> MonoTimer<Self, FREQ> {
49 FTimer::new(self, clocks).monotonic()
50 }
51}
52
53pub trait MonoTimer64Ext: Sized {
54 fn monotonic64<const FREQ: u32>(self, clocks: &Clocks) -> MonoTimer64<Self, FREQ>;
55 fn monotonic64_us(self, clocks: &Clocks) -> MonoTimer64<Self, 1_000_000> {
56 self.monotonic64::<1_000_000>(clocks)
57 }
58}
59
60impl<TIM> MonoTimer64Ext for TIM
61where
62 Self: Instance + General + WithPwm,
63{
64 fn monotonic64<const FREQ: u32>(self, clocks: &Clocks) -> MonoTimer64<Self, FREQ> {
65 FTimer::new(self, clocks).monotonic64()
66 }
67}
68
69pub trait SysMonoTimerExt: Sized {
70 fn monotonic<const FREQ: u32>(self, clocks: &Clocks) -> Systick<FREQ>;
71 fn monotonic_us(self, clocks: &Clocks) -> Systick<1_000_000> {
72 self.monotonic::<1_000_000>(clocks)
73 }
74}
75
76impl SysMonoTimerExt for cortex_m::peripheral::SYST {
77 fn monotonic<const FREQ: u32>(self, clocks: &Clocks) -> Systick<FREQ> {
78 Systick::new(self, clocks.hclk().raw())
79 }
80}
81
82impl<TIM, const FREQ: u32> FTimer<TIM, FREQ>
83where
84 TIM: Instance + General<Width = u32> + WithPwm,
85{
86 pub fn monotonic(mut self) -> MonoTimer<TIM, FREQ> {
87 unsafe {
88 self.tim.set_auto_reload_unchecked(TIM::max_auto_reload());
89 }
90 self.tim.trigger_update();
91 self.tim.start_free(false);
92 MonoTimer(self)
93 }
94}
95
96impl<TIM, const FREQ: u32> FTimer<TIM, FREQ>
97where
98 TIM: Instance + General + WithPwm,
99{
100 pub fn monotonic64(mut self) -> MonoTimer64<TIM, FREQ> {
101 unsafe {
102 self.tim.set_auto_reload_unchecked(TIM::max_auto_reload());
103 }
104 self.tim.trigger_update();
105 self.tim.start_free(true);
106 MonoTimer64 {
107 ftimer: self,
108 ovf: 0,
109 }
110 }
111}
112
113impl<TIM, const FREQ: u32> rtic_monotonic::Monotonic for MonoTimer<TIM, FREQ>
114where
115 TIM: Instance + General<Width = u32> + WithPwm,
116{
117 type Instant = fugit::TimerInstantU32<FREQ>;
118 type Duration = fugit::TimerDurationU32<FREQ>;
119
120 unsafe fn reset(&mut self) {
121 self.tim.listen_event(None, Some(Event::C1.into()));
122 self.tim.reset_counter();
123 }
124
125 #[inline(always)]
126 fn now(&mut self) -> Self::Instant {
127 Self::Instant::from_ticks(self.tim.read_count())
128 }
129
130 fn set_compare(&mut self, instant: Self::Instant) {
131 TIM::set_cc_value(Channel::C1 as u8, instant.duration_since_epoch().ticks());
132 }
133
134 fn clear_compare_flag(&mut self) {
135 self.tim.clear_interrupt_flag(Flag::C1.into());
136 }
137
138 #[inline(always)]
139 fn zero() -> Self::Instant {
140 Self::Instant::from_ticks(0)
141 }
142}
143
144pub struct MonoTimer64<TIM, const FREQ: u32> {
146 ftimer: FTimer<TIM, FREQ>,
147 ovf: u64,
148}
149
150impl<TIM, const FREQ: u32> Deref for MonoTimer64<TIM, FREQ> {
151 type Target = FTimer<TIM, FREQ>;
152 fn deref(&self) -> &Self::Target {
153 &self.ftimer
154 }
155}
156
157impl<TIM, const FREQ: u32> DerefMut for MonoTimer64<TIM, FREQ> {
158 fn deref_mut(&mut self) -> &mut Self::Target {
159 &mut self.ftimer
160 }
161}
162
163impl<TIM: Instance, const FREQ: u32> MonoTimer64<TIM, FREQ> {
164 fn is_overflow(&self) -> bool {
165 self.flags().contains(Flag::Update)
166 }
167}
168
169impl<TIM, const FREQ: u32> rtic_monotonic::Monotonic for MonoTimer64<TIM, FREQ>
171where
172 TIM: Instance + General + WithPwm,
173 TIM::Width: ArrWidth,
174 u64: From<TIM::Width>,
175 u32: From<TIM::Width>,
176{
177 const DISABLE_INTERRUPT_ON_EMPTY_QUEUE: bool = false;
179
180 type Instant = fugit::TimerInstantU64<FREQ>;
181 type Duration = fugit::TimerDurationU64<FREQ>;
182
183 fn now(&mut self) -> Self::Instant {
184 let cnt = self.tim.read_count();
185
186 let ovf = if self.is_overflow() {
189 TIM::Width::OVF_VALUE
190 } else {
191 0
192 };
193 Self::Instant::from_ticks(u64::from(cnt) + ovf + self.ovf)
194 }
195
196 fn zero() -> Self::Instant {
197 Self::Instant::from_ticks(0)
198 }
199
200 unsafe fn reset(&mut self) {
201 self.tim.listen_event(None, Some(Event::C1.into()));
203 self.tim.reset_counter();
204 }
205
206 fn set_compare(&mut self, instant: Self::Instant) {
207 let now = self.now();
208
209 let val: TIM::Width = match instant.checked_duration_since(now) {
212 None => TIM::Width::ONE, Some(x) if x.ticks() < TIM::Width::OVF_VALUE => {
214 TIM::Width::cast_u64(instant.duration_since_epoch().ticks())
215 } Some(_x) => self.tim.read_count().wrapping_add(TIM::Width::FOR_WRAP), };
218
219 TIM::set_cc_value(Channel::C1 as u8, u32::from(val));
220 }
221
222 fn clear_compare_flag(&mut self) {
223 self.tim.clear_interrupt_flag(Flag::C1.into());
224 }
225
226 fn on_interrupt(&mut self) {
227 if self.is_overflow() {
229 self.tim.clear_interrupt_flag(Flag::Update.into());
230
231 self.ovf += TIM::Width::OVF_VALUE;
232 }
233 }
234}
235
236trait ArrWidth {
237 const OVF_VALUE: u64;
238 const FOR_WRAP: Self;
239 const ONE: Self;
240 fn cast_u64(from: u64) -> Self;
241 fn wrapping_add(self, other: Self) -> Self;
242}
243
244impl ArrWidth for u16 {
245 const OVF_VALUE: u64 = 0x1_0000;
246 const FOR_WRAP: Self = 0xfffe;
247 const ONE: Self = 1;
248 fn cast_u64(from: u64) -> Self {
249 from as _
250 }
251 fn wrapping_add(self, other: Self) -> Self {
252 self.wrapping_add(other)
253 }
254}
255
256impl ArrWidth for u32 {
257 const OVF_VALUE: u64 = 0x1_0000_0000;
258 const FOR_WRAP: Self = 0xffff_fffe;
259 const ONE: Self = 1;
260 fn cast_u64(from: u64) -> Self {
261 from as _
262 }
263 fn wrapping_add(self, other: Self) -> Self {
264 self.wrapping_add(other)
265 }
266}