From 0a798fc533962c7094883d4ddbbf92abe621c7f3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 10 Dec 2025 12:29:03 -0800 Subject: MCXA: Add a function to read Reset Reason --- embassy-mcxa/src/lib.rs | 1 + embassy-mcxa/src/reset_reason.rs | 108 ++++++++++++++++++++++++++++++++++ examples/mcxa/src/bin/reset-reason.rs | 15 +++++ 3 files changed, 124 insertions(+) create mode 100644 embassy-mcxa/src/reset_reason.rs create mode 100644 examples/mcxa/src/bin/reset-reason.rs diff --git a/embassy-mcxa/src/lib.rs b/embassy-mcxa/src/lib.rs index be279e509..7de5839be 100644 --- a/embassy-mcxa/src/lib.rs +++ b/embassy-mcxa/src/lib.rs @@ -17,6 +17,7 @@ pub mod i2c; pub mod interrupt; pub mod lpuart; pub mod ostimer; +pub mod reset_reason; pub mod rtc; pub use crate::pac::NVIC_PRIO_BITS; diff --git a/embassy-mcxa/src/reset_reason.rs b/embassy-mcxa/src/reset_reason.rs new file mode 100644 index 000000000..1f5a0ec1f --- /dev/null +++ b/embassy-mcxa/src/reset_reason.rs @@ -0,0 +1,108 @@ +//! Reset reason +//! +//! MCXA families keep the most recent reset reason in the SRS +//! register of the CMC block. This lets users understand why the MCU +//! has reset and take appropriate corrective actions if required. + +/// Reads the most recent reset reason from the Core Mode Controller +/// (CMC). +pub fn reset_reason() -> ResetReason { + critical_section::with(|_| { + let regs = unsafe { &*crate::pac::Cmc::steal() }; + + let srs = regs.srs().read(); + + if srs.wakeup().is_enabled() { + ResetReason::WakeUp + } else if srs.por().bit_is_set() { + ResetReason::Por + } else if srs.vd().bit_is_set() { + ResetReason::VoltageDetect + } else if srs.warm().bit_is_set() { + ResetReason::Warm + } else if srs.fatal().bit_is_set() { + ResetReason::Fatal + } else if srs.pin().bit_is_set() { + ResetReason::Pin + } else if srs.dap().bit_is_set() { + ResetReason::Dap + } else if srs.rstack().bit_is_set() { + ResetReason::ResetAckTimeout + } else if srs.lpack().bit_is_set() { + ResetReason::LowPowerAckTimeout + } else if srs.scg().bit_is_set() { + ResetReason::SystemClockGeneration + } else if srs.wwdt0().bit_is_set() { + ResetReason::Wwdt0 + } else if srs.sw().bit_is_set() { + ResetReason::Software + } else if srs.lockup().bit_is_set() { + ResetReason::Lockup + } else if srs.cdog0().bit_is_set() { + ResetReason::Cdog0 + } else if srs.cdog1().bit_is_set() { + ResetReason::Cdog1 + } else if srs.jtag().bit_is_set() { + ResetReason::Jtag + } else { + ResetReason::Tamper + } + }) +} + +/// Indicates the type and source of the most recent reset. +#[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[non_exhaustive] +pub enum ResetReason { + /// Tamper reset. + Tamper, + + /// JTAG System Reset request. + Jtag, + + /// Code Watchdog 0 reset. + Cdog0, + + /// Code Watchdog 1 reset. + Cdog1, + + /// Lockup reset. + Lockup, + + /// Software reset. + Software, + + /// Windowed Watchdog 0 reset. + Wwdt0, + + /// System clock generation reset. + SystemClockGeneration, + + /// Low Power Acknowledge Timeout reset. + LowPowerAckTimeout, + + /// Reset Timeout. + ResetAckTimeout, + + /// Debug Access Port reset. + Dap, + + /// External assertion of RESET_b pin. + Pin, + + /// Fatal reset. + Fatal, + + /// Warm reset. + Warm, + + /// Voltage detect reset. + VoltageDetect, + + /// Power-on reset. + Por, + + /// Wake-up reset. + WakeUp, +} diff --git a/examples/mcxa/src/bin/reset-reason.rs b/examples/mcxa/src/bin/reset-reason.rs new file mode 100644 index 000000000..c244fbe04 --- /dev/null +++ b/examples/mcxa/src/bin/reset-reason.rs @@ -0,0 +1,15 @@ +#![no_std] +#![no_main] + +use embassy_executor::Spawner; +use hal::config::Config; +use hal::reset_reason::reset_reason; +use {defmt_rtt as _, embassy_mcxa as hal, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let config = Config::default(); + let _p = hal::init(config); + + defmt::info!("Reset Reason: '{}'", reset_reason()); +} -- cgit From 0ab1e8f9faa149e14e3348f9a88fb4efea26962a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Dec 2025 08:15:07 -0800 Subject: Remove critical section --- embassy-mcxa/src/reset_reason.rs | 80 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/embassy-mcxa/src/reset_reason.rs b/embassy-mcxa/src/reset_reason.rs index 1f5a0ec1f..f9a9ce096 100644 --- a/embassy-mcxa/src/reset_reason.rs +++ b/embassy-mcxa/src/reset_reason.rs @@ -7,47 +7,45 @@ /// Reads the most recent reset reason from the Core Mode Controller /// (CMC). pub fn reset_reason() -> ResetReason { - critical_section::with(|_| { - let regs = unsafe { &*crate::pac::Cmc::steal() }; - - let srs = regs.srs().read(); - - if srs.wakeup().is_enabled() { - ResetReason::WakeUp - } else if srs.por().bit_is_set() { - ResetReason::Por - } else if srs.vd().bit_is_set() { - ResetReason::VoltageDetect - } else if srs.warm().bit_is_set() { - ResetReason::Warm - } else if srs.fatal().bit_is_set() { - ResetReason::Fatal - } else if srs.pin().bit_is_set() { - ResetReason::Pin - } else if srs.dap().bit_is_set() { - ResetReason::Dap - } else if srs.rstack().bit_is_set() { - ResetReason::ResetAckTimeout - } else if srs.lpack().bit_is_set() { - ResetReason::LowPowerAckTimeout - } else if srs.scg().bit_is_set() { - ResetReason::SystemClockGeneration - } else if srs.wwdt0().bit_is_set() { - ResetReason::Wwdt0 - } else if srs.sw().bit_is_set() { - ResetReason::Software - } else if srs.lockup().bit_is_set() { - ResetReason::Lockup - } else if srs.cdog0().bit_is_set() { - ResetReason::Cdog0 - } else if srs.cdog1().bit_is_set() { - ResetReason::Cdog1 - } else if srs.jtag().bit_is_set() { - ResetReason::Jtag - } else { - ResetReason::Tamper - } - }) + let regs = unsafe { &*crate::pac::Cmc::steal() }; + + let srs = regs.srs().read(); + + if srs.wakeup().is_enabled() { + ResetReason::WakeUp + } else if srs.por().bit_is_set() { + ResetReason::Por + } else if srs.vd().bit_is_set() { + ResetReason::VoltageDetect + } else if srs.warm().bit_is_set() { + ResetReason::Warm + } else if srs.fatal().bit_is_set() { + ResetReason::Fatal + } else if srs.pin().bit_is_set() { + ResetReason::Pin + } else if srs.dap().bit_is_set() { + ResetReason::Dap + } else if srs.rstack().bit_is_set() { + ResetReason::ResetAckTimeout + } else if srs.lpack().bit_is_set() { + ResetReason::LowPowerAckTimeout + } else if srs.scg().bit_is_set() { + ResetReason::SystemClockGeneration + } else if srs.wwdt0().bit_is_set() { + ResetReason::Wwdt0 + } else if srs.sw().bit_is_set() { + ResetReason::Software + } else if srs.lockup().bit_is_set() { + ResetReason::Lockup + } else if srs.cdog0().bit_is_set() { + ResetReason::Cdog0 + } else if srs.cdog1().bit_is_set() { + ResetReason::Cdog1 + } else if srs.jtag().bit_is_set() { + ResetReason::Jtag + } else { + ResetReason::Tamper + } } /// Indicates the type and source of the most recent reset. -- cgit