-
Notifications
You must be signed in to change notification settings - Fork 75
/
rcm_reboot_tracking.c
83 lines (73 loc) · 3.06 KB
/
rcm_reboot_tracking.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! @file
//!
//! Copyright (c) Memfault, Inc.
//! See LICENSE for details
//!
//! A port for recovering reset reason information by reading the
//! "Reset Control Module" (RCM)'s "System Reset Status" (SRS) Register.
//!
//! See "26.4.3 System Reset Status Register" of S32K-RM for more details
#include "device_registers.h"
#include "memfault/config.h"
#include "memfault/core/debug_log.h"
#include "memfault/core/reboot_reason_types.h"
#include "memfault/core/sdk_assert.h"
#include "memfault/ports/reboot_reason.h"
#if MEMFAULT_ENABLE_REBOOT_DIAG_DUMP
#define MEMFAULT_PRINT_RESET_INFO(...) MEMFAULT_LOG_INFO(__VA_ARGS__)
#else
#define MEMFAULT_PRINT_RESET_INFO(...)
#endif
void memfault_reboot_reason_get(sResetBootupInfo *info) {
MEMFAULT_SDK_ASSERT(info != NULL);
// NB: The S32 has two reset registers:
// System Reset Status (SRS) which contains reset reasons for most recent boot
// Sticky System Reset Status (SSRS) which contains all reasons for resets since last POR
//
// We'll just use the non-sticky variant for the port!
const uint32_t reset_cause = RCM->SRS;
eMemfaultRebootReason reset_reason = kMfltRebootReason_Unknown;
MEMFAULT_LOG_INFO("Reset Reason, SRS=0x%" PRIx32, reset_cause);
MEMFAULT_PRINT_RESET_INFO("Reset Causes: ");
// From the S32K-RM:
//
// The reset value of this register depends on the reset source:
// POR (including LVD) — 0x82
// LVD (without POR) — 0x02
// Other reset — a bit is set if its corresponding reset source caused the reset
if ((reset_cause & RCM_SRS_LVD(1)) && (reset_cause & RCM_SRS_POR(1))) {
MEMFAULT_PRINT_RESET_INFO(" Low or High Voltage");
reset_reason = kMfltRebootReason_BrownOutReset;
} else if (reset_cause & RCM_SRS_POR(1)) {
MEMFAULT_PRINT_RESET_INFO(" POR");
reset_reason = kMfltRebootReason_PowerOnReset;
} else if (reset_cause & RCM_SRS_MDM_AP(1)) {
MEMFAULT_PRINT_RESET_INFO(" Debugger (AP)");
reset_reason = kMfltRebootReason_SoftwareReset;
} else if (reset_cause & RCM_SRS_SW(1)) {
MEMFAULT_PRINT_RESET_INFO(" Software");
reset_reason = kMfltRebootReason_SoftwareReset;
} else if (reset_cause & RCM_SRS_JTAG(1)) {
MEMFAULT_PRINT_RESET_INFO(" Debugger (JTAG)");
reset_reason = kMfltRebootReason_SoftwareReset;
} else if (reset_cause & RCM_SRS_PIN(1)) {
MEMFAULT_PRINT_RESET_INFO(" Reset Pin");
reset_reason = kMfltRebootReason_ButtonReset;
} else if (reset_cause & RCM_SRS_LOCKUP(1)) {
MEMFAULT_PRINT_RESET_INFO(" Lockup");
reset_reason = kMfltRebootReason_Lockup;
} else if (reset_cause & RCM_SRS_WDOG(1)) {
MEMFAULT_PRINT_RESET_INFO(" Hardware Watchdog");
reset_reason = kMfltRebootReason_HardwareWatchdog;
} else if (reset_cause & RCM_SRS_LOL(1)) {
MEMFAULT_PRINT_RESET_INFO(" Loss of Lock in PLL/FLL");
reset_reason = kMfltRebootReason_ClockFailure;
} else if (reset_cause & RCM_SRS_LOC(1)) {
MEMFAULT_PRINT_RESET_INFO(" Loss of Clock");
reset_reason = kMfltRebootReason_ClockFailure;
}
*info = (sResetBootupInfo){
.reset_reason_reg = reset_cause,
.reset_reason = reset_reason,
};
}