Skip to content

Commit e358da3

Browse files
bors[bot]dflemstrrichardeoin
authored
Merge #129
129: Add a set_timeout method for timers r=hargoniX a=dflemstr I have a use-case where I need to set a specific timer timeout (using interrupts). Of course it would be possible to convert the delay into a frequency, but then it would involve one division (delay -> Hz) and another one back (Hz -> delay). It seemed more natural to support duration delays directly. It might also make sense to use `CountDown<Time=Duration>` as well, but since there is already a `CountDown<Time=Hz>` I couldn't add a conflicting one. However it might make sense to reconsider whether it makes sense to measure a duration in Hz, as is currently the case in this crate? Co-authored-by: David Flemström <[email protected]> Co-authored-by: Richard Meadows <[email protected]>
2 parents 4b5387a + 54b9082 commit e358da3

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/time.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Time units
22
33
use core::fmt;
4+
use core::time::Duration;
45
use cortex_m::peripheral::DWT;
56

67
/// Bits per second
@@ -130,6 +131,13 @@ impl Into<Hertz> for MilliSeconds {
130131
}
131132
}
132133

134+
// Into core::time::Duration
135+
impl Into<Duration> for MilliSeconds {
136+
fn into(self) -> Duration {
137+
Duration::from_millis(self.0 as u64)
138+
}
139+
}
140+
133141
// /// A monotonic nondecreasing timer
134142
// #[derive(Clone, Copy)]
135143
// pub struct MonoTimer {

src/timer.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// TODO: on the h7x3 at least, only TIM2, TIM3, TIM4, TIM5 can support 32 bits.
44
// TIM1 is 16 bit.
55

6+
use core::convert::TryFrom;
67
use core::marker::PhantomData;
78

89
use crate::hal::timer::{CountDown, Periodic};
@@ -227,6 +228,43 @@ macro_rules! hal {
227228
let frequency = self.timeout.0;
228229
let ticks = clk / frequency;
229230

231+
self.set_timeout_ticks(ticks);
232+
}
233+
234+
/// Sets the timer period from a time duration
235+
///
236+
/// ```
237+
/// // Set timeout to 100ms
238+
/// timer.set_timeout(100.ms());
239+
/// ```
240+
///
241+
/// Alternatively, the duration can be set using the
242+
/// core::time::Duration type
243+
///
244+
/// ```
245+
/// let duration = core::time::Duration::from_nanos(2_500);
246+
///
247+
/// // Set timeout to 2.5µs
248+
/// timer.set_timeout(duration);
249+
/// ```
250+
pub fn set_timeout<T>(&mut self, timeout: T)
251+
where
252+
T: Into<core::time::Duration>
253+
{
254+
const NANOS_PER_SECOND: u64 = 1_000_000_000;
255+
let timeout = timeout.into();
256+
257+
let clk = self.clk as u64;
258+
let ticks = u32::try_from(
259+
clk * timeout.as_secs() +
260+
clk * u64::from(timeout.subsec_nanos()) / NANOS_PER_SECOND,
261+
)
262+
.unwrap_or(u32::max_value());
263+
264+
self.set_timeout_ticks(ticks.max(1));
265+
}
266+
267+
fn set_timeout_ticks(&mut self, ticks: u32) {
230268
let psc = u16((ticks - 1) / (1 << 16)).unwrap();
231269
self.tim.psc.write(|w| { w.psc().bits(psc) });
232270

0 commit comments

Comments
 (0)