va416xx_hal/
wdt.rs

1//! # API for the Watchdog peripheral
2//!
3//! ## Examples
4//!
5//! - [Watchdog simple example](https://egit.irs.uni-stuttgart.de/rust/va416xx-rs/src/branch/main/examples/simple/examples/wdt.rs)
6use vorago_shared_hal::{enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect};
7
8use crate::time::Hertz;
9use crate::{clock::Clocks, pac};
10use crate::{disable_nvic_interrupt, enable_nvic_interrupt};
11
12pub const WDT_UNLOCK_VALUE: u32 = 0x1ACC_E551;
13
14/// Watchdog peripheral driver.
15pub struct Wdt {
16    clock_freq: Hertz,
17    wdt: pac::WatchDog,
18}
19
20/// Type alias for backwards compatibility
21#[deprecated(since = "0.2.0", note = "Please use `Wdt` instead")]
22pub type WdtController = Wdt;
23
24/// Enable the watchdog interrupt
25///
26/// # Safety
27///
28/// This function is `unsafe` because it can break mask-based critical sections.
29#[inline]
30pub unsafe fn enable_wdt_interrupts() {
31    enable_nvic_interrupt(pac::Interrupt::WATCHDOG)
32}
33
34#[inline]
35pub fn disable_wdt_interrupts() {
36    disable_nvic_interrupt(pac::Interrupt::WATCHDOG)
37}
38
39impl Wdt {
40    pub fn new(wdt: pac::WatchDog, clocks: &Clocks, wdt_freq_ms: u32) -> Self {
41        Self::start(wdt, clocks, wdt_freq_ms)
42    }
43
44    pub fn start(wdt: pac::WatchDog, clocks: &Clocks, wdt_freq_ms: u32) -> Self {
45        enable_peripheral_clock(PeripheralSelect::Watchdog);
46        reset_peripheral_for_cycles(PeripheralSelect::Watchdog, 2);
47
48        let wdt_clock = clocks.apb2();
49        let mut wdt_ctrl = Self {
50            clock_freq: wdt_clock,
51            wdt,
52        };
53        wdt_ctrl.set_freq(wdt_freq_ms);
54        wdt_ctrl.wdt.wdogcontrol().write(|w| w.inten().set_bit());
55        wdt_ctrl.feed();
56        // Unmask the watchdog interrupt
57        unsafe {
58            enable_wdt_interrupts();
59        }
60        wdt_ctrl
61    }
62
63    #[inline]
64    pub fn set_freq(&mut self, freq_ms: u32) {
65        let counter = (self.clock_freq.raw() / 1000) * freq_ms;
66        self.wdt.wdogload().write(|w| unsafe { w.bits(counter) });
67    }
68
69    #[inline]
70    pub fn disable_reset(&mut self) {
71        self.wdt.wdogcontrol().modify(|_, w| w.resen().clear_bit());
72    }
73
74    #[inline]
75    pub fn enable_reset(&mut self) {
76        self.wdt.wdogcontrol().modify(|_, w| w.resen().set_bit());
77    }
78
79    #[inline]
80    pub fn counter(&self) -> u32 {
81        self.wdt.wdogvalue().read().bits()
82    }
83
84    #[inline]
85    pub fn feed(&self) {
86        self.wdt.wdogintclr().write(|w| unsafe { w.bits(1) });
87    }
88
89    #[inline]
90    pub fn lock(&self) {
91        self.wdt.wdoglock().write(|w| unsafe { w.bits(0) });
92    }
93
94    #[inline]
95    pub fn unlock(&self) {
96        self.wdt
97            .wdoglock()
98            .write(|w| unsafe { w.bits(WDT_UNLOCK_VALUE) });
99    }
100
101    #[inline]
102    pub fn is_locked(&self) -> bool {
103        self.wdt.wdogload().read().bits() == 1
104    }
105}