1use core::{
4 future::Future,
5 pin::Pin,
6 task::{Context, Poll, Waker},
7};
8use embedded_hal::timer::CountDown;
9use stm32f1xx_hal::{
10 pac::{TIM2, TIM3},
11 time::U32Ext,
12 timer::{CountDownTimer, Event, Timer},
13};
14
15pub struct AsyncTimer<T>(T);
27
28impl<T> AsMut<T> for AsyncTimer<T> {
29 fn as_mut(&mut self) -> &mut T {
30 &mut self.0
31 }
32}
33
34impl<T> AsyncTimer<T>
35where
36 T: CountDown,
37{
38 pub fn delay_for<C>(&mut self, count: C) -> Delay<'_, T>
40 where
41 C: Into<T::Time>,
42 {
43 self.as_mut().start(count);
44 Delay(&mut self.0)
45 }
46}
47
48#[must_use = "futures do nothing unless you `.await` or poll them"]
52pub struct Delay<'a, T>(&'a mut T);
53
54impl<T> AsMut<T> for Delay<'_, T> {
55 fn as_mut(&mut self) -> &mut T {
56 self.0
57 }
58}
59
60macro_rules! timer {
61 ($(
62 $TIMX:ident
63 ),+) => {
64 $(
65 impl AsyncTimer<CountDownTimer<$TIMX>> {
66 pub fn release(self) -> $TIMX {
68 self.0.release()
69 }
70 }
71
72 impl From<Timer<$TIMX>> for AsyncTimer<CountDownTimer<$TIMX>> {
73 fn from(timer: Timer<$TIMX>) -> Self {
74 let mut count_down_timer = timer.start_count_down(1.hz());
75 count_down_timer.listen(Event::Update);
76 Self(count_down_timer)
77 }
78 }
79
80 impl Future for Delay<'_, CountDownTimer<$TIMX>> {
81 type Output = ();
82
83 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
84 use nb::{Error, Result};
85
86 match self.get_mut().as_mut().wait() {
87 Result::Ok(ok) => Poll::Ready(ok),
88 Result::Err(Error::Other(err)) => void::unreachable(err),
89 Result::Err(Error::WouldBlock) => {
90 waker_interrupt!($TIMX, cx.waker().clone());
91 Poll::Pending
92 }
93 }
94 }
95 }
96 )+
97 }
98}
99
100timer!(TIM2, TIM3);