#include "rom/rtc.h"
#include "soc/rtc_cntl_reg.h"
+static void esp_reset_reason_clear_hint();
+
static esp_reset_reason_t s_reset_reason;
static esp_reset_reason_t get_reset_reason(RESET_REASON rtc_reset_reason, esp_reset_reason_t reset_reason_hint)
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(rtc_get_reset_reason(PRO_CPU_NUM),
- esp_reset_reason_get_hint());
- esp_reset_reason_set_hint(ESP_RST_UNKNOWN);
+ hint);
+ if (hint != ESP_RST_UNKNOWN) {
+ esp_reset_reason_clear_hint();
+ }
}
esp_reset_reason_t esp_reset_reason(void)
}
return (esp_reset_reason_t) low;
}
+static void esp_reset_reason_clear_hint()
+{
+ REG_WRITE(RTC_RESET_CAUSE_REG, 0);
+}
+
REG_WRITE(RTC_MEMORY_CRC_REG, stored_crc);
_lock_release(&lock_rtc_memory_crc);
- if(stored_crc == calc_crc) {
- return (esp_deep_sleep_wake_stub_fn_t)REG_READ(RTC_ENTRY_ADDR_REG);
- } else {
+ if(stored_crc != calc_crc) {
+ return NULL;
+ }
+ esp_deep_sleep_wake_stub_fn_t stub_ptr = (esp_deep_sleep_wake_stub_fn_t) REG_READ(RTC_ENTRY_ADDR_REG);
+ if (!esp_ptr_executable(stub_ptr)) {
return NULL;
}
+ return stub_ptr;
}
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
}
#endif
+static void do_deep_sleep()
+{
+ esp_sleep_enable_timer_wakeup(100000);
+ esp_deep_sleep_start();
+}
+
+static void check_sleep_reset_and_sleep()
+{
+ TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason());
+ esp_sleep_enable_timer_wakeup(100000);
+ esp_deep_sleep_start();
+}
+
+static void check_sleep_reset()
+{
+ TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason());
+}
+
+TEST_CASE_MULTIPLE_STAGES("enter deep sleep more than once", "[deepsleep][reset=DEEPSLEEP_RESET,DEEPSLEEP_RESET,DEEPSLEEP_RESET]",
+ do_deep_sleep,
+ check_sleep_reset_and_sleep,
+ check_sleep_reset_and_sleep,
+ check_sleep_reset);
+
+static void do_abort()
+{
+ abort();
+}
+
+static void check_abort_reset_and_sleep()
+{
+ TEST_ASSERT_EQUAL(ESP_RST_PANIC, esp_reset_reason());
+ esp_sleep_enable_timer_wakeup(100000);
+ esp_deep_sleep_start();
+}
+
+TEST_CASE_MULTIPLE_STAGES("enter deep sleep after abort", "[deepsleep][reset=abort,SW_CPU_RESET,DEEPSLEEP_RESET]",
+ do_abort,
+ check_abort_reset_and_sleep,
+ check_sleep_reset);
+
+static RTC_DATA_ATTR uint32_t s_wake_stub_var;
+
+static RTC_IRAM_ATTR void wake_stub()
+{
+ esp_default_wake_deep_sleep();
+ s_wake_stub_var = (uint32_t) &wake_stub;
+}
+
+static void prepare_wake_stub()
+{
+ esp_set_deep_sleep_wake_stub(&wake_stub);
+ esp_sleep_enable_timer_wakeup(100000);
+ esp_deep_sleep_start();
+}
+
+static void check_wake_stub()
+{
+ TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason());
+ TEST_ASSERT_EQUAL_HEX32((uint32_t) &wake_stub, s_wake_stub_var);
+ /* ROM code clears wake stub entry address */
+ TEST_ASSERT_NULL(esp_get_deep_sleep_wake_stub());
+}
+
+TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub", "[deepsleep][reset=DEEPSLEEP_RESET]",
+ prepare_wake_stub,
+ check_wake_stub);
+
TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
{