Merge branch 'feature/support_feature_depend_on_rtc_fast_mem_for_esp32c2' into 'master'

esp32c2: support feature(rtc time) depend on rtc fast mem

Closes IDF-3901, IDF-4239, IDF-5053, IDF-5060, and IDF-5131

See merge request espressif/esp-idf!19067
This commit is contained in:
Jing Li 2023-02-07 15:16:01 +08:00
commit 409804f673
19 changed files with 161 additions and 150 deletions

View File

@ -52,8 +52,9 @@ extern uint32_t g_ticks_per_us_app;
static portMUX_TYPE s_esp_rtc_time_lock = portMUX_INITIALIZER_UNLOCKED;
// TODO: IDF-4239
#if SOC_RTC_FAST_MEM_SUPPORTED
static RTC_NOINIT_ATTR uint64_t s_esp_rtc_time_us, s_rtc_last_ticks;
#endif
inline static int IRAM_ATTR s_get_cpu_freq_mhz(void)
{
@ -99,18 +100,18 @@ void IRAM_ATTR ets_update_cpu_frequency(uint32_t ticks_per_us)
uint64_t esp_rtc_get_time_us(void)
{
#if !SOC_RTC_FAST_MEM_SUPPORTED
//IDF-3901
return 0;
#endif
portENTER_CRITICAL_SAFE(&s_esp_rtc_time_lock);
const uint32_t cal = esp_clk_slowclk_cal_get();
#if SOC_RTC_FAST_MEM_SUPPORTED
if (cal == 0) {
s_esp_rtc_time_us = 0;
s_rtc_last_ticks = 0;
}
const uint64_t rtc_this_ticks = rtc_time_get();
const uint64_t ticks = rtc_this_ticks - s_rtc_last_ticks;
#else
const uint64_t ticks = rtc_time_get();
#endif
/* RTC counter result is up to 2^48, calibration factor is up to 2^24,
* for a 32kHz clock. We need to calculate (assuming no overflow):
* (ticks * cal) >> RTC_CLK_CAL_FRACT
@ -126,10 +127,16 @@ uint64_t esp_rtc_get_time_us(void)
const uint64_t ticks_high = ticks >> 32;
const uint64_t delta_time_us = ((ticks_low * cal) >> RTC_CLK_CAL_FRACT) +
((ticks_high * cal) << (32 - RTC_CLK_CAL_FRACT));
#if SOC_RTC_FAST_MEM_SUPPORTED
s_esp_rtc_time_us += delta_time_us;
s_rtc_last_ticks = rtc_this_ticks;
portEXIT_CRITICAL_SAFE(&s_esp_rtc_time_lock);
return s_esp_rtc_time_us;
#else
uint64_t esp_rtc_time_us = delta_time_us + clk_ll_rtc_slow_load_rtc_fix_us();
portEXIT_CRITICAL_SAFE(&s_esp_rtc_time_lock);
return esp_rtc_time_us;
#endif
}
void esp_clk_slowclk_cal_set(uint32_t new_cal)
@ -138,7 +145,34 @@ void esp_clk_slowclk_cal_set(uint32_t new_cal)
/* To force monotonic time values even when clock calibration value changes,
* we adjust esp_rtc_time
*/
#if SOC_RTC_FAST_MEM_SUPPORTED
esp_rtc_get_time_us();
#else
portENTER_CRITICAL_SAFE(&s_esp_rtc_time_lock);
uint32_t old_cal = clk_ll_rtc_slow_load_cal();
if (old_cal != 0) {
/**
* The logic of time correction is:
* old_rtc_us = ticks * old_cal >> RTC_CLK_CAL_FRACT + old_fix_us
* new_rtc_us = ticks * new_cal >> RTC_CLK_CAL_FRACT + new_fix_us
*
* Keep "old_rtc_us == new_rtc_us" to make time monotonically increasing,
* then we can get new_fix_us:
* new_fix_us = (ticks * old_cal >> RTC_CLK_CAL_FRACT + old_fix_us) - (ticks * new_cal >> RTC_CLK_CAL_FRACT)
*/
uint64_t ticks = rtc_time_get();
const uint64_t ticks_low = ticks & UINT32_MAX;
const uint64_t ticks_high = ticks >> 32;
uint64_t old_fix_us = clk_ll_rtc_slow_load_rtc_fix_us();
uint64_t new_fix_us;
old_fix_us += ((ticks_low * old_cal) >> RTC_CLK_CAL_FRACT) + ((ticks_high * old_cal) << (32 - RTC_CLK_CAL_FRACT));
new_fix_us = ((ticks_low * new_cal) >> RTC_CLK_CAL_FRACT) + ((ticks_high * new_cal) << (32 - RTC_CLK_CAL_FRACT));
new_fix_us = old_fix_us - new_fix_us;
clk_ll_rtc_slow_store_rtc_fix_us(new_fix_us);
}
portEXIT_CRITICAL_SAFE(&s_esp_rtc_time_lock);
#endif // SOC_RTC_FAST_MEM_SUPPORTED
#endif // CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER
clk_ll_rtc_slow_store_cal(new_cal);
}

View File

@ -490,14 +490,7 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre
//ToDo: if we are to allow placing interrupt handlers into the 0x400c0000—0x400c2000 region,
//we need to make sure the interrupt is connected to the CPU0.
//CPU1 does not have access to the RTC fast memory through this region.
if ((flags & ESP_INTR_FLAG_IRAM)
&& handler
&& !esp_ptr_in_iram(handler)
#if SOC_RTC_FAST_MEM_SUPPORTED
// IDF-3901.
&& !esp_ptr_in_rtc_iram_fast(handler)
#endif
) {
if ((flags & ESP_INTR_FLAG_IRAM) && handler && !esp_ptr_in_iram(handler) && !esp_ptr_in_rtc_iram_fast(handler)) {
return ESP_ERR_INVALID_ARG;
}

View File

@ -71,7 +71,7 @@ void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_
out_config->dbg_atten_monitor = RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT;
out_config->bias_sleep_monitor = RTC_CNTL_BIASSLP_MONITOR_DEFAULT;
out_config->dbg_atten_slp = RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
out_config->dbg_atten_slp = !(sleep_flags & RTC_SLEEP_PD_INT_8M) ? RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP : RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT;
out_config->bias_sleep_slp = RTC_CNTL_BIASSLP_SLEEP_DEFAULT;
out_config->pd_cur_monitor = RTC_CNTL_PD_CUR_MONITOR_DEFAULT;
out_config->pd_cur_slp = RTC_CNTL_PD_CUR_SLEEP_DEFAULT;
@ -176,85 +176,6 @@ uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
return rtc_sleep_finish(lslp_mem_inf_fpu);
}
#define STR2(X) #X
#define STR(X) STR2(X)
uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt)
{
REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
WRITE_PERI_REG(RTC_CNTL_SLP_REJECT_CONF_REG, reject_opt);
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG,
RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
/* Calculate RTC Fast Memory CRC (for wake stub) & go to deep sleep
Because we may be running from RTC memory as stack, we can't easily call any
functions to do this (as registers will spill to stack, corrupting the CRC).
Instead, load all the values we need into registers then use register ops only to calculate
the CRC value, write it to the RTC CRC value register, and immediately go into deep sleep.
*/
/* Values used to set the SYSTEM_RTC_FASTMEM_CONFIG_REG value */
const unsigned CRC_START_ADDR = 0;
const unsigned CRC_LEN = 0x7ff;
asm volatile(
/* Start CRC calculation */
"sw %1, 0(%0)\n" // set RTC_MEM_CRC_ADDR & RTC_MEM_CRC_LEN
"or t0, %1, %2\n"
"sw t0, 0(%0)\n" // set RTC_MEM_CRC_START
/* Wait for the CRC calculation to finish */
".Lwaitcrc:\n"
"fence\n"
"lw t0, 0(%0)\n"
"li t1, "STR(SYSTEM_RTC_MEM_CRC_FINISH)"\n"
"and t0, t0, t1\n"
"beqz t0, .Lwaitcrc\n"
"not %2, %2\n" // %2 -> ~DPORT_RTC_MEM_CRC_START
"and t0, t0, %2\n"
"sw t0, 0(%0)\n" // clear RTC_MEM_CRC_START
"fence\n"
"not %2, %2\n" // %2 -> DPORT_RTC_MEM_CRC_START, probably unnecessary but gcc assumes inputs unchanged
/* Store the calculated value in RTC_MEM_CRC_REG */
"lw t0, 0(%3)\n"
"sw t0, 0(%4)\n"
"fence\n"
/* Set register bit to go into deep sleep */
"lw t0, 0(%5)\n"
"or t0, t0, %6\n"
"sw t0, 0(%5)\n"
"fence\n"
/* Wait for sleep reject interrupt (never finishes if successful) */
".Lwaitsleep:"
"fence\n"
"lw t0, 0(%7)\n"
"and t0, t0, %8\n"
"beqz t0, .Lwaitsleep\n"
:
:
"r" (SYSTEM_RTC_FASTMEM_CONFIG_REG), // %0
"r" ( (CRC_START_ADDR << SYSTEM_RTC_MEM_CRC_START_S)
| (CRC_LEN << SYSTEM_RTC_MEM_CRC_LEN_S)), // %1
"r" (SYSTEM_RTC_MEM_CRC_START), // %2
"r" (SYSTEM_RTC_FASTMEM_CRC_REG), // %3
"r" (RTC_MEMORY_CRC_REG), // %4
"r" (RTC_CNTL_STATE0_REG), // %5
"r" (RTC_CNTL_SLEEP_EN), // %6
"r" (RTC_CNTL_INT_RAW_REG), // %7
"r" (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW) // %8
: "t0", "t1" // working registers
);
return rtc_sleep_finish(0);
}
static uint32_t rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
{
/* In deep sleep mode, we never get here */

View File

@ -217,6 +217,7 @@ static void touch_wakeup_prepare(void);
static void gpio_deep_sleep_wakeup_prepare(void);
#endif
#if SOC_RTC_FAST_MEM_SUPPORTED
#if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
static RTC_FAST_ATTR esp_deep_sleep_wake_stub_fn_t wake_stub_fn_handler = NULL;
@ -297,6 +298,7 @@ void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void)
}
void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
#endif // SOC_RTC_FAST_MEM_SUPPORTED
void esp_deep_sleep(uint64_t time_in_us)
{
@ -544,8 +546,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
#else
#if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
/* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */
#if !CONFIG_IDF_TARGET_ESP32C2
// RTC has no rtc memory, IDF-3901
#if SOC_RTC_FAST_MEM_SUPPORTED
set_rtc_memory_crc();
#endif
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, 0);
@ -614,10 +615,12 @@ void IRAM_ATTR esp_deep_sleep_start(void)
// record current RTC time
s_config.rtc_ticks_at_sleep_start = rtc_time_get();
#if SOC_RTC_FAST_MEM_SUPPORTED
// Configure wake stub
if (esp_get_deep_sleep_wake_stub() == NULL) {
esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
}
#endif // SOC_RTC_FAST_MEM_SUPPORTED
// Decide which power domains can be powered down
uint32_t pd_flags = get_power_down_flags();

