Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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;
    }
}