use crate::pac;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum ResetReason {
Brownout,
ResetPin,
SoftwareBor,
Lpm5WakeUp,
SecurityViolation,
SvsHigh,
SoftwarePor,
WatchdogTimeout,
WatchdogPassword,
FramPassword,
FramBitError,
PeripheralFetch,
PmmPassword,
MpuPassword,
CsPassword,
MpuSegIp,
MpuSegInfo,
MpuSeg1,
MpuSeg2,
MpuSeg3,
FramAccessTime,
Unknown(u16),
}
impl ResetReason {
pub fn from_iv(iv: u16) -> Option<ResetReason> {
Some(match iv {
0x00 => return None,
0x02 => ResetReason::Brownout,
0x04 => ResetReason::ResetPin,
0x06 => ResetReason::SoftwareBor,
0x08 => ResetReason::Lpm5WakeUp,
0x0A => ResetReason::SecurityViolation,
0x0E => ResetReason::SvsHigh,
0x14 => ResetReason::SoftwarePor,
0x16 => ResetReason::WatchdogTimeout,
0x18 => ResetReason::WatchdogPassword,
0x1A => ResetReason::FramPassword,
0x1C => ResetReason::FramBitError,
0x1E => ResetReason::PeripheralFetch,
0x20 => ResetReason::PmmPassword,
0x22 => ResetReason::MpuPassword,
0x24 => ResetReason::CsPassword,
0x26 => ResetReason::MpuSegIp,
0x28 => ResetReason::MpuSegInfo,
0x2A => ResetReason::MpuSeg1,
0x2C => ResetReason::MpuSeg2,
0x2E => ResetReason::MpuSeg3,
0x30 => ResetReason::FramAccessTime,
other => ResetReason::Unknown(other),
})
}
pub fn as_str(&self) -> &'static str {
match self {
ResetReason::Brownout => "brownout",
ResetReason::ResetPin => "reset pin",
ResetReason::SoftwareBor => "software BOR",
ResetReason::Lpm5WakeUp => "LPMx.5 wakeup",
ResetReason::SecurityViolation => "security violation",
ResetReason::SvsHigh => "SVSH event",
ResetReason::SoftwarePor => "software POR",
ResetReason::WatchdogTimeout => "WDT timeout",
ResetReason::WatchdogPassword => "WDT password",
ResetReason::FramPassword => "FRAM password",
ResetReason::FramBitError => "FRAM bit error",
ResetReason::PeripheralFetch => "peripheral fetch",
ResetReason::PmmPassword => "PMM password",
ResetReason::MpuPassword => "MPU password",
ResetReason::CsPassword => "CS password",
ResetReason::MpuSegIp => "MPU seg IP",
ResetReason::MpuSegInfo => "MPU seg info",
ResetReason::MpuSeg1 => "MPU seg 1",
ResetReason::MpuSeg2 => "MPU seg 2",
ResetReason::MpuSeg3 => "MPU seg 3",
ResetReason::FramAccessTime => "FRAM access time",
ResetReason::Unknown(_) => "unknown",
}
}
}
const CAPACITY: usize = 8;
#[derive(Clone, Copy, Debug)]
pub struct ResetReasons {
raw: [u16; CAPACITY],
len: u8,
}
impl ResetReasons {
pub fn drain(sys: &pac::Sys) -> ResetReasons {
let mut reasons = ResetReasons {
raw: [0; CAPACITY],
len: 0,
};
for _ in 0..32 {
let iv = sys.sysrstiv().read().bits();
if iv == 0 {
break;
}
if (reasons.len as usize) < CAPACITY {
reasons.raw[reasons.len as usize] = iv;
reasons.len += 1;
}
}
reasons
}
pub fn primary(&self) -> Option<ResetReason> {
self.iter().next()
}
pub fn iter(&self) -> impl Iterator<Item = ResetReason> + '_ {
self.raw[..self.len as usize]
.iter()
.map(|&iv| ResetReason::from_iv(iv).unwrap_or(ResetReason::Unknown(iv)))
}
pub fn contains(&self, reason: ResetReason) -> bool {
self.iter().any(|r| r == reason)
}
pub fn len(&self) -> usize {
self.len as usize
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn raw(&self) -> &[u16] {
&self.raw[..self.len as usize]
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum NmiSource {
FramUncorrectableBit,
MpuSegIp,
MpuSegInfo,
MpuSeg1,
MpuSeg2,
MpuSeg3,
VacantMemory,
JtagMailboxIn,
JtagMailboxOut,
FramCorrectableBit,
Unknown(u16),
}
impl NmiSource {
pub fn from_iv(iv: u16) -> Option<NmiSource> {
Some(match iv {
0x00 => return None,
0x04 => NmiSource::FramUncorrectableBit,
0x08 => NmiSource::MpuSegIp,
0x0A => NmiSource::MpuSegInfo,
0x0C => NmiSource::MpuSeg1,
0x0E => NmiSource::MpuSeg2,
0x10 => NmiSource::MpuSeg3,
0x12 => NmiSource::VacantMemory,
0x14 => NmiSource::JtagMailboxIn,
0x16 => NmiSource::JtagMailboxOut,
0x18 => NmiSource::FramCorrectableBit,
other => NmiSource::Unknown(other),
})
}
pub fn as_str(&self) -> &'static str {
match self {
NmiSource::FramUncorrectableBit => "FRAM uncorrectable bit",
NmiSource::MpuSegIp => "MPU seg IP",
NmiSource::MpuSegInfo => "MPU seg info",
NmiSource::MpuSeg1 => "MPU seg 1",
NmiSource::MpuSeg2 => "MPU seg 2",
NmiSource::MpuSeg3 => "MPU seg 3",
NmiSource::VacantMemory => "vacant memory",
NmiSource::JtagMailboxIn => "JTAG mailbox in",
NmiSource::JtagMailboxOut => "JTAG mailbox out",
NmiSource::FramCorrectableBit => "FRAM correctable bit",
NmiSource::Unknown(_) => "unknown",
}
}
}
pub fn read_nmi_iv() -> Option<NmiSource> {
let sys = unsafe { pac::Sys::steal() };
NmiSource::from_iv(sys.syssniv().read().bits())
}