use embedded_hal_02::watchdog;
use crate::pac::IWDG;
use crate::rcc::Rcc;
use crate::time::Hertz;
pub struct Watchdog {
iwdg: IWDG,
}
impl watchdog::Watchdog for Watchdog {
fn feed(&mut self) {
self.iwdg.kr.write(|w| w.key().reset());
}
}
#[derive(PartialEq, PartialOrd, Clone, Copy)]
pub struct IwdgTimeout {
psc: u8,
reload: u16,
}
impl From<Hertz> for IwdgTimeout {
fn from(hz: Hertz) -> Self {
let mut time = 32_768 / 4 / hz.raw();
let mut psc = 0;
let mut reload = 0;
while psc < 7 {
reload = time;
if reload < 0x1000 {
break;
}
psc += 1;
time /= 2;
}
let reload = reload as u16;
IwdgTimeout { psc, reload }
}
}
impl Watchdog {
pub fn new(rcc: &mut Rcc, iwdg: IWDG) -> Self {
rcc.regs.csr.modify(|_, w| w.lsion().on());
while rcc.regs.csr.read().lsirdy().is_not_ready() {}
Self { iwdg }
}
}
impl watchdog::WatchdogEnable for Watchdog {
type Time = IwdgTimeout;
fn start<T>(&mut self, period: T)
where
T: Into<IwdgTimeout>,
{
let time: IwdgTimeout = period.into();
self.iwdg.kr.write(|w| w.key().reset());
self.iwdg.kr.write(|w| w.key().start());
self.iwdg.kr.write(|w| w.key().enable());
while self.iwdg.sr.read().pvu().bit() {}
self.iwdg.pr.write(|w| w.pr().bits(time.psc));
while self.iwdg.sr.read().rvu().bit() {}
self.iwdg.rlr.write(|w| w.rl().bits(time.reload));
while self.iwdg.sr.read().bits() != 0 {}
self.iwdg.kr.write(|w| w.key().reset());
}
}