diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 717ebb95e..7be0c77ea 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs @@ -55,6 +55,9 @@ pub mod usb; #[cfg(any(otgfs, otghs))] pub mod usb_otg; +#[cfg(iwdg)] +pub mod wdg; + #[cfg(feature = "subghz")] pub mod subghz; diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs new file mode 100644 index 000000000..da25692ab --- /dev/null +++ b/embassy-stm32/src/wdg/mod.rs @@ -0,0 +1,53 @@ +use core::marker::PhantomData; + +use embassy_hal_common::{unborrow, Unborrow}; +use stm32_metapac::iwdg::vals::Key; +pub use stm32_metapac::iwdg::vals::Pr as Prescaler; + +pub struct IndependentWatchdog<'d, T: Instance> { + wdg: PhantomData<&'d mut T>, +} + +impl<'d, T: Instance> IndependentWatchdog<'d, T> { + pub fn new(_instance: impl Unborrow + 'd, presc: Prescaler) -> Self { + unborrow!(_instance); + + let wdg = T::regs(); + unsafe { + wdg.kr().write(|w| w.set_key(Key::ENABLE)); + wdg.pr().write(|w| w.set_pr(presc)); + } + + IndependentWatchdog { + wdg: PhantomData::default(), + } + } + + pub unsafe fn unleash(&mut self) { + T::regs().kr().write(|w| w.set_key(Key::START)); + } + + pub unsafe fn pet(&mut self) { + T::regs().kr().write(|w| w.set_key(Key::RESET)); + } +} + +mod sealed { + pub trait Instance { + fn regs() -> crate::pac::iwdg::Iwdg; + } +} + +pub trait Instance: sealed::Instance {} + +foreach_peripheral!( + (iwdg, $inst:ident) => { + impl sealed::Instance for crate::peripherals::$inst { + fn regs() -> crate::pac::iwdg::Iwdg { + crate::pac::$inst + } + } + + impl Instance for crate::peripherals::$inst {} + }; +);