use stm32h7xx_hal::{
self as hal,
rcc::{rec, CoreClocks, ResetEnable},
};
#[allow(dead_code)]
pub enum Channel {
One,
Two,
}
pub struct HighResTimerE {
master: hal::stm32::HRTIM_MASTER,
timer: hal::stm32::HRTIM_TIME,
common: hal::stm32::HRTIM_COMMON,
clocks: CoreClocks,
}
impl HighResTimerE {
pub fn new(
timer_regs: hal::stm32::HRTIM_TIME,
master_regs: hal::stm32::HRTIM_MASTER,
common_regs: hal::stm32::HRTIM_COMMON,
clocks: CoreClocks,
prec: rec::Hrtim,
) -> Self {
prec.reset().enable();
Self {
master: master_regs,
timer: timer_regs,
common: common_regs,
clocks,
}
}
pub fn configure_single_shot(
&mut self,
channel: Channel,
delay: f32,
duration: f32,
) {
self.master.mcr.modify(|_, w| w.tecen().clear_bit());
let clk = self.clocks.timy_ker_ck().to_Hz() as f32;
let end = ((delay + duration) * clk) as u32 + 1;
let div: u8 = if end < 0xFFDF {
1
} else if (end / 2) < 0xFFDF {
2
} else if (end / 4) < 0xFFDF {
3
} else {
panic!("Unattainable timing parameters!");
};
let period = (end / (1 << (div - 1)) as u32) as u16;
assert!(period > 2);
self.timer
.timecr
.modify(|_, w| unsafe { w.ck_pscx().bits(div + 4) });
self.timer.perer.write(|w| unsafe { w.perx().bits(period) });
let delay = (delay * clk) as u16;
assert!(delay >= 3);
self.timer
.cmp1er
.write(|w| unsafe { w.cmp1x().bits(delay) });
match channel {
Channel::One => {
self.timer.sete1r.write(|w| w.cmp1().set_bit());
self.timer.rste1r.write(|w| w.per().set_bit());
self.common.oenr.write(|w| w.te1oen().set_bit());
}
Channel::Two => {
self.timer.sete2r.write(|w| w.cmp1().set_bit());
self.timer.rste2r.write(|w| w.per().set_bit());
self.common.oenr.write(|w| w.te2oen().set_bit());
}
}
self.master.mcr.modify(|_, w| w.tecen().set_bit());
}
pub fn trigger(&mut self) {
self.common.cr2.write(|w| w.terst().set_bit());
}
}