Skip to content

Commit 2b4cad8

Browse files
authored
rcc: Add reset reason calculation determination (#9)
The reset_reason submodule is used to determine the reset reason after a reset. As with the rest of the RCC code, this is adapted from same module in stm32h7xx-hal.
1 parent 8a23b98 commit 2b4cad8

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed

src/rcc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1+
mod reset_reason;

src/rcc/reset_reason.rs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
//! A module that can capture the RCC registers and read the reason why the mcu
2+
//! has reset
3+
4+
use core::fmt::Display;
5+
6+
/// Gets and clears the reason of why the mcu was reset
7+
#[rustfmt::skip]
8+
#[allow(dead_code)]
9+
pub fn get_reset_reason(rcc: &mut crate::stm32::RCC) -> ResetReason {
10+
let reset_reason = rcc.rsr().read();
11+
12+
// Clear the register
13+
rcc.rsr().modify(|_, w| w.rmvf().reset());
14+
15+
#[cfg(feature = "rm0492")]
16+
// See R0492 Section 10.3.4 Reset source identification
17+
return match (
18+
reset_reason.lpwrrstf().is_reset_occurred(),
19+
reset_reason.wwdgrstf().is_reset_occurred(),
20+
reset_reason.iwdgrstf().is_reset_occurred(),
21+
reset_reason.sftrstf().is_reset_occurred(),
22+
reset_reason.borrstf().is_reset_occurred(),
23+
reset_reason.pinrstf().is_reset_occurred(),
24+
) {
25+
(false, false, false, false, true, true) => {
26+
ResetReason::PowerOnReset
27+
}
28+
(false, false, false, false, false, true) => {
29+
ResetReason::PinReset
30+
}
31+
(false, false, false, true, false, true) => {
32+
ResetReason::SystemReset
33+
}
34+
(false, true, false, false, false, true) => {
35+
ResetReason::WindowWatchdogReset
36+
}
37+
(false, false, true, false, false, true) => {
38+
ResetReason::IndependentWatchdogReset
39+
}
40+
(true, false, false, false, false, true) => {
41+
ResetReason::IllegalStopEntryReset
42+
}
43+
(false, true, true, false, false, true) => {
44+
ResetReason::GenericWatchdogReset
45+
}
46+
_ => ResetReason::Unknown {
47+
rcc_rsr: reset_reason.bits(),
48+
},
49+
};
50+
51+
#[cfg(feature = "rm0481")]
52+
return ResetReason::Unknown { rcc_rsr: reset_reason.bits() }
53+
54+
}
55+
56+
/// Gives the reason why the mcu was reset
57+
#[derive(Debug, Copy, Clone)]
58+
#[allow(dead_code)]
59+
pub enum ResetReason {
60+
/// The mcu went from not having power to having power and resetting
61+
PowerOnReset,
62+
/// The reset pin was asserted
63+
PinReset,
64+
/// The software did a soft reset through the AIRCR register of the M33 core
65+
SystemReset,
66+
/// The window watchdog triggered
67+
WindowWatchdogReset,
68+
/// The independent watchdog triggered
69+
IndependentWatchdogReset,
70+
/// Either or both of the two watchdogs triggered (but we don't know which one)
71+
GenericWatchdogReset,
72+
/// Illegal stop entry reset triggered
73+
IllegalStopEntryReset,
74+
/// The reason could not be determined
75+
Unknown {
76+
/// The raw register value
77+
rcc_rsr: u32,
78+
},
79+
}
80+
81+
impl Display for ResetReason {
82+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83+
match self {
84+
ResetReason::PowerOnReset => write!(f, "Power-on reset"),
85+
ResetReason::PinReset => write!(f, "Pin reset (NRST)"),
86+
ResetReason::SystemReset => {
87+
write!(f, "System reset generated by CPU (SYSRESETREQ)")
88+
}
89+
ResetReason::WindowWatchdogReset => write!(f, "WWDG reset"),
90+
ResetReason::IndependentWatchdogReset => write!(f, "IWDG reset"),
91+
ResetReason::GenericWatchdogReset => {
92+
write!(f, "IWDG or WWDG reset")
93+
}
94+
ResetReason::IllegalStopEntryReset => {
95+
write!(f, "Illegal stop entry reset")
96+
}
97+
ResetReason::Unknown { rcc_rsr } => write!(
98+
f,
99+
"Could not determine the cause. RCC RSR bits were 0x{:X}",
100+
rcc_rsr
101+
),
102+
}
103+
}
104+
}
105+
106+
#[cfg(feature = "defmt")]
107+
impl defmt::Format for ResetReason {
108+
fn format(&self, f: defmt::Formatter<'_>) {
109+
match self {
110+
ResetReason::PowerOnReset => {
111+
defmt::intern!("Power-on reset").format(f)
112+
}
113+
ResetReason::PinReset => {
114+
defmt::intern!("Pin reset (NRST)").format(f)
115+
}
116+
ResetReason::SystemReset => {
117+
defmt::intern!("System reset generated by CPU (SYSRESETREQ)")
118+
.format(f)
119+
}
120+
ResetReason::WindowWatchdogReset => {
121+
defmt::intern!("WWDG reset").format(f)
122+
}
123+
ResetReason::IndependentWatchdogReset => {
124+
defmt::intern!("IWDG reset").format(f)
125+
}
126+
ResetReason::GenericWatchdogReset => {
127+
defmt::intern!("IWDG or WWDG reset").format(f)
128+
}
129+
ResetReason::IllegalStopEntryReset => {
130+
defmt::intern!("Illegal stop entry reset").format(f)
131+
}
132+
ResetReason::Unknown { rcc_rsr } => defmt::write!(
133+
f,
134+
"Could not determine the cause. RCC RSR bits were 0x{:X}",
135+
rcc_rsr
136+
),
137+
}
138+
}
139+
}

0 commit comments

Comments
 (0)