Provides a means of obtaining the current WDT config
Obtaining the current WDT config is important so that we do not have to duplication configuration around the place. A constructor method has been introduced that returns WDT config in accordance with how the register is presently configured. The bootloader example has also been updated to show the watchdog can be obtained and used.
This commit is contained in:
parent
6e6c3cbebc
commit
8497f98de2
@ -23,6 +23,30 @@ pub struct Config {
|
|||||||
pub run_during_debug_halt: bool,
|
pub run_during_debug_halt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
/// Create a config structure from the current configuration of the WDT
|
||||||
|
/// peripheral.
|
||||||
|
pub fn try_new(_wdt: &peripherals::WDT) -> Option<Self> {
|
||||||
|
let r = unsafe { &*WDT::ptr() };
|
||||||
|
|
||||||
|
#[cfg(not(feature = "_nrf9160"))]
|
||||||
|
let runstatus = r.runstatus.read().runstatus().bit();
|
||||||
|
#[cfg(feature = "_nrf9160")]
|
||||||
|
let runstatus = r.runstatus.read().runstatuswdt().bit();
|
||||||
|
|
||||||
|
if runstatus {
|
||||||
|
let config = r.config.read();
|
||||||
|
Some(Self {
|
||||||
|
timeout_ticks: r.crv.read().bits(),
|
||||||
|
run_during_sleep: config.sleep().bit(),
|
||||||
|
run_during_debug_halt: config.halt().bit(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -8,6 +8,7 @@ use embassy_embedded_hal::adapter::BlockingAsync;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
|
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
|
||||||
use embassy_nrf::nvmc::Nvmc;
|
use embassy_nrf::nvmc::Nvmc;
|
||||||
|
use embassy_nrf::wdt::{self, Watchdog};
|
||||||
use panic_reset as _;
|
use panic_reset as _;
|
||||||
|
|
||||||
static APP_B: &[u8] = include_bytes!("../../b.bin");
|
static APP_B: &[u8] = include_bytes!("../../b.bin");
|
||||||
@ -20,6 +21,23 @@ async fn main(_spawner: Spawner) {
|
|||||||
//let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard);
|
//let mut led = Output::new(p.P1_10, Level::Low, OutputDrive::Standard);
|
||||||
//let mut button = Input::new(p.P1_02, Pull::Up);
|
//let mut button = Input::new(p.P1_02, Pull::Up);
|
||||||
|
|
||||||
|
// The following code block illustrates how to obtain a watchdog that is configured
|
||||||
|
// as per the existing watchdog. Ordinarily, we'd use the handle returned to "pet" the
|
||||||
|
// watchdog periodically. If we don't, and we're not going to for this example, then
|
||||||
|
// the watchdog will cause the device to reset as per its configured timeout in the bootloader.
|
||||||
|
// This helps is avoid a situation where new firmware might be bad and block our executor.
|
||||||
|
// If firmware is bad in this way then the bootloader will revert to any previous version.
|
||||||
|
let wdt_config = wdt::Config::try_new(&p.WDT).unwrap();
|
||||||
|
let (_wdt, [_wdt_handle]) = match Watchdog::try_new(p.WDT, wdt_config) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(_) => {
|
||||||
|
// Watchdog already active with the wrong number of handles, waiting for it to timeout...
|
||||||
|
loop {
|
||||||
|
cortex_m::asm::wfe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let nvmc = Nvmc::new(p.NVMC);
|
let nvmc = Nvmc::new(p.NVMC);
|
||||||
let mut nvmc = BlockingAsync::new(nvmc);
|
let mut nvmc = BlockingAsync::new(nvmc);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user