mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-12-29 21:00:46 +00:00
[MCXA] reset_reason: process multiple bits
After testing with the pending watchdog driver, I noticed that more than one bit got set (Warm and Wdog0), changing my original assumption of this register being one-hot. Update the `reset_reason()` function and example according to James Munns' MCXA DMA Error implementation.
This commit is contained in:
parent
c3b5b1243f
commit
6c9345a022
@ -6,45 +6,158 @@
|
||||
|
||||
/// Reads the most recent reset reason from the Core Mode Controller
|
||||
/// (CMC).
|
||||
pub fn reset_reason() -> ResetReason {
|
||||
pub fn reset_reason() -> ResetReasonRaw {
|
||||
let regs = unsafe { &*crate::pac::Cmc::steal() };
|
||||
let srs = regs.srs().read().bits();
|
||||
ResetReasonRaw(srs)
|
||||
}
|
||||
|
||||
let srs = regs.srs().read();
|
||||
/// Raw reset reason bits. Can be queried or all reasons can be iterated over
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct ResetReasonRaw(u32);
|
||||
|
||||
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
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct ResetReasonRawIter(u32);
|
||||
|
||||
impl ResetReasonRaw {
|
||||
const MAP: &[(u32, ResetReason)] = &[
|
||||
(1 << 0, ResetReason::WakeUp),
|
||||
(1 << 1, ResetReason::Por),
|
||||
(1 << 2, ResetReason::VoltageDetect),
|
||||
(1 << 4, ResetReason::Warm),
|
||||
(1 << 5, ResetReason::Fatal),
|
||||
(1 << 8, ResetReason::Pin),
|
||||
(1 << 9, ResetReason::Dap),
|
||||
(1 << 10, ResetReason::ResetAckTimeout),
|
||||
(1 << 11, ResetReason::LowPowerAckTimeout),
|
||||
(1 << 12, ResetReason::SystemClockGeneration),
|
||||
(1 << 13, ResetReason::Wwdt0),
|
||||
(1 << 14, ResetReason::Software),
|
||||
(1 << 15, ResetReason::Lockup),
|
||||
(1 << 26, ResetReason::Cdog0),
|
||||
(1 << 27, ResetReason::Cdog1),
|
||||
(1 << 28, ResetReason::Jtag),
|
||||
];
|
||||
|
||||
/// Convert to an iterator of contained reset reasons
|
||||
pub fn into_iter(self) -> ResetReasonRawIter {
|
||||
ResetReasonRawIter(self.0)
|
||||
}
|
||||
|
||||
/// Wake up
|
||||
#[inline]
|
||||
pub fn is_wakeup(&self) -> bool {
|
||||
(self.0 & (1 << 0)) != 0
|
||||
}
|
||||
|
||||
/// Power-on Reset
|
||||
#[inline]
|
||||
pub fn is_por(&self) -> bool {
|
||||
(self.0 & (1 << 1)) != 0
|
||||
}
|
||||
|
||||
/// Voltage detect
|
||||
#[inline]
|
||||
pub fn is_voltage_detect(&self) -> bool {
|
||||
(self.0 & (1 << 2)) != 0
|
||||
}
|
||||
|
||||
/// Warm
|
||||
#[inline]
|
||||
pub fn is_warm(&self) -> bool {
|
||||
(self.0 & (1 << 4)) != 0
|
||||
}
|
||||
|
||||
/// Fatal
|
||||
#[inline]
|
||||
pub fn is_fatal(&self) -> bool {
|
||||
(self.0 & (1 << 5)) != 0
|
||||
}
|
||||
|
||||
/// Pin
|
||||
#[inline]
|
||||
pub fn is_pin(&self) -> bool {
|
||||
(self.0 & (1 << 8)) != 0
|
||||
}
|
||||
|
||||
/// DAP
|
||||
#[inline]
|
||||
pub fn is_dap(&self) -> bool {
|
||||
(self.0 & (1 << 9)) != 0
|
||||
}
|
||||
|
||||
/// Reset ack timeout
|
||||
#[inline]
|
||||
pub fn is_reset_ack_timeout(&self) -> bool {
|
||||
(self.0 & (1 << 10)) != 0
|
||||
}
|
||||
|
||||
/// Low power ack timeout
|
||||
#[inline]
|
||||
pub fn is_low_power_ack_timeout(&self) -> bool {
|
||||
(self.0 & (1 << 11)) != 0
|
||||
}
|
||||
|
||||
/// System clock generation
|
||||
#[inline]
|
||||
pub fn is_system_clock_generation(&self) -> bool {
|
||||
(self.0 & (1 << 12)) != 0
|
||||
}
|
||||
|
||||
/// Watchdog 0
|
||||
#[inline]
|
||||
pub fn is_watchdog0(&self) -> bool {
|
||||
(self.0 & (1 << 13)) != 0
|
||||
}
|
||||
|
||||
/// Software
|
||||
pub fn is_software(&self) -> bool {
|
||||
(self.0 & (1 << 14)) != 0
|
||||
}
|
||||
|
||||
/// Lockup
|
||||
pub fn is_lockup(&self) -> bool {
|
||||
(self.0 & (1 << 15)) != 0
|
||||
}
|
||||
|
||||
/// Code watchdog 0
|
||||
pub fn is_code_watchdog0(&self) -> bool {
|
||||
(self.0 & (1 << 26)) != 0
|
||||
}
|
||||
|
||||
/// Code watchdog 1
|
||||
pub fn is_code_watchdog1(&self) -> bool {
|
||||
(self.0 & (1 << 27)) != 0
|
||||
}
|
||||
|
||||
/// JTAG
|
||||
pub fn is_jtag(&self) -> bool {
|
||||
(self.0 & (1 << 28)) != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ResetReasonRawIter {
|
||||
type Item = ResetReason;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.0 == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
for (mask, var) in ResetReasonRaw::MAP {
|
||||
// If the bit is set...
|
||||
if self.0 & mask != 0 {
|
||||
// clear the bit
|
||||
self.0 &= !mask;
|
||||
// and return the answer
|
||||
return Some(*var);
|
||||
}
|
||||
}
|
||||
|
||||
// Shouldn't happen, but oh well.
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,5 +11,7 @@ async fn main(_spawner: Spawner) {
|
||||
let config = Config::default();
|
||||
let _p = hal::init(config);
|
||||
|
||||
defmt::info!("Reset Reason: '{}'", reset_reason());
|
||||
for reason in reset_reason().into_iter() {
|
||||
defmt::info!("Reset Reason: '{}'", reason);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user