diff --git a/embassy-mspm0/CHANGELOG.md b/embassy-mspm0/CHANGELOG.md index d9910a7ab5..f0b5868f48 100644 --- a/embassy-mspm0/CHANGELOG.md +++ b/embassy-mspm0/CHANGELOG.md @@ -18,3 +18,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - feat: add MSPM0H3216 support - feat: Add i2c target implementation (#4605) - fix: group irq handlers must check for NO_INTR (#4785) +- feat: Add read_reset_cause function diff --git a/embassy-mspm0/Cargo.toml b/embassy-mspm0/Cargo.toml index df6176ff6c..b76bc7e418 100644 --- a/embassy-mspm0/Cargo.toml +++ b/embassy-mspm0/Cargo.toml @@ -72,7 +72,7 @@ cortex-m = "0.7.6" critical-section = "1.2.0" # mspm0-metapac = { version = "" } -mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-e7de4103a0713772695ffcad52c3c2f07414dc29" } +mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-8542f260cc89645a983b7f1a874c87b21822279e" } [build-dependencies] proc-macro2 = "1.0.94" @@ -80,7 +80,7 @@ quote = "1.0.40" cfg_aliases = "0.2.1" # mspm0-metapac = { version = "", default-features = false, features = ["metadata"] } -mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-e7de4103a0713772695ffcad52c3c2f07414dc29", default-features = false, features = ["metadata"] } +mspm0-metapac = { git = "https://github.com/mspm0-rs/mspm0-data-generated/", tag = "mspm0-data-8542f260cc89645a983b7f1a874c87b21822279e", default-features = false, features = ["metadata"] } [features] default = ["rt"] diff --git a/embassy-mspm0/src/lib.rs b/embassy-mspm0/src/lib.rs index 7135dd9f04..9f3e4d5e83 100644 --- a/embassy-mspm0/src/lib.rs +++ b/embassy-mspm0/src/lib.rs @@ -234,3 +234,114 @@ impl Iterator for BitIter { } } } + +/// Reset cause values from SYSCTL.RSTCAUSE register. +/// Based on MSPM0 L-series Technical Reference Manual Table 2-9 and +/// MSPM0 G-series Technical Reference Manual Table 2-12. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum ResetCause { + /// No reset since last read + NoReset, + /// VDD < POR- violation, PMU trim parity fault, or SHUTDNSTOREx parity fault + PorHwFailure, + /// NRST pin reset (>1s) + PorExternalNrst, + /// Software-triggered POR + PorSwTriggered, + /// VDD < BOR- violation + BorSupplyFailure, + /// Wake from SHUTDOWN + BorWakeFromShutdown, + /// Non-PMU trim parity fault + #[cfg(not(any( + mspm0c110x, + mspm0c1105_c1106, + mspm0g110x, + mspm0g150x, + mspm0g151x, + mspm0g310x, + mspm0g350x, + mspm0g351x + )))] + BootrstNonPmuParityFault, + /// Fatal clock fault + BootrstClockFault, + /// Software-triggered BOOTRST + BootrstSwTriggered, + /// NRST pin reset (<1s) + BootrstExternalNrst, + /// WWDT0 violation + BootrstWwdt0Violation, + /// WWDT1 violation (G-series only) + #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x))] + SysrstWwdt1Violation, + /// BSL exit (if present) + SysrstBslExit, + /// BSL entry (if present) + SysrstBslEntry, + /// Uncorrectable flash ECC error (if present) + #[cfg(not(any(mspm0c110x, mspm0c1105_c1106, mspm0g351x, mspm0g151x)))] + SysrstFlashEccError, + /// CPU lockup violation + SysrstCpuLockupViolation, + /// Debug-triggered SYSRST + SysrstDebugTriggered, + /// Software-triggered SYSRST + SysrstSwTriggered, + /// Debug-triggered CPURST + CpurstDebugTriggered, + /// Software-triggered CPURST + CpurstSwTriggered, +} + +/// Read the reset cause from the SYSCTL.RSTCAUSE register. +/// +/// This function reads the reset cause register which indicates why the last +/// system reset occurred. The register is automatically cleared after being read, +/// so this should be called only once per application startup. +/// +/// If the reset cause is not recognized, an `Err` containing the raw value is returned. +#[must_use = "Reading reset cause will clear it"] +pub fn read_reset_cause() -> Result { + let cause_raw = pac::SYSCTL.rstcause().read().id(); + + use ResetCause::*; + use pac::sysctl::vals::Id; + + match cause_raw { + Id::NORST => Ok(NoReset), + Id::PORHWFAIL => Ok(PorHwFailure), + Id::POREXNRST => Ok(PorExternalNrst), + Id::PORSW => Ok(PorSwTriggered), + Id::BORSUPPLY => Ok(BorSupplyFailure), + Id::BORWAKESHUTDN => Ok(BorWakeFromShutdown), + #[cfg(not(any( + mspm0c110x, + mspm0c1105_c1106, + mspm0g110x, + mspm0g150x, + mspm0g151x, + mspm0g310x, + mspm0g350x, + mspm0g351x + )))] + Id::BOOTNONPMUPARITY => Ok(BootrstNonPmuParityFault), + Id::BOOTCLKFAIL => Ok(BootrstClockFault), + Id::BOOTSW => Ok(BootrstSwTriggered), + Id::BOOTEXNRST => Ok(BootrstExternalNrst), + Id::BOOTWWDT0 => Ok(BootrstWwdt0Violation), + Id::SYSBSLEXIT => Ok(SysrstBslExit), + Id::SYSBSLENTRY => Ok(SysrstBslEntry), + #[cfg(any(mspm0g110x, mspm0g150x, mspm0g151x, mspm0g310x, mspm0g350x, mspm0g351x))] + Id::SYSWWDT1 => Ok(SysrstWwdt1Violation), + #[cfg(not(any(mspm0c110x, mspm0c1105_c1106, mspm0g351x, mspm0g151x)))] + Id::SYSFLASHECC => Ok(SysrstFlashEccError), + Id::SYSCPULOCK => Ok(SysrstCpuLockupViolation), + Id::SYSDBG => Ok(SysrstDebugTriggered), + Id::SYSSW => Ok(SysrstSwTriggered), + Id::CPUDBG => Ok(CpurstDebugTriggered), + Id::CPUSW => Ok(CpurstSwTriggered), + other => Err(other as u8), + } +}