Watchdog timer
Now let’s see an example of using the Pico watchdog timer:
#![no_std]
#![no_main]
use aux::blink_led;
pub use cortex_m_rt::entry;
use defmt::info;
use crate::aux::{setup, sleep};
mod aux;
#[entry]
fn main() -> ! {
unsafe {
setup();
// put GPIO Pin 16 in output low mode
// then disables output mode
// this allows you to briefly blink a LED
// at the beginning to help us see that the pico
// is being reset
blink_led();
// These two tell which components the watchdog will reset
// (without these, the watchdog event wouldn't cause anything
// to reset)
{
// PSM: WDSEL Register bit 24 to reset
core::ptr::write_volatile(0x40018008 as *mut u32, (1 << 25) - 1);
// POWMAN: WDSEL Register
// RESET_POWMAN_ASYNC + password
core::ptr::write_volatile(0x40100030 as *mut u32, 0x5AFE0001);
}
// WATCHDOG: CTRL Register Enable
core::ptr::write_volatile(0x400d8000 as *mut u32, 1 << 30);
// WATCHDOG: CTRL Register Trigger Reset
// This would trigger the watchdog reset immediatelly
// core::ptr::write_volatile(0x400d8000 as *mut u32, 1 << 31);
// TICKS: WATCHDOG_CTRL Register
// Without this the watchdog timer won't tick
// (i.e.: won't go down)
core::ptr::write_volatile(0x40108030 as *mut u32, 1);
// TICKS: WATCHDOG_CYCLES Register
// A divider that must result in a 1MHz clock.
// If using the XOSC of reference board which 12MHz
// this needs to be 12.
core::ptr::write_volatile(0x40108034 as *mut u32, 12);
};
let mut i = 16_000_000;
loop {
unsafe {
info!(
"{} WATCHDOG: CTRL Register TIME",
core::ptr::read_volatile(0x400d8000 as *const u32)
& ((1 << 24) - 1)
);
sleep(500_000);
info!(
"{} WATCHDOG: CTRL Register TIME",
core::ptr::read_volatile(0x400d8000 as *const u32)
& ((1 << 24) - 1)
);
// WATCHDOG: LOAD Register
// Set how long we have until the watchdog timer
// will trigger the reset event
core::ptr::write_volatile(0x400d8004 as *mut u32, i);
sleep(1_000_000);
}
i >>= 1;
}
}