|
2 | 2 |
|
3 | 3 | use crate::hal::timer::{CountDown, Periodic};
|
4 | 4 | use crate::pac::{TIM1, TIM2, TIM3, TIM4};
|
5 |
| -use cast::{u16, u32}; |
| 5 | +use cast::{u16, u32, u64}; |
6 | 6 | use cortex_m::peripheral::syst::SystClkSource;
|
7 | 7 | use cortex_m::peripheral::SYST;
|
8 | 8 | use nb;
|
@@ -73,6 +73,26 @@ impl Timer<SYST> {
|
73 | 73 | }
|
74 | 74 | }
|
75 | 75 |
|
| 76 | + /// Resets the timer |
| 77 | + pub fn reset(&mut self) { |
| 78 | + // According to the Cortex-M3 Generic User Guide, the interrupt request is only generated |
| 79 | + // when the counter goes from 1 to 0, so writing zero should not trigger an interrupt |
| 80 | + self.tim.clear_current(); |
| 81 | + } |
| 82 | + |
| 83 | + /// Returns the number of microseconds since the last update event. |
| 84 | + /// *NOTE:* This method is not a very good candidate to keep track of time, because |
| 85 | + /// it is very easy to lose an update event. |
| 86 | + pub fn micros_since(&self) -> u32 { |
| 87 | + let reload_value = SYST::get_reload(); |
| 88 | + let timer_clock = u64(self.clocks.sysclk().0); |
| 89 | + let ticks = u64(reload_value - SYST::get_current()); |
| 90 | + |
| 91 | + // It is safe to make this cast since the maximum ticks is (2^24 - 1) and the minimum sysclk |
| 92 | + // is 4Mhz, which gives a maximum period of ~4.2 seconds which is < (2^32 - 1) microsenconds |
| 93 | + u32(1_000_000 * ticks / timer_clock).unwrap() |
| 94 | + } |
| 95 | + |
76 | 96 | /// Stops the timer
|
77 | 97 | pub fn stop(&mut self) {
|
78 | 98 | self.tim.disable_counter();
|
@@ -161,15 +181,27 @@ macro_rules! hal {
|
161 | 181 | self.tim
|
162 | 182 | }
|
163 | 183 |
|
164 |
| - /// Returns the current counter value |
165 |
| - pub fn count(&self) -> u16 { |
166 |
| - self.tim.cnt.read().cnt().bits() |
| 184 | + /// Returns the number of microseconds since the last update event. |
| 185 | + /// *NOTE:* This method is not a very good candidate to keep track of time, because |
| 186 | + /// it is very easy to lose an update event. |
| 187 | + pub fn micros_since(&self) -> u32 { |
| 188 | + let timer_clock = $TIMX::get_clk(&self.clocks).0; |
| 189 | + let psc = u32(self.tim.psc.read().psc().bits()); |
| 190 | + |
| 191 | + // freq_divider is always bigger than 0, since (psc + 1) is always less than |
| 192 | + // timer_clock |
| 193 | + let freq_divider = u64(timer_clock / (psc + 1)); |
| 194 | + let cnt = u64(self.tim.cnt.read().cnt().bits()); |
| 195 | + |
| 196 | + // It is safe to make this cast, because the maximum timer period in this HAL is |
| 197 | + // 1s (1Hz), then 1 second < (2^32 - 1) microseconds |
| 198 | + u32(1_000_000 * cnt / freq_divider).unwrap() |
167 | 199 | }
|
168 | 200 |
|
169 | 201 | /// Resets the counter and generates an update event
|
170 | 202 | pub fn reset(&mut self) {
|
171 | 203 | // Sets the URS bit to prevent an interrupt from being triggered by
|
172 |
| - // the UG bit. |
| 204 | + // the UG bit |
173 | 205 | self.tim.cr1.modify(|_, w| w.urs().set_bit());
|
174 | 206 |
|
175 | 207 | self.tim.egr.write(|w| w.ug().set_bit());
|
|
0 commit comments