1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::pac::TIMER6;
use crate::rcu::{Clocks, APB1};
use crate::unit::Hertz;
use embedded_hal::blocking::delay::DelayMs;
use embedded_hal::timer::CountDown;
use core::convert::Infallible;
pub struct Timer<TIMER> {
timer: TIMER,
clock_scaler: u16,
clock_frequency: Hertz,
}
impl Timer<TIMER6> {
pub fn timer6(timer: TIMER6, clock: Clocks, apb1: &mut APB1) -> Self {
riscv::interrupt::free(|_| {
apb1.en().modify(|_, w| w.timer6en().set_bit());
apb1.rst().write(|w| w.timer6rst().set_bit());
apb1.rst().write(|w| w.timer6rst().clear_bit());
});
Timer {
timer,
clock_scaler: 1000,
clock_frequency: clock.ck_apb1(),
}
}
}
impl<TIMER> Timer<TIMER> {
pub fn release(self) -> TIMER {
self.timer
}
}
impl<T: Into<u32>> DelayMs<T> for Timer<TIMER6> {
type Error = Infallible;
fn try_delay_ms(&mut self, ms: T) -> Result<(), Self::Error> {
let count = (ms.into() * self.clock_frequency.0) / (self.clock_scaler as u32 * 1000);
if count > u16::max_value() as u32 {
panic!("can not delay that long");
}
self.try_start(count as u16).ok();
nb::block!(self.try_wait()).ok();
Ok(())
}
}
impl CountDown for Timer<TIMER6> {
type Error = Infallible;
type Time = u16;
fn try_start<T>(&mut self, count: T) -> Result<(), Self::Error>
where
T: Into<Self::Time>,
{
let c = count.into();
riscv::interrupt::free(|_| {
self.timer
.psc
.write(|w| unsafe { w.psc().bits(self.clock_scaler) });
self.timer.intf.write(|w| w.upif().clear_bit());
self.timer.swevg.write(|w| w.upg().set_bit());
self.timer.intf.write(|w| w.upif().clear_bit());
self.timer.car.modify(|_, w| unsafe { w.carl().bits(c) });
self.timer.ctl0.modify(|_, w| w.cen().set_bit());
});
Ok(())
}
fn try_wait(&mut self) -> nb::Result<(), Self::Error> {
let flag = self.timer.intf.read().upif().bit_is_set();
if flag {
Ok(())
} else {
Err(nb::Error::WouldBlock)
}
}
}