1
6
7
12
13
14
15
16
17
18
19
20
23
24
33
36
39
42
43
44
45
48
51
54
56
57
58
59
67
68
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
96
97
98
99
100
101
102
103
106
107
108
/* ... */
#include "esp_system.h"
#include "esp_rom_sys.h"
#include "esp_private/system_internal.h"
#include "soc/rtc_periph.h"
#include "esp32/rom/rtc.h"5 includes
static void esp_reset_reason_clear_hint(void);
static esp_reset_reason_t s_reset_reason;
static esp_reset_reason_t get_reset_reason(uint32_t rtc_reset_reason, esp_reset_reason_t reset_reason_hint)
{
switch (rtc_reset_reason) {
case RESET_REASON_CHIP_POWER_ON:
return ESP_RST_POWERON;
...
case RESET_REASON_CPU0_SW:
case RESET_REASON_CORE_SW:
if (reset_reason_hint == ESP_RST_PANIC ||
reset_reason_hint == ESP_RST_BROWNOUT ||
reset_reason_hint == ESP_RST_TASK_WDT ||
reset_reason_hint == ESP_RST_INT_WDT) {
return reset_reason_hint;
}{...}
return ESP_RST_SW;
...
case RESET_REASON_CORE_DEEP_SLEEP:
return ESP_RST_DEEPSLEEP;
...
case RESET_REASON_CORE_MWDT0:
return ESP_RST_TASK_WDT;
...
case RESET_REASON_CORE_MWDT1:
return ESP_RST_INT_WDT;
...
case RESET_REASON_CORE_RTC_WDT:
case RESET_REASON_SYS_RTC_WDT:
case RESET_REASON_CPU0_RTC_WDT:
case RESET_REASON_CPU0_MWDT0:
return ESP_RST_WDT;
...
case RESET_REASON_SYS_BROWN_OUT:
return ESP_RST_BROWNOUT;
...
case RESET_REASON_CORE_SDIO:
return ESP_RST_SDIO;
...
default:
return ESP_RST_UNKNOWN;...
}{...}
}{ ... }
static void __attribute__((constructor)) esp_reset_reason_init(void)
{
esp_reset_reason_t hint = esp_reset_reason_get_hint();
s_reset_reason = get_reset_reason(esp_rom_get_reset_reason(PRO_CPU_NUM), hint);
if (hint != ESP_RST_UNKNOWN) {
esp_reset_reason_clear_hint();
}{...}
}{ ... }
esp_reset_reason_t esp_reset_reason(void)
{
return s_reset_reason;
}{ ... }
/* ... */
#define RST_REASON_BIT 0x80000000
#define RST_REASON_MASK 0x7FFF
#define RST_REASON_SHIFT 16
void IRAM_ATTR esp_reset_reason_set_hint(esp_reset_reason_t hint)
{
assert((hint & (~RST_REASON_MASK)) == 0);
uint32_t val = hint | (hint << RST_REASON_SHIFT) | RST_REASON_BIT;
REG_WRITE(RTC_RESET_CAUSE_REG, val);
}{ ... }
esp_reset_reason_t esp_reset_reason_get_hint(void)
{
uint32_t reset_reason_hint = REG_READ(RTC_RESET_CAUSE_REG);
uint32_t high = (reset_reason_hint >> RST_REASON_SHIFT) & RST_REASON_MASK;
uint32_t low = reset_reason_hint & RST_REASON_MASK;
if ((reset_reason_hint & RST_REASON_BIT) == 0 || high != low) {
return ESP_RST_UNKNOWN;
}{...}
return (esp_reset_reason_t) low;
}{ ... }
static void esp_reset_reason_clear_hint(void)
{
REG_WRITE(RTC_RESET_CAUSE_REG, 0);
}{ ... }