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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
use crate::hal::watchdog; use crate::pac::{IWDG, WWDG}; use crate::rcc::Rcc; use crate::time::Hertz; pub struct IndependedWatchdog { iwdg: IWDG, } impl IndependedWatchdog { pub fn set_config(&mut self, pre: u8, reload: u16) { self.iwdg.kr.write(|w| w.key().reset()); self.iwdg.kr.write(|w| w.key().enable()); while self.iwdg.sr.read().pvu().bit() {} self.iwdg.pr.write(|w| w.pr().bits(pre)); while self.iwdg.sr.read().rvu().bit() {} self.iwdg.rlr.write(|w| w.rl().bits(reload)); self.iwdg.kr.write(|w| w.key().start()); self.iwdg.kr.write(|w| w.key().reset()); } } impl watchdog::Watchdog for IndependedWatchdog { fn feed(&mut self) { self.iwdg.kr.write(|w| w.key().reset()); } } impl watchdog::WatchdogEnable for IndependedWatchdog { type Time = Hertz; fn start<T>(&mut self, period: T) where T: Into<Hertz>, { const LSI_CLOCK: u32 = 38_000_u32; let freq = period.into().0; let mut timeout = LSI_CLOCK / freq / 4; let mut pre = 0; let mut reload = 0; while pre < 7 { reload = timeout; if reload <= 0xFFF { break; } pre += 1; timeout /= 2; } self.set_config(pre, reload as u16); } } pub trait IndependedWatchdogExt { fn watchdog(self) -> IndependedWatchdog; } impl IndependedWatchdogExt for IWDG { fn watchdog(self) -> IndependedWatchdog { IndependedWatchdog { iwdg: self } } } pub struct WindowWatchdog { wwdg: WWDG, clk: u32, } impl watchdog::Watchdog for WindowWatchdog { fn feed(&mut self) { self.wwdg.cr.write(|w| w.t().bits(0xFF)); } } impl WindowWatchdog { pub fn set_window<T>(&mut self, window: T) where T: Into<Hertz>, { let freq = window.into().0; let mut ticks = self.clk / freq; let mut pre = 0; let mut threshold = 0; while pre < 3 { threshold = ticks; if threshold <= 0x7F { break; } pre += 1; ticks /= 2; } let window_bits = if threshold >= 0xFF { 0 } else { 0xFF - threshold as u8 }; self.wwdg .cfr .write(|w| w.wdgtb().bits(pre).w().bits(window_bits)); } pub fn listen(&mut self) { self.wwdg.cfr.write(|w| w.ewi().set_bit()); } } impl watchdog::WatchdogEnable for WindowWatchdog { type Time = Hertz; fn start<T>(&mut self, period: T) where T: Into<Hertz>, { self.set_window(period); self.wwdg.cr.write(|w| w.wdga().set_bit().t().bits(0xFF)); } } pub trait WindowWatchdogExt { fn watchdog(self, rcc: &mut Rcc) -> WindowWatchdog; } impl WindowWatchdogExt for WWDG { fn watchdog(self, rcc: &mut Rcc) -> WindowWatchdog { rcc.rb.apb1enr.modify(|_, w| w.wwdgen().set_bit()); WindowWatchdog { wwdg: self, clk: rcc.clocks.apb1_clk().0 / 4096, } } }