View File

@ -349,8 +349,6 @@ TEST_CASE("Test starting 'External 32kHz XTAL' on the board without it.", "[test
#endif // !TEMPORARY_DISABLED_FOR_TARGETS(...)
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5060
TEST_CASE("Test rtc clk calibration compensation", "[rtc_clk]")
{
int64_t t1 = esp_rtc_get_time_us();
@ -428,5 +426,3 @@ static void check_time_deepsleep_2(void)
}
TEST_CASE_MULTIPLE_STAGES("Test rtc clk calibration compensation across deep sleep", "", trigger_deepsleep, check_time_deepsleep_1, check_time_deepsleep_2);
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)

View File

@ -280,8 +280,6 @@ TEST_CASE("Can wake up from automatic light sleep by GPIO", "[pm][ignore]")
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
#endif //CONFIG_ULP_COPROC_TYPE_FSM
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5053
typedef struct {
int delay_us;
int result;
@ -402,7 +400,6 @@ TEST_CASE("esp_timer produces correct delays with light sleep", "[pm]")
#undef NUM_INTERVALS
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
static void timer_cb1(void *arg)
{

View File

@ -45,29 +45,35 @@ extern "C" {
*
*************************************************************************************
* RTC store registers usage
* RTC_CNTL_STORE0_REG Reserved
* RTC_CNTL_STORE0_REG RTC fix us, high 32 bits
* RTC_CNTL_STORE1_REG RTC_SLOW_CLK calibration value
* RTC_CNTL_STORE2_REG Boot time, low word
* RTC_CNTL_STORE3_REG Boot time, high word
* RTC_CNTL_STORE4_REG External XTAL frequency
* RTC_CNTL_STORE5_REG APB bus frequency
* RTC_CNTL_STORE6_REG FAST_RTC_MEMORY_ENTRY
* RTC_CNTL_STORE7_REG FAST_RTC_MEMORY_CRC
* RTC_CNTL_STORE6_REG rtc reset cause
* RTC_CNTL_STORE7_REG RTC fix us, low 32 bits
*************************************************************************************
*
* Since esp32c2 does not support RTC fast mem, so use RTC store regs to record rtc time:
*
* |------------------------|----------------------------------------|
* | RTC_CNTL_STORE0_REG | RTC_CNTL_STORE7_REG |
* | rtc_fix_us(MSB) | rtc_fix_us(LSB) |
* |------------------------|----------------------------------------|
*/
#define RTC_FIX_US_HIGH_REG RTC_CNTL_STORE0_REG
#define RTC_SLOW_CLK_CAL_REG RTC_CNTL_STORE1_REG
#define RTC_BOOT_TIME_LOW_REG RTC_CNTL_STORE2_REG
#define RTC_BOOT_TIME_HIGH_REG RTC_CNTL_STORE3_REG
#define RTC_XTAL_FREQ_REG RTC_CNTL_STORE4_REG
#define RTC_APB_FREQ_REG RTC_CNTL_STORE5_REG
#define RTC_ENTRY_ADDR_REG RTC_CNTL_STORE6_REG
#define RTC_RESET_CAUSE_REG RTC_CNTL_STORE6_REG
#define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG
#define RTC_FIX_US_LOW_REG RTC_CNTL_STORE7_REG
#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code.
typedef enum {
AWAKE = 0, //<CPU ON
LIGHT_SLEEP = BIT0, //CPU waiti, PLL ON. We don't need explicitly set this mode.

View File

@ -7,10 +7,6 @@ components/esp_system/host_test/esp_system:
components/esp_system/test_apps/rtc_8md256:
disable:
- if: SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256 != 1
disable_test:
- if: IDF_TARGET == "esp32c2"
temporary: true
reason: target esp32c2 is not supported yet IDF-5131
components/esp_system/test_apps/rtc_power_modes:
enable:

View File

@ -65,16 +65,10 @@ esp_reset_reason_t esp_reset_reason(void)
return s_reset_reason;
}
/* Reset reason hint is stored in RTC_RESET_CAUSE_REG, a.k.a. RTC_CNTL_STORE6_REG,
* a.k.a. RTC_ENTRY_ADDR_REG. It is safe to use this register both for the
* deep sleep wake stub entry address and for reset reason hint, since wake stub
* is only used for deep sleep reset, and in this case the reason provided by
* esp_rom_get_reset_reason is unambiguous.
/* Reset reason hint is stored in RTC_RESET_CAUSE_REG, a.k.a. RTC_CNTL_STORE6_REG.
*
* Same layout is used as for RTC_APB_FREQ_REG (a.k.a. RTC_CNTL_STORE5_REG):
* the value is replicated in low and high half-words. In addition to that,
* MSB is set to 1, which doesn't happen when RTC_CNTL_STORE6_REG contains
* deep sleep wake stub address.
* the value is replicated in low and high half-words.
*/
#define RST_REASON_BIT 0x80000000

View File

@ -1,7 +1,8 @@
set(requires "unity"
"test_utils"
"driver"
"esp_timer")
"esp_timer"
"nvs_flash")
set(excludes "test_ipc_isr.c"
"test_ipc_isr.S"

View File

@ -27,6 +27,8 @@
#include "esp_timer.h"
#include "esp_private/esp_clk.h"
#include "esp_random.h"
#include "nvs_flash.h"
#include "nvs.h"
#if SOC_PMU_SUPPORTED
#include "esp_private/esp_pmu.h"
@ -70,8 +72,6 @@ TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][re
}
#endif
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5131
TEST_CASE("wake up from deep sleep using timer", "[deepsleep][reset=DEEPSLEEP_RESET]")
{
esp_sleep_enable_timer_wakeup(2000000);
@ -85,7 +85,6 @@ TEST_CASE("light sleep followed by deep sleep", "[deepsleep][reset=DEEPSLEEP_RES
esp_deep_sleep_start();
}
//IDF-5053
TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
{
esp_sleep_enable_timer_wakeup(2000000);
@ -97,7 +96,6 @@ TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
(tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//NOTE: Explained in IDF-1445 | MR !14996
#if !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384)
@ -238,8 +236,6 @@ TEST_CASE("light sleep and frequency switching", "[deepsleep]")
}
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5131
static void do_deep_sleep(void)
{
esp_sleep_enable_timer_wakeup(100000);
@ -281,6 +277,7 @@ TEST_CASE_MULTIPLE_STAGES("enter deep sleep after abort", "[deepsleep][reset=abo
check_abort_reset_and_sleep,
check_sleep_reset);
#if SOC_RTC_FAST_MEM_SUPPORTED
static RTC_DATA_ATTR uint32_t s_wake_stub_var;
static RTC_IRAM_ATTR void wake_stub(void)
@ -306,12 +303,10 @@ static void check_wake_stub(void)
#endif
}
TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub", "[deepsleep][reset=DEEPSLEEP_RESET]",
prepare_wake_stub,
check_wake_stub);
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
#endif // SOC_RTC_FAST_MEM_SUPPORTED
#if CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
@ -380,9 +375,7 @@ TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub from stack in RTC RAM", "[dee
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5131
#if SOC_PM_SUPPORT_EXT_WAKEUP
TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
{
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
@ -436,8 +429,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][igno
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
esp_deep_sleep_start();
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
#endif // SOC_PM_SUPPORT_EXT_WAKEUP
__attribute__((unused)) static float get_time_ms(void)
{
@ -537,11 +529,30 @@ TEST_CASE("disable source trigger behavior", "[deepsleep]")
#endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5131
static RTC_DATA_ATTR struct timeval start;
static void trigger_deepsleep(void)
{
struct timeval start;
// Use NVS instead of RTC mem to store the start time of deep sleep
// Beacuse not all esp chips support RTC mem(such as esp32c2)
// Initialize NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
nvs_handle_t nvs_handle;
err = nvs_open("storage", NVS_READWRITE, &nvs_handle);
if (err != ESP_OK) {
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
} else {
printf("Done\n");
}
printf("Trigger deep sleep. Waiting for 10 sec ...\n");
// Simulate the dispersion of the calibration coefficients at start-up.
@ -554,6 +565,14 @@ static void trigger_deepsleep(void)
// Save start time. Deep sleep.
gettimeofday(&start, NULL);
ESP_ERROR_CHECK(nvs_set_i32(nvs_handle, "start_sec", start.tv_sec));
ESP_ERROR_CHECK(nvs_set_i32(nvs_handle, "start_usec", start.tv_usec));
ESP_ERROR_CHECK(nvs_commit(nvs_handle));
nvs_close(nvs_handle);
// Deinit NVS to prevent Unity from complaining "The test leaked too much memory"
ESP_ERROR_CHECK(nvs_flash_deinit());
esp_sleep_enable_timer_wakeup(1000);
// In function esp_deep_sleep_start() uses function esp_sync_timekeeping_timers()
// to prevent a negative time after wake up.
@ -562,11 +581,39 @@ static void trigger_deepsleep(void)
static void check_time_deepsleep(void)
{
struct timeval stop;
struct timeval start, stop;
// Initialize NVS
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
nvs_handle_t nvs_handle;
err = nvs_open("storage", NVS_READWRITE, &nvs_handle);
if (err != ESP_OK) {
printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
} else {
printf("Done\n");
}
// Get start time of deep sleep
ESP_ERROR_CHECK(nvs_get_i32(nvs_handle, "start_sec", (int32_t *)&start.tv_sec));
ESP_ERROR_CHECK(nvs_get_i32(nvs_handle, "start_usec", (int32_t *)&start.tv_usec));
nvs_close(nvs_handle);
// Deinit NVS to prevent Unity from complaining "The test leaked too much memory"
ESP_ERROR_CHECK(nvs_flash_deinit());
// Reset must be caused by deep sleep
soc_reset_reason_t reason = esp_rom_get_reset_reason(0);
TEST_ASSERT(reason == RESET_REASON_CORE_DEEP_SLEEP);
gettimeofday(&stop, NULL);
// Time dt_ms must in any case be positive.
gettimeofday(&stop, NULL);
int dt_ms = (stop.tv_sec - start.tv_sec) * 1000 + (stop.tv_usec - start.tv_usec) / 1000;
printf("delta time = %d \n", dt_ms);
TEST_ASSERT_MESSAGE(dt_ms > 0, "Time in deep sleep is negative");
@ -598,5 +645,4 @@ TEST_CASE("wake up using GPIO (2 or 4 low)", "[deepsleep][ignore]")
esp_deep_sleep_start();
}
#endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) TODO: IDF-5349

View File

@ -16,9 +16,6 @@
#include "soc/soc_caps.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
//IDF-5131
static const char TAG[] = "rtc_8m";
static void test_deepsleep(bool force_rtc_periph)
@ -40,7 +37,6 @@ TEST_CASE("Can use 8MD256 as RTC clock source in deepsleep", "[pm]")
{
test_deepsleep(false);
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
static void test_lightsleep(bool force_rtc_periph)
{

View File

@ -19,11 +19,11 @@ def deepsleep_test(dut: Dut, case_name: str) -> None:
dut.expect(r'rst:.*\(%s\)' % reset_reason, timeout=10)
# IDF-5131
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c2
@pytest.mark.generic
def test_rtc_8md256_deepsleep(dut: Dut) -> None:
deepsleep_test(dut, '"Can use 8MD256 as RTC clock source in deepsleep"')

View File

@ -600,6 +600,27 @@ static inline uint32_t clk_ll_rtc_slow_load_cal(void)
return REG_READ(RTC_SLOW_CLK_CAL_REG);
}
/**
* @brief Store rtc_fix_us in RTC storage register
*
* @param rtc_fix_us The value used to correct the time obtained from the rtc timer when the calibration value changes
*/
static inline void clk_ll_rtc_slow_store_rtc_fix_us(uint64_t rtc_fix_us)
{
REG_WRITE(RTC_FIX_US_LOW_REG, rtc_fix_us);
REG_WRITE(RTC_FIX_US_HIGH_REG, rtc_fix_us >> 32);
}
/**
* @brief Load the rtc_fix_ticks from RTC storage register
*
* @return The value used to correct the time obtained from the rtc timer when the calibration value changes
*/
static inline uint64_t clk_ll_rtc_slow_load_rtc_fix_us(void)
{
return REG_READ(RTC_FIX_US_LOW_REG) | ((uint64_t)REG_READ(RTC_FIX_US_HIGH_REG) << 32);
}
#ifdef __cplusplus
}
#endif

View File

@ -104,6 +104,7 @@ set sleep_init default param
#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 5
#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_NODROP 0
#define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15
#define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_NODROP 0
#define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0
#define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0
#define RTC_CNTL_BIASSLP_SLEEP_ON 0

View File

@ -106,7 +106,7 @@ examples/system/ipc/ipc_isr:
examples/system/light_sleep:
disable:
- if: IDF_TARGET in ["esp32c2", "esp32h2"]
- if: IDF_TARGET in ["esp32h2"]
temporary: true
reason: target(s) not supported yet

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
# Light Sleep Example

View File

@ -59,8 +59,14 @@ static void light_sleep_task(void *args)
wakeup_reason = "other";
break;
}
#if CONFIG_NEWLIB_NANO_FORMAT
/* printf in newlib-nano does not support %ll format, causing example test fail */
printf("Returned from light sleep, reason: %s, t=%d ms, slept for %d ms\n",
wakeup_reason, (int) (t_after_us / 1000), (int) ((t_after_us - t_before_us) / 1000));
#else
printf("Returned from light sleep, reason: %s, t=%lld ms, slept for %lld ms\n",
wakeup_reason, t_after_us / 1000, (t_after_us - t_before_us) / 1000);
#endif
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_GPIO) {
/* Waiting for the gpio inactive, or the chip will continously trigger wakeup*/
example_wait_gpio_inactive();

View File

@ -8,11 +8,11 @@ import pytest
from pytest_embedded import Dut
# IDF-5053
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c2
@pytest.mark.esp32c6
@pytest.mark.generic
def test_light_sleep(dut: Dut) -> None: