Skip to content

Commit 36dde28

Browse files
authored
Merge pull request #168 from stm32-rs/free_running_timer
Started a free running timer based on normal timers
2 parents 2f64d51 + 18d90ec commit 36dde28

File tree

1 file changed

+72
-9
lines changed

1 file changed

+72
-9
lines changed

src/timer.rs

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub enum Event {
2424
}
2525

2626
macro_rules! hal {
27-
($($TIM:ident: ($tim:ident, $timXen:ident, $timXrst:ident, $apb:ident),)+) => {
27+
($($TIM:ident: ($tim:ident, $frname:ident, $timXen:ident, $timXrst:ident, $apb:ident, $width:ident),)+) => {
2828
$(
2929
impl Periodic for Timer<$TIM> {}
3030

@@ -97,6 +97,63 @@ macro_rules! hal {
9797
timer
9898
}
9999

100+
/// Start a free running, monotonic, timer running at some specific frequency.
101+
///
102+
/// May generate events on overflow of the timer.
103+
pub fn $frname<T>(
104+
tim: $TIM,
105+
clocks: Clocks,
106+
frequency: T,
107+
event_on_overflow: bool,
108+
apb: &mut $apb,
109+
) -> Self
110+
where
111+
T: Into<Hertz>,
112+
{
113+
apb.enr().modify(|_, w| w.$timXen().set_bit());
114+
apb.rstr().modify(|_, w| w.$timXrst().set_bit());
115+
apb.rstr().modify(|_, w| w.$timXrst().clear_bit());
116+
117+
let frequency = frequency.into();
118+
let psc = clocks.pclk1().0 / frequency.0 - 1;
119+
120+
debug_assert!(clocks.pclk1().0 >= frequency.0);
121+
debug_assert!(frequency.0 > 0);
122+
debug_assert!(psc <= core::u16::MAX.into());
123+
124+
tim.psc.write(|w| w.psc().bits((psc as u16).into()) );
125+
let max = core::$width::MAX;
126+
tim.arr.write(|w| unsafe { w.bits(max.into()) });
127+
128+
// Trigger an update event to load the prescaler value to the clock
129+
tim.egr.write(|w| w.ug().set_bit());
130+
131+
132+
// The above line raises an update event which will indicate
133+
// that the timer is already finished. Since this is not the case,
134+
// it should be cleared
135+
tim.sr.modify(|_, w| w.uif().clear_bit());
136+
137+
// start counter
138+
tim.cr1.modify(|_, w| {
139+
w.cen().set_bit();
140+
141+
if event_on_overflow {
142+
w.udis().clear_bit();
143+
} else {
144+
w.udis().set_bit();
145+
}
146+
147+
w
148+
});
149+
150+
Timer {
151+
clocks,
152+
tim,
153+
timeout: frequency,
154+
}
155+
}
156+
100157
/// Starts listening for an `event`
101158
pub fn listen(&mut self, event: Event) {
102159
match event {
@@ -137,6 +194,12 @@ macro_rules! hal {
137194
self.tim.sr.modify(|_, w| w.uif().clear_bit());
138195
}
139196

197+
/// Get the count of the timer.
198+
pub fn count() -> $width {
199+
let cnt = unsafe { (*$TIM::ptr()).cnt.read() };
200+
cnt.cnt().bits()
201+
}
202+
140203
/// Releases the TIM peripheral
141204
pub fn free(self) -> $TIM {
142205
// pause counter
@@ -149,16 +212,16 @@ macro_rules! hal {
149212
}
150213

151214
hal! {
152-
TIM2: (tim2, tim2en, tim2rst, APB1R1),
153-
TIM6: (tim6, tim6en, tim6rst, APB1R1),
154-
TIM7: (tim7, tim7en, tim7rst, APB1R1),
155-
TIM15: (tim15, tim15en, tim15rst, APB2),
156-
TIM16: (tim16, tim16en, tim16rst, APB2),
215+
TIM2: (tim2, free_running_tim2, tim2en, tim2rst, APB1R1, u32),
216+
TIM6: (tim6, free_running_tim6, tim6en, tim6rst, APB1R1, u16),
217+
TIM7: (tim7, free_running_tim7, tim7en, tim7rst, APB1R1, u16),
218+
TIM15: (tim15, free_running_tim15, tim15en, tim15rst, APB2, u16),
219+
TIM16: (tim16, free_running_tim16, tim16en, tim16rst, APB2, u16),
157220
}
158221

159222
#[cfg(any(feature = "stm32l4x5", feature = "stm32l4x6",))]
160223
hal! {
161-
TIM4: (tim4, tim4en, tim4rst, APB1R1),
162-
TIM5: (tim5, tim5en, tim5rst, APB1R1),
163-
TIM17: (tim17, tim17en, tim17rst, APB2),
224+
TIM4: (tim4, free_running_tim4, tim4en, tim4rst, APB1R1, u16),
225+
TIM5: (tim5, free_running_tim5, tim5en, tim5rst, APB1R1, u32),
226+
TIM17: (tim17, free_running_tim17, tim17en, tim17rst, APB2, u16),
164227
}

0 commit comments

Comments
 (0)