esp_01/timing.rs
1use nb;
2use core::convert::Infallible;
3
4/**
5 A countdown timer which nonblockingly waits until the specified countdown
6 is completed. The countdown is started by calling `start`.
7
8 This trait is needed because `embedded_hal` currently does not have a standardised
9 measure of time.
10
11 The implementation of this trait will depend on your HAL implementation, but
12 here is a sample impl for the stm32f1xx_hal
13
14
15 ```rust
16 struct LongTimer<T> {
17 timer: Timer<T>,
18 milliseconds_remaining: u32,
19 }
20
21 impl<T> LongTimer<T>
22 where Timer<T>: CountDown<Time = Hertz> + Periodic
23 {
24 pub fn new(timer: Timer<T>) -> Self {
25 Self {
26 timer,
27 milliseconds_remaining: 0
28 }
29 }
30 fn process_tick(&mut self) -> nb::Result<(), Infallible>{
31 match self.milliseconds_remaining {
32 0 => Ok(()),
33 t @ 0..=1000 => {
34 self.milliseconds_remaining = 0;
35 self.timer.start(((1000. / t as f32) as u32).hz());
36 Err(nb::Error::WouldBlock)
37 }
38 _ => {
39 self.timer.start(1.hz());
40 self.milliseconds_remaining -= 1000;
41 Err(nb::Error::WouldBlock)
42 }
43 }
44 }
45 }
46
47 impl<T> esp01::LongTimer for LongTimer<T>
48 where Timer<T>: CountDown<Time = Hertz> + Periodic
49 {
50 fn wait(&mut self) -> nb::Result<(), Infallible> {
51 match self.timer.wait() {
52 Ok(_) => self.process_tick(),
53 Err(nb::Error::WouldBlock) => Err(nb::Error::WouldBlock),
54 Err(_void) => unreachable!() // The void type can not exist
55 }
56 }
57 fn start(&mut self, Millisecond(duration): Millisecond) {
58 self.milliseconds_remaining = duration;
59 // This will always return nb::WouldBlock (unless duration is 0)
60 self.process_tick().ok();
61 }
62
63 }
64 ```
65*/
66pub trait LongTimer {
67 /**
68 Returns Err(WouldBlock) if less time than `delay` has passed since `start_real`
69 was called and `Ok(())` if more time has passed.
70
71 If start_real hasn't been called yet, the behaviour is undefined
72 */
73 fn wait(&mut self) -> nb::Result<(), Infallible>;
74
75 /**
76 Start the count down for the specified amount of milliseconds.
77
78 The required accuracy depends on the duration. Above 1 second, the
79 requirements are very low.
80 */
81 fn start(&mut self, duration: Millisecond);
82}
83
84
85#[derive(Clone, Copy)]
86pub struct Second(pub u32);
87#[derive(Clone, Copy)]
88pub struct Millisecond(pub u32);
89
90impl From<Second> for Millisecond {
91 fn from(Second(duration): Second) -> Self {
92 return Millisecond(duration * 1000);
93 }
94}
95