aboutsummaryrefslogtreecommitdiff
path: root/embassy-mcxa/src
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2025-12-18 18:31:04 +0000
committerGitHub <[email protected]>2025-12-18 18:31:04 +0000
commit65a6ce4c8bd1993e8cd05ce1d6fb3b378e35407a (patch)
treea0d14c035581b62f4cc1656f2c39cb4f487d1149 /embassy-mcxa/src
parent660abf8a659efa14ddc7ef5e5e11d83f84b61eaf (diff)
parent6c9345a022dfd4a4dac5005166789792dffbbbe7 (diff)
Merge pull request #5105 from felipebalbi/mcxa/reset-reason
[MCXA] reset_reason: process multiple bits
Diffstat (limited to 'embassy-mcxa/src')
-rw-r--r--embassy-mcxa/src/reset_reason.rs187
1 files changed, 150 insertions, 37 deletions
diff --git a/embassy-mcxa/src/reset_reason.rs b/embassy-mcxa/src/reset_reason.rs
index f9a9ce096..1787690a7 100644
--- a/embassy-mcxa/src/reset_reason.rs
+++ b/embassy-mcxa/src/reset_reason.rs
@@ -6,45 +6,158 @@
6 6
7/// Reads the most recent reset reason from the Core Mode Controller 7/// Reads the most recent reset reason from the Core Mode Controller
8/// (CMC). 8/// (CMC).
9pub fn reset_reason() -> ResetReason { 9pub fn reset_reason() -> ResetReasonRaw {
10 let regs = unsafe { &*crate::pac::Cmc::steal() }; 10 let regs = unsafe { &*crate::pac::Cmc::steal() };
11 let srs = regs.srs().read().bits();
12 ResetReasonRaw(srs)
13}
14
15/// Raw reset reason bits. Can be queried or all reasons can be iterated over
16#[cfg_attr(feature = "defmt", derive(defmt::Format))]
17#[derive(Copy, Clone, Debug)]
18pub struct ResetReasonRaw(u32);
19
20#[cfg_attr(feature = "defmt", derive(defmt::Format))]
21#[derive(Copy, Clone, Debug)]
22pub struct ResetReasonRawIter(u32);
23
24impl ResetReasonRaw {
25 const MAP: &[(u32, ResetReason)] = &[
26 (1 << 0, ResetReason::WakeUp),
27 (1 << 1, ResetReason::Por),
28 (1 << 2, ResetReason::VoltageDetect),
29 (1 << 4, ResetReason::Warm),
30 (1 << 5, ResetReason::Fatal),
31 (1 << 8, ResetReason::Pin),
32 (1 << 9, ResetReason::Dap),
33 (1 << 10, ResetReason::ResetAckTimeout),
34 (1 << 11, ResetReason::LowPowerAckTimeout),
35 (1 << 12, ResetReason::SystemClockGeneration),
36 (1 << 13, ResetReason::Wwdt0),
37 (1 << 14, ResetReason::Software),
38 (1 << 15, ResetReason::Lockup),
39 (1 << 26, ResetReason::Cdog0),
40 (1 << 27, ResetReason::Cdog1),
41 (1 << 28, ResetReason::Jtag),
42 ];
43
44 /// Convert to an iterator of contained reset reasons
45 pub fn into_iter(self) -> ResetReasonRawIter {
46 ResetReasonRawIter(self.0)
47 }
48
49 /// Wake up
50 #[inline]
51 pub fn is_wakeup(&self) -> bool {
52 (self.0 & (1 << 0)) != 0
53 }
54
55 /// Power-on Reset
56 #[inline]
57 pub fn is_por(&self) -> bool {
58 (self.0 & (1 << 1)) != 0
59 }
60
61 /// Voltage detect
62 #[inline]
63 pub fn is_voltage_detect(&self) -> bool {
64 (self.0 & (1 << 2)) != 0
65 }
66
67 /// Warm
68 #[inline]
69 pub fn is_warm(&self) -> bool {
70 (self.0 & (1 << 4)) != 0
71 }
72
73 /// Fatal
74 #[inline]
75 pub fn is_fatal(&self) -> bool {
76 (self.0 & (1 << 5)) != 0
77 }
78
79 /// Pin
80 #[inline]
81 pub fn is_pin(&self) -> bool {
82 (self.0 & (1 << 8)) != 0
83 }
84
85 /// DAP
86 #[inline]
87 pub fn is_dap(&self) -> bool {
88 (self.0 & (1 << 9)) != 0
89 }
90
91 /// Reset ack timeout
92 #[inline]
93 pub fn is_reset_ack_timeout(&self) -> bool {
94 (self.0 & (1 << 10)) != 0
95 }
96
97 /// Low power ack timeout
98 #[inline]
99 pub fn is_low_power_ack_timeout(&self) -> bool {
100 (self.0 & (1 << 11)) != 0
101 }
102
103 /// System clock generation
104 #[inline]
105 pub fn is_system_clock_generation(&self) -> bool {
106 (self.0 & (1 << 12)) != 0
107 }
108
109 /// Watchdog 0
110 #[inline]
111 pub fn is_watchdog0(&self) -> bool {
112 (self.0 & (1 << 13)) != 0
113 }
114
115 /// Software
116 pub fn is_software(&self) -> bool {
117 (self.0 & (1 << 14)) != 0
118 }
119
120 /// Lockup
121 pub fn is_lockup(&self) -> bool {
122 (self.0 & (1 << 15)) != 0
123 }
124
125 /// Code watchdog 0
126 pub fn is_code_watchdog0(&self) -> bool {
127 (self.0 & (1 << 26)) != 0
128 }
129
130 /// Code watchdog 1
131 pub fn is_code_watchdog1(&self) -> bool {
132 (self.0 & (1 << 27)) != 0
133 }
134
135 /// JTAG
136 pub fn is_jtag(&self) -> bool {
137 (self.0 & (1 << 28)) != 0
138 }
139}
11 140
12 let srs = regs.srs().read(); 141impl Iterator for ResetReasonRawIter {
13 142 type Item = ResetReason;
14 if srs.wakeup().is_enabled() { 143
15 ResetReason::WakeUp 144 fn next(&mut self) -> Option<Self::Item> {
16 } else if srs.por().bit_is_set() { 145 if self.0 == 0 {
17 ResetReason::Por 146 return None;
18 } else if srs.vd().bit_is_set() { 147 }
19 ResetReason::VoltageDetect 148
20 } else if srs.warm().bit_is_set() { 149 for (mask, var) in ResetReasonRaw::MAP {
21 ResetReason::Warm 150 // If the bit is set...
22 } else if srs.fatal().bit_is_set() { 151 if self.0 & mask != 0 {
23 ResetReason::Fatal 152 // clear the bit
24 } else if srs.pin().bit_is_set() { 153 self.0 &= !mask;
25 ResetReason::Pin 154 // and return the answer
26 } else if srs.dap().bit_is_set() { 155 return Some(*var);
27 ResetReason::Dap 156 }
28 } else if srs.rstack().bit_is_set() { 157 }
29 ResetReason::ResetAckTimeout 158
30 } else if srs.lpack().bit_is_set() { 159 // Shouldn't happen, but oh well.
31 ResetReason::LowPowerAckTimeout 160 None
32 } else if srs.scg().bit_is_set() {
33 ResetReason::SystemClockGeneration
34 } else if srs.wwdt0().bit_is_set() {
35 ResetReason::Wwdt0
36 } else if srs.sw().bit_is_set() {
37 ResetReason::Software
38 } else if srs.lockup().bit_is_set() {
39 ResetReason::Lockup
40 } else if srs.cdog0().bit_is_set() {
41 ResetReason::Cdog0
42 } else if srs.cdog1().bit_is_set() {
43 ResetReason::Cdog1
44 } else if srs.jtag().bit_is_set() {
45 ResetReason::Jtag
46 } else {
47 ResetReason::Tamper
48 } 161 }
49} 162}
50 163