mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
commit
409804f673
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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"')
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user