use crate::pac::WATCHDOG;
use embedded_hal::watchdog;
use fugit::MicrosDurationU32;
pub struct Watchdog {
watchdog: WATCHDOG,
load_value: u32, }
impl Watchdog {
pub fn new(watchdog: WATCHDOG) -> Self {
Self {
watchdog,
load_value: 0,
}
}
pub fn enable_tick_generation(&mut self, cycles: u8) {
const WATCHDOG_TICK_ENABLE_BITS: u32 = 0x200;
self.watchdog
.tick
.write(|w| unsafe { w.bits(WATCHDOG_TICK_ENABLE_BITS | cycles as u32) })
}
pub fn pause_on_debug(&mut self, pause: bool) {
self.watchdog.ctrl.write(|w| {
w.pause_dbg0()
.bit(pause)
.pause_dbg1()
.bit(pause)
.pause_jtag()
.bit(pause)
})
}
fn load_counter(&self, counter: u32) {
self.watchdog.load.write(|w| unsafe { w.bits(counter) });
}
fn enable(&self, bit: bool) {
self.watchdog.ctrl.write(|w| w.enable().bit(bit))
}
unsafe fn configure_wdog_reset_triggers(&self) {
let psm = &*pac::PSM::ptr();
psm.wdsel.write_with_zero(|w| {
w.bits(0x0001ffff);
w.xosc().clear_bit();
w.rosc().clear_bit();
w
});
}
}
impl watchdog::Watchdog for Watchdog {
fn feed(&mut self) {
self.load_counter(self.load_value)
}
}
impl watchdog::WatchdogEnable for Watchdog {
type Time = MicrosDurationU32;
fn start<T: Into<Self::Time>>(&mut self, period: T) {
const MAX_PERIOD: u32 = 0xFFFFFF;
let delay_us = period.into().to_micros();
if delay_us > MAX_PERIOD / 2 {
panic!(
"Period cannot exceed maximum load value of {} ({} microseconds))",
MAX_PERIOD,
MAX_PERIOD / 2
);
}
self.load_value = delay_us * 2;
self.enable(false);
unsafe {
self.configure_wdog_reset_triggers();
}
self.load_counter(self.load_value);
self.enable(true);
}
}
impl watchdog::WatchdogDisable for Watchdog {
fn disable(&mut self) {
self.enable(false)
}
}