1 /* 2 * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include "esp_system.h" 8 #include "esp_rom_sys.h" 9 #include "esp_private/system_internal.h" 10 #include "soc/rtc_periph.h" 11 #include "esp32c2/rom/rtc.h" 12 13 static void esp_reset_reason_clear_hint(void); 14 15 static esp_reset_reason_t s_reset_reason; 16 get_reset_reason(soc_reset_reason_t rtc_reset_reason,esp_reset_reason_t reset_reason_hint)17static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason, esp_reset_reason_t reset_reason_hint) 18 { 19 switch (rtc_reset_reason) { 20 case RESET_REASON_CHIP_POWER_ON: 21 return ESP_RST_POWERON; 22 23 case RESET_REASON_CPU0_SW: 24 case RESET_REASON_CORE_SW: 25 if (reset_reason_hint == ESP_RST_PANIC || 26 reset_reason_hint == ESP_RST_BROWNOUT || 27 reset_reason_hint == ESP_RST_TASK_WDT || 28 reset_reason_hint == ESP_RST_INT_WDT) { 29 return reset_reason_hint; 30 } 31 return ESP_RST_SW; 32 33 case RESET_REASON_CORE_DEEP_SLEEP: 34 return ESP_RST_DEEPSLEEP; 35 36 case RESET_REASON_CORE_MWDT0: 37 return ESP_RST_INT_WDT; 38 39 case RESET_REASON_CORE_RTC_WDT: 40 case RESET_REASON_SYS_RTC_WDT: 41 case RESET_REASON_SYS_SUPER_WDT: 42 case RESET_REASON_CPU0_RTC_WDT: 43 case RESET_REASON_CPU0_MWDT0: 44 return ESP_RST_WDT; 45 46 case RESET_REASON_SYS_BROWN_OUT: 47 return ESP_RST_BROWNOUT; 48 49 default: 50 return ESP_RST_UNKNOWN; 51 } 52 } 53 esp_reset_reason_init(void)54void esp_reset_reason_init(void) 55 { 56 esp_reset_reason_t hint = esp_reset_reason_get_hint(); 57 s_reset_reason = get_reset_reason(esp_rom_get_reset_reason(PRO_CPU_NUM), hint); 58 if (hint != ESP_RST_UNKNOWN) { 59 esp_reset_reason_clear_hint(); 60 } 61 } 62 esp_reset_reason(void)63esp_reset_reason_t esp_reset_reason(void) 64 { 65 return s_reset_reason; 66 } 67 68 /* Reset reason hint is stored in RTC_RESET_CAUSE_REG, a.k.a. RTC_CNTL_STORE6_REG. 69 * 70 * Same layout is used as for RTC_APB_FREQ_REG (a.k.a. RTC_CNTL_STORE5_REG): 71 * the value is replicated in low and high half-words. 72 */ 73 74 #define RST_REASON_BIT 0x80000000 75 #define RST_REASON_MASK 0x7FFF 76 #define RST_REASON_SHIFT 16 77 78 /* in IRAM, can be called from panic handler */ esp_reset_reason_set_hint(esp_reset_reason_t hint)79void IRAM_ATTR esp_reset_reason_set_hint(esp_reset_reason_t hint) 80 { 81 assert((hint & (~RST_REASON_MASK)) == 0); 82 uint32_t val = hint | (hint << RST_REASON_SHIFT) | RST_REASON_BIT; 83 REG_WRITE(RTC_RESET_CAUSE_REG, val); 84 } 85 86 /* in IRAM, can be called from panic handler */ esp_reset_reason_get_hint(void)87esp_reset_reason_t esp_reset_reason_get_hint(void) 88 { 89 uint32_t reset_reason_hint = REG_READ(RTC_RESET_CAUSE_REG); 90 uint32_t high = (reset_reason_hint >> RST_REASON_SHIFT) & RST_REASON_MASK; 91 uint32_t low = reset_reason_hint & RST_REASON_MASK; 92 if ((reset_reason_hint & RST_REASON_BIT) == 0 || high != low) { 93 return ESP_RST_UNKNOWN; 94 } 95 return (esp_reset_reason_t) low; 96 } esp_reset_reason_clear_hint(void)97static inline void esp_reset_reason_clear_hint(void) 98 { 99 REG_WRITE(RTC_RESET_CAUSE_REG, 0); 100 } 101