Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure the watchdog #575

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 71 additions & 1 deletion components/boards/src/nk3am.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ use nfc_device::traits::nfc::{Device as NfcDevice, Error as NfcError, State as N
use nrf52840_hal::{
gpio::{p0, p1, Level, Output, Pin, PushPull},
gpiote::Gpiote,
pac::power::RESETREAS,
pac::WDT,
prelude::OutputPin as _,
spim,
timer::Timer,
twim, Spim, Twim,
twim,
wdt::{self, count::One, handles::Hdl0, Watchdog, WatchdogHandle},
Spim, Twim,
};
use nrf52840_pac::{FICR, GPIOTE, P0, P1, POWER, PWM0, PWM1, PWM2, SPIM3, TIMER1, TWIM1};

Expand Down Expand Up @@ -259,3 +263,69 @@ pub fn power_handler(power: &mut POWER) {
trace!("usb-");
}
}

pub fn init_watchdog(wdt: WDT) -> Result<wdt::Parts<(WatchdogHandle<Hdl0>,)>, WDT> {
const WDT_FREQUENCY: u32 = 32_768;
// Watchdog triggers after 3 minutes
const DURATION_SECONS: u32 = 3 * 60;
const TICKS: u32 = DURATION_SECONS * WDT_FREQUENCY;

match Watchdog::try_new(wdt) {
Ok(mut watchdog) => {
watchdog.set_lfosc_ticks(TICKS);
watchdog.enable_interrupt();
let mut parts = watchdog.activate::<One>();
parts.handles.0.pet();
Ok(parts)
}
Err(wdt) => {
let mut parts = Watchdog::try_recover::<One>(wdt)?;
parts.handles.0.pet();
Ok(parts)
}
}
}

#[derive(Debug)]
pub struct ResetReason {
pub resetpin: bool,
/// Reset from watchdog
pub dog: bool,
/// Soft Reset
pub sreq: bool,
pub lockup: bool,
pub off: bool,
pub lpcomp: bool,
pub dif: bool,
pub nfc: bool,
pub vbus: bool,
}

pub fn reset_reason(reset_reason: &RESETREAS) -> ResetReason {
debug_now!("Reset Reason: {:b}", reset_reason.read().bits());
let read = reset_reason.read();
let res = ResetReason {
resetpin: read.resetpin().bits(),
dog: read.dog().bits(),
sreq: read.sreq().bits(),
lockup: read.lockup().bits(),
off: read.off().bits(),
lpcomp: read.lpcomp().bits(),
dif: read.dif().bits(),
nfc: read.nfc().bits(),
vbus: read.vbus().bits(),
};
reset_reason.write(|w| {
w.resetpin().bit(false);
w.dog().bit(false);
w.sreq().bit(false);
w.lockup().bit(false);
w.off().bit(false);
w.lpcomp().bit(false);
w.dif().bit(false);
w.nfc().bit(false);
w.vbus().bit(false);
w
});
res
}
3 changes: 0 additions & 3 deletions components/boards/src/soc/nrf52.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ pub fn init_bootup(
uuid[0..4].copy_from_slice(&deviceid0.to_be_bytes());
uuid[4..8].copy_from_slice(&deviceid1.to_be_bytes());

info!("RESET Reason: {:x}", power.resetreas.read().bits());
power.resetreas.write(|w| w);

info!("FICR DeviceID {}", delog::hex_str!(&uuid),);
info!(
"FICR IdtRoot {:08x} {:08x} {:08x} {:08x}",
Expand Down
44 changes: 40 additions & 4 deletions runners/embedded/src/bin/app-nrf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,21 @@ use cortex_m_rt::{exception, ExceptionFrame};
#[rtic::app(device = nrf52840_hal::pac, peripherals = true, dispatchers = [SWI3_EGU3, SWI4_EGU4, SWI5_EGU5])]
mod app {
use apdu_dispatch::{dispatch::ApduDispatch, interchanges::Channel as CcidChannel};
use apps::Reboot;
use boards::{
init::UsbClasses,
nk3am::{self, InternalFlashStorage, NK3AM},
runtime,
soc::nrf52::{self, rtic_monotonic::RtcDuration},
soc::nrf52::{self, rtic_monotonic::RtcDuration, Nrf52},
store, Apps, Trussed,
};
use ctaphid_dispatch::dispatch::Dispatch as CtaphidDispatch;
use interchange::Channel;
use nrf52840_hal::{gpiote::Gpiote, rng::Rng};
use nrf52840_hal::{
gpiote::Gpiote,
rng::Rng,
wdt::{self, handles::Hdl0, WatchdogHandle},
};

use embedded_runner_lib::{VERSION, VERSION_STRING};

Expand All @@ -38,6 +43,7 @@ mod app {
struct LocalResources {
gpiote: Gpiote,
power: nrf52840_pac::POWER,
watchdog_parts: Option<wdt::Parts<WatchdogHandle<Hdl0>>>,
}

#[monotonic(binds = RTC0, default = true)]
Expand All @@ -55,8 +61,21 @@ mod app {

boards::init::init_logger::<Board>(VERSION_STRING);

let reset_reason = nk3am::reset_reason(&ctx.device.POWER.resetreas);
debug_now!("Reset Reason: {reset_reason:?}");

// Go to bootloader after watchdog failure
// After a soft reset, go back to normal operation
// This is required because for some reason the `RESETREAS` register
// is not cleared until a full poweroff
if reset_reason.dog && !reset_reason.sreq {
Nrf52::reboot_to_firmware_update();
}

let soc = nrf52::init_bootup(&ctx.device.FICR, &ctx.device.UICR, &mut ctx.device.POWER);

let wdt_parts = nk3am::init_watchdog(ctx.device.WDT);

let mut board_gpio = nk3am::init_pins(ctx.device.GPIOTE, ctx.device.P0, ctx.device.P1);

let usb_bus = nrf52::setup_usb_bus(ctx.device.CLOCK, ctx.device.USBD);
Expand Down Expand Up @@ -127,12 +146,16 @@ mod app {
LocalResources {
gpiote: board_gpio.gpiote,
power: ctx.device.POWER,
watchdog_parts: wdt_parts.ok().map(|parts| wdt::Parts {
watchdog: parts.watchdog,
handles: parts.handles.0,
}),
},
init::Monotonics(rtc_mono),
)
}

#[idle(shared = [apps, apdu_dispatch, ctaphid_dispatch, usb_classes])]
#[idle(shared = [apps, apdu_dispatch, ctaphid_dispatch, usb_classes], local = [watchdog_parts])]
fn idle(ctx: idle::Context) -> ! {
let idle::SharedResources {
mut apps,
Expand All @@ -146,6 +169,11 @@ mod app {
// cortex_m::asm::wfi();

loop {
ctx.local
.watchdog_parts
.as_mut()
.map(|mut parts| parts.handles.pet());

#[cfg(not(feature = "no-delog"))]
boards::init::Delogger::flush();

Expand All @@ -170,7 +198,6 @@ mod app {
);
});
}
// loop {}
}

#[task(priority = 2, binds = SWI0_EGU0, shared = [trussed])]
Expand Down Expand Up @@ -237,6 +264,15 @@ mod app {
});
ui::spawn_after(RtcDuration::from_ms(125)).ok();
}

#[task(priority = 6, binds = WDT)]
fn wdt_handler(_ctx: wdt_handler::Context) {
#[no_mangle]
fn wdt_handler_inner() {
error_now!("Reached interrupt");
}
wdt_handler_inner();
}
}

#[inline(never)]
Expand Down