stm32f1xx_hal/timer/
monotonic.rs1use super::{FTimer, Instance};
4use crate::rcc::Rcc;
5use core::ops::{Deref, DerefMut};
6pub use fugit::{self, ExtU32};
7use rtic_monotonic::Monotonic;
8
9pub struct MonoTimer<TIM, const FREQ: u32> {
10 timer: FTimer<TIM, FREQ>,
11 ovf: u32,
12}
13
14impl<TIM, const FREQ: u32> Deref for MonoTimer<TIM, FREQ> {
15 type Target = FTimer<TIM, FREQ>;
16 fn deref(&self) -> &Self::Target {
17 &self.timer
18 }
19}
20
21impl<TIM, const FREQ: u32> DerefMut for MonoTimer<TIM, FREQ> {
22 fn deref_mut(&mut self) -> &mut Self::Target {
23 &mut self.timer
24 }
25}
26
27pub type MonoTimerUs<TIM> = MonoTimer<TIM, 1_000_000>;
29
30impl<TIM: Instance, const FREQ: u32> MonoTimer<TIM, FREQ> {
31 pub fn release(mut self) -> FTimer<TIM, FREQ> {
33 self.tim.cr1_reset();
35 self.timer
36 }
37}
38
39pub trait MonoTimerExt: Sized {
40 fn monotonic<const FREQ: u32>(self, rcc: &mut Rcc) -> MonoTimer<Self, FREQ>;
41 fn monotonic_us(self, rcc: &mut Rcc) -> MonoTimer<Self, 1_000_000> {
42 self.monotonic::<1_000_000>(rcc)
43 }
44}
45
46macro_rules! mono {
47 ($TIM:ty) => {
48 impl MonoTimerExt for $TIM {
49 fn monotonic<const FREQ: u32>(self, rcc: &mut Rcc) -> MonoTimer<Self, FREQ> {
50 FTimer::new(self, rcc).monotonic()
51 }
52 }
53
54 impl<const FREQ: u32> FTimer<$TIM, FREQ> {
55 pub fn monotonic(self) -> MonoTimer<$TIM, FREQ> {
56 MonoTimer::<$TIM, FREQ>::_new(self)
57 }
58 }
59
60 impl<const FREQ: u32> MonoTimer<$TIM, FREQ> {
61 fn _new(timer: FTimer<$TIM, FREQ>) -> Self {
62 timer.tim.arr().write(|w| w.arr().set(u16::MAX));
64 timer.tim.egr().write(|w| w.ug().set_bit());
66
67 timer.tim.sr().modify(|_, w| w.uif().clear_bit());
70 timer.tim.cr1().modify(|_, w| {
71 w.cen().set_bit();
73 w.udis().clear_bit();
75 w.urs().set_bit()
77 });
78
79 Self { timer, ovf: 0 }
80 }
81 }
82
83 impl<const FREQ: u32> Monotonic for MonoTimer<$TIM, FREQ> {
84 type Instant = fugit::TimerInstantU32<FREQ>;
85 type Duration = fugit::TimerDurationU32<FREQ>;
86
87 unsafe fn reset(&mut self) {
88 self.tim.dier().modify(|_, w| w.cc1ie().set_bit());
89 }
90
91 #[inline(always)]
92 fn now(&mut self) -> Self::Instant {
93 let cnt = self.tim.cnt().read().cnt().bits() as u32;
94
95 let ovf = if self.tim.sr().read().uif().bit_is_set() {
98 0x10000
99 } else {
100 0
101 };
102
103 Self::Instant::from_ticks(cnt.wrapping_add(ovf).wrapping_add(self.ovf))
104 }
105
106 fn set_compare(&mut self, instant: Self::Instant) {
107 let now = self.now();
108 let cnt = self.tim.cnt().read().cnt().bits();
109
110 let val = match instant.checked_duration_since(now) {
113 None => cnt.wrapping_add(0xffff), Some(x) if x.ticks() <= 0xffff => instant.duration_since_epoch().ticks() as u16, Some(_) => cnt.wrapping_add(0xffff), };
117
118 self.tim.ccr1().write(|w| w.ccr().set(val));
119 }
120
121 fn clear_compare_flag(&mut self) {
122 self.tim.sr().modify(|_, w| w.cc1if().clear_bit());
123 }
124
125 fn on_interrupt(&mut self) {
126 if self.tim.sr().read().uif().bit_is_set() {
128 self.tim.sr().modify(|_, w| w.uif().clear_bit());
129
130 self.ovf += 0x10000;
131 }
132 }
133
134 #[inline(always)]
135 fn zero() -> Self::Instant {
136 Self::Instant::from_ticks(0)
137 }
138 }
139 };
140}
141
142mono!(crate::pac::TIM2);
143mono!(crate::pac::TIM3);
144
145#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
146mono!(crate::pac::TIM1);
147
148#[cfg(feature = "medium")]
149mono!(crate::pac::TIM4);
150
151#[cfg(any(feature = "high", feature = "connectivity"))]
152mono!(crate::pac::TIM5);
153
154#[cfg(all(feature = "stm32f103", feature = "high"))]
155mono!(crate::pac::TIM8);