Skip to content

Commit a61a773

Browse files
bors[bot]bschwindtherealprof
authored
Merge #238
238: Port MonoTimer from stm32f1xx-hal r=therealprof a=bschwind This is a straight-up copy of the `MonoTimer` from the `stm32f1xx-hal` crate: https://github.com/stm32-rs/stm32f1xx-hal/blob/d976ba2312fae2f1b15707573bc5d82ea00ba73f/src/time.rs#L229-L278 I wanted the same functionality in a stm32f4-based project. I tested it on an `stm32f411CE` [WeAct USB C board](https://stm32-base.org/boards/STM32F401CEU6-WeAct-Black-Pill-V3.0), and it seems to behave properly. Co-authored-by: Brian Schwind <[email protected]> Co-authored-by: Daniel Egger <[email protected]>
2 parents be04db0 + a6d4c65 commit a61a773

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3737
- Add initial DMA support
3838
- Allow specification of ADC reference voltage in ADC configuraton structure
3939
- Added support for hardware-based CRC32 functionality
40+
- Add `MonoTimer` and `Instant` structs for basic time measurement.
4041

4142
### Fixed
4243

src/timer.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use cast::{u16, u32};
44
use cortex_m::peripheral::syst::SystClkSource;
5-
use cortex_m::peripheral::SYST;
5+
use cortex_m::peripheral::{DCB, DWT, SYST};
66
use embedded_hal::timer::{Cancel, CountDown, Periodic};
77
use void::Void;
88

@@ -170,6 +170,57 @@ impl Cancel for Timer<SYST> {
170170

171171
impl Periodic for Timer<SYST> {}
172172

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+
173224
macro_rules! hal {
174225
($($TIM:ident: ($tim:ident, $en_bit:expr, $reset_bit:expr, $apbenr:ident, $apbrstr:ident, $pclk:ident, $ppre:ident),)+) => {
175226
$(

0 commit comments

Comments
 (0)