|
2 | 2 |
|
3 | 3 | use cast::{u16, u32};
|
4 | 4 | use cortex_m::peripheral::syst::SystClkSource;
|
5 |
| -use cortex_m::peripheral::SYST; |
| 5 | +use cortex_m::peripheral::{DCB, DWT, SYST}; |
6 | 6 | use embedded_hal::timer::{Cancel, CountDown, Periodic};
|
7 | 7 | use void::Void;
|
8 | 8 |
|
@@ -170,6 +170,57 @@ impl Cancel for Timer<SYST> {
|
170 | 170 |
|
171 | 171 | impl Periodic for Timer<SYST> {}
|
172 | 172 |
|
| 173 | +/// A monotonic non-decreasing timer |
| 174 | +/// |
| 175 | +/// This uses the timer in the debug watch trace peripheral. This means, that if the |
| 176 | +/// core is stopped, the timer does not count up. This may be relevant if you are using |
| 177 | +/// cortex_m_semihosting::hprintln for debugging in which case the timer will be stopped |
| 178 | +/// while printing |
| 179 | +#[derive(Clone, Copy)] |
| 180 | +pub struct MonoTimer { |
| 181 | + frequency: Hertz, |
| 182 | +} |
| 183 | + |
| 184 | +impl MonoTimer { |
| 185 | + /// Creates a new `Monotonic` timer |
| 186 | + pub fn new(mut dwt: DWT, mut dcb: DCB, clocks: Clocks) -> Self { |
| 187 | + dcb.enable_trace(); |
| 188 | + dwt.enable_cycle_counter(); |
| 189 | + |
| 190 | + // now the CYCCNT counter can't be stopped or reset |
| 191 | + drop(dwt); |
| 192 | + |
| 193 | + MonoTimer { |
| 194 | + frequency: clocks.hclk(), |
| 195 | + } |
| 196 | + } |
| 197 | + |
| 198 | + /// Returns the frequency at which the monotonic timer is operating at |
| 199 | + pub fn frequency(self) -> Hertz { |
| 200 | + self.frequency |
| 201 | + } |
| 202 | + |
| 203 | + /// Returns an `Instant` corresponding to "now" |
| 204 | + pub fn now(self) -> Instant { |
| 205 | + Instant { |
| 206 | + now: DWT::get_cycle_count(), |
| 207 | + } |
| 208 | + } |
| 209 | +} |
| 210 | + |
| 211 | +/// A measurement of a monotonically non-decreasing clock |
| 212 | +#[derive(Clone, Copy)] |
| 213 | +pub struct Instant { |
| 214 | + now: u32, |
| 215 | +} |
| 216 | + |
| 217 | +impl Instant { |
| 218 | + /// Ticks elapsed since the `Instant` was created |
| 219 | + pub fn elapsed(self) -> u32 { |
| 220 | + DWT::get_cycle_count().wrapping_sub(self.now) |
| 221 | + } |
| 222 | +} |
| 223 | + |
173 | 224 | macro_rules! hal {
|
174 | 225 | ($($TIM:ident: ($tim:ident, $en_bit:expr, $reset_bit:expr, $apbenr:ident, $apbrstr:ident, $pclk:ident, $ppre:ident),)+) => {
|
175 | 226 | $(
|
|
0 commit comments