Skip to content

Commit 9472c6f

Browse files
committed
eh-1.0.0: reimplement DelayFromCountDownTimer for Timers and LpTimers
1 parent b9d9014 commit 9472c6f

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

src/delay.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,17 @@ use cortex_m::peripheral::SYST;
4343
use embedded_hal::delay::DelayNs;
4444
use void::Void;
4545

46+
use crate::block;
4647
use crate::rcc::CoreClocks;
48+
use crate::stm32::{LPTIM1, LPTIM2, LPTIM3};
49+
#[cfg(not(feature = "rm0455"))]
50+
use crate::stm32::{LPTIM4, LPTIM5};
51+
use crate::stm32::{
52+
TIM1, TIM12, TIM13, TIM14, TIM15, TIM16, TIM17, TIM2, TIM3, TIM4, TIM5,
53+
TIM6, TIM7, TIM8,
54+
};
55+
use crate::time::Hertz;
56+
use crate::timer::{Enabled, LpTimer, Timer};
4757

4858
pub trait DelayExt {
4959
fn delay(self, clocks: CoreClocks) -> Delay;
@@ -211,3 +221,75 @@ impl DelayNs for Delay {
211221
self.systick_delay_cycles(total_rvr);
212222
}
213223
}
224+
225+
/// Delay that implements [embedded_hal::blocking::delay] traits
226+
pub struct DelayFromCountDownTimer<TIM>(TIM);
227+
228+
impl<TIM> DelayFromCountDownTimer<TIM> {
229+
/// Creates a delay from a timer resource
230+
pub fn new(timer: TIM) -> Self {
231+
Self(timer)
232+
}
233+
/// Free the timer resource for other uses
234+
pub fn free(self) -> TIM {
235+
self.0
236+
}
237+
}
238+
239+
macro_rules! impl_delay_from_count_down_timer {
240+
($($TIMX:ty),+) => {
241+
$(
242+
impl DelayFromCountDownTimer<$TIMX>
243+
{
244+
fn delay_us_internal(&mut self, t: u32) {
245+
let mut time_left = t;
246+
247+
// Due to the LpTimer having only a 3 bit scaler, it is
248+
// possible that the max timeout we can set is
249+
// (128 * 65536) / clk_hz milliseconds.
250+
// Assuming the fastest clk_hz = 480Mhz this is roughly ~17ms,
251+
// or a frequency of ~57.2Hz. We use a 60Hz frequency for each
252+
// loop step here to ensure that we stay within these bounds.
253+
let looping_delay = 1_000_000 / 60;
254+
let looping_delay_hz = Hertz::from_raw(1_000_000 / looping_delay);
255+
256+
let _ = self.0.start(looping_delay_hz); // This method is infallible
257+
while time_left > looping_delay {
258+
block!(self.0.wait()).ok();
259+
time_left -= looping_delay;
260+
}
261+
262+
if time_left > 0 {
263+
// This method is infallible
264+
let _ = self.0.start(Hertz::from_raw(1_000_000 / time_left));
265+
block!(self.0.wait()).ok();
266+
}
267+
}
268+
}
269+
270+
impl DelayNs for DelayFromCountDownTimer<$TIMX> {
271+
fn delay_ns(&mut self, ns: u32) {
272+
// TODO(): This delay is 1000x longer than the intended duration!
273+
self.delay_us_internal(ns);
274+
}
275+
fn delay_us(&mut self, us: u32) {
276+
self.delay_us_internal(us);
277+
}
278+
}
279+
)+
280+
}
281+
}
282+
283+
impl_delay_from_count_down_timer! {
284+
Timer<TIM1>, Timer<TIM8>,
285+
Timer<TIM2>, Timer<TIM3>, Timer<TIM4>,
286+
Timer<TIM5>, Timer<TIM6>, Timer<TIM7>,
287+
Timer<TIM12>, Timer<TIM13>, Timer<TIM14>, Timer<TIM15>, Timer<TIM16>, Timer<TIM17>
288+
}
289+
impl_delay_from_count_down_timer! {
290+
LpTimer<LPTIM1, Enabled>, LpTimer<LPTIM2, Enabled>, LpTimer<LPTIM3, Enabled>
291+
}
292+
#[cfg(not(feature = "rm0455"))]
293+
impl_delay_from_count_down_timer! {
294+
LpTimer<LPTIM4, Enabled>, LpTimer<LPTIM5, Enabled>
295+
}

0 commit comments

Comments
 (0)