59 lines
1.7 KiB
Rust
59 lines
1.7 KiB
Rust
use rtic::Monotonic;
|
|
|
|
use stm32f1xx_hal::{
|
|
time::U32Ext,
|
|
pac::{RCC, TIM2},
|
|
rcc::Clocks,
|
|
};
|
|
|
|
pub struct MonoTimer<T, const FREQ: u32>(T);
|
|
|
|
impl<const FREQ: u32> MonoTimer<TIM2, FREQ> {
|
|
pub fn new(timer: TIM2, clocks: &Clocks) -> Self {
|
|
let rcc = unsafe { &(*RCC::ptr()) };
|
|
rcc.apb1enr.modify(|_, w| w.tim2en().set_bit());
|
|
rcc.apb1rstr.modify(|_, w| w.tim2rst().set_bit());
|
|
rcc.apb1rstr.modify(|_, w| w.tim2rst().clear_bit());
|
|
let prescaler: u32 = clocks.pclk1_tim().to_Hz() / FREQ - 1;
|
|
timer.psc.write(|w| w.psc().bits(prescaler as u16));
|
|
// set reload value to max
|
|
timer.arr.write(|w| unsafe { w.bits(u32::MAX) });
|
|
// set upcounting mode
|
|
timer.egr.write(|w| w.ug().set_bit());
|
|
// clear update interrupt flag
|
|
timer.sr.modify(|_, w| w.uif().clear_bit());
|
|
timer.cr1.modify(|_, w| w.cen().set_bit().udis().set_bit());
|
|
MonoTimer(timer)
|
|
}
|
|
}
|
|
|
|
impl<const FREQ: u32> Monotonic for MonoTimer<TIM2, FREQ> {
|
|
type Instant = fugit::TimerInstantU32<FREQ>;
|
|
type Duration = fugit::TimerDurationU32<FREQ>;
|
|
|
|
unsafe fn reset(&mut self) {
|
|
self.0.dier.modify(|_, w| w.cc1ie().set_bit());
|
|
}
|
|
|
|
#[inline(always)]
|
|
fn now(&mut self) -> Self::Instant {
|
|
Self::Instant::from_ticks(self.0.cnt.read().cnt().bits().into())
|
|
}
|
|
|
|
fn set_compare(&mut self, instant: Self::Instant) {
|
|
self.0
|
|
.ccr1()
|
|
.write(|w| w.ccr().bits(instant.duration_since_epoch().ticks()));
|
|
}
|
|
|
|
fn clear_compare_flag(&mut self) {
|
|
self.0.sr.modify(|_, w| w.cc1if().clear_bit());
|
|
}
|
|
|
|
#[inline(always)]
|
|
fn zero() -> Self::Instant {
|
|
Self::Instant::from_ticks(0)
|
|
}
|
|
}
|
|
|