From a7be8fddcb7f33055814018b663a8e7a8c8b1a7c Mon Sep 17 00:00:00 2001 From: jingli Date: Mon, 11 Jul 2022 15:44:38 +0800 Subject: [PATCH 1/6] examples/system/light_sleep: Add some hints in README to remind users that they can try to power down the CPU and SPI Flash for lower power consumption. --- examples/system/light_sleep/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/system/light_sleep/README.md b/examples/system/light_sleep/README.md index 94d57c3236..f975874bb3 100644 --- a/examples/system/light_sleep/README.md +++ b/examples/system/light_sleep/README.md @@ -15,6 +15,11 @@ The example enables the following wakeup sources: The example also prints time spent in light sleep mode to illustrate that timekeeping continues while the chip is in light sleep. +Note: If you find that the bottom current measured by running this example is larger than what is declared on the datasheet, you can try the following methods: + +- configure the CPU to be powered down via menuconfig(not all esp series support this feature) +- configure the SPI Flash to be powered down via menuconfig + ## How to Use Example ### Hardware Required From c6fbdb4acb5d2726b0659990b6156ac24e5b29c5 Mon Sep 17 00:00:00 2001 From: jingli Date: Tue, 12 Jul 2022 19:00:47 +0800 Subject: [PATCH 2/6] examples/system/deep_sleep: Use nvs instead of RTC_DATA_ATTR to record deep sleep enter time when the target chip does not have rtc mem. --- .../deep_sleep/main/deep_sleep_example_main.c | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/examples/system/deep_sleep/main/deep_sleep_example_main.c b/examples/system/deep_sleep/main/deep_sleep_example_main.c index f3ea42cd06..7a724e9170 100644 --- a/examples/system/deep_sleep/main/deep_sleep_example_main.c +++ b/examples/system/deep_sleep/main/deep_sleep_example_main.c @@ -21,6 +21,14 @@ #include "esp_log.h" #include "driver/rtc_io.h" #include "soc/rtc.h" +#include "nvs_flash.h" +#include "nvs.h" + +#if SOC_RTC_FAST_MEM_SUPPORTED +static RTC_DATA_ATTR struct timeval sleep_enter_time; +#else +static struct timeval sleep_enter_time; +#endif #if SOC_TOUCH_SENSOR_SUPPORTED #include "soc/sens_periph.h" @@ -36,8 +44,6 @@ #endif #endif -static RTC_DATA_ATTR struct timeval sleep_enter_time; - #ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP #if CONFIG_IDF_TARGET_ESP32 #define TOUCH_THRESH_NO_USE 0 @@ -47,6 +53,35 @@ static void calibrate_touch_pad(touch_pad_t pad); void app_main(void) { + /** + * Prefer to use RTC mem instead of NVS to save the deep sleep enter time, unless the chip + * does not support RTC mem(such as esp32c2). Because the time overhead of NVS will cause + * the recorded deep sleep enter time to be not very accurate. + */ +#if !SOC_RTC_FAST_MEM_SUPPORTED + // 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("Open NVS done\n"); + } + + // Get deep sleep enter time + nvs_get_i32(nvs_handle, "slp_enter_sec", (int32_t *)&sleep_enter_time.tv_sec); + nvs_get_i32(nvs_handle, "slp_enter_usec", (int32_t *)&sleep_enter_time.tv_usec); +#endif + struct timeval now; gettimeofday(&now, NULL); int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; @@ -220,8 +255,19 @@ void app_main(void) #endif printf("Entering deep sleep\n"); + + // get deep sleep enter time gettimeofday(&sleep_enter_time, NULL); +#if !SOC_RTC_FAST_MEM_SUPPORTED + // record deep sleep enter time via nvs + ESP_ERROR_CHECK(nvs_set_i32(nvs_handle, "slp_enter_sec", sleep_enter_time.tv_sec)); + ESP_ERROR_CHECK(nvs_set_i32(nvs_handle, "slp_enter_usec", sleep_enter_time.tv_usec)); + ESP_ERROR_CHECK(nvs_commit(nvs_handle)); + nvs_close(nvs_handle); +#endif + + // enter deep sleep esp_deep_sleep_start(); } From 63db044e9ca258880771c264f05a92195c6ce834 Mon Sep 17 00:00:00 2001 From: jingli Date: Wed, 1 Mar 2023 21:02:11 +0800 Subject: [PATCH 3/6] esp32c2/ci: reenable deep sleep example test --- examples/system/.build-test-rules.yml | 6 ------ examples/system/deep_sleep/README.md | 4 ++-- examples/system/deep_sleep/pytest_deep_sleep.py | 8 +++++--- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/examples/system/.build-test-rules.yml b/examples/system/.build-test-rules.yml index b55c9caec5..f4e3aea0b0 100644 --- a/examples/system/.build-test-rules.yml +++ b/examples/system/.build-test-rules.yml @@ -36,12 +36,6 @@ examples/system/console/basic: temporary: true reason: lack of runners -examples/system/deep_sleep: - disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet - examples/system/efuse: disable_test: - if: IDF_TARGET == "esp32s3" diff --git a/examples/system/deep_sleep/README.md b/examples/system/deep_sleep/README.md index 5b82a00d78..2bf6c32952 100644 --- a/examples/system/deep_sleep/README.md +++ b/examples/system/deep_sleep/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | # Deep Sleep Example diff --git a/examples/system/deep_sleep/pytest_deep_sleep.py b/examples/system/deep_sleep/pytest_deep_sleep.py index 12ef483fda..e58d3548bd 100644 --- a/examples/system/deep_sleep/pytest_deep_sleep.py +++ b/examples/system/deep_sleep/pytest_deep_sleep.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging @@ -12,7 +12,7 @@ touch_wake_up_support = ['esp32', 'esp32s2'] CONFIGS = [ pytest.param('esp32_singlecore', marks=[pytest.mark.esp32]), - pytest.param('basic', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32c3]), + pytest.param('basic', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32c3, pytest.mark.esp32c2]), ] @@ -60,7 +60,9 @@ def test_deep_sleep(dut: Dut) -> None: # This line indicates that the CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP option set in sdkconfig.defaults # has correctly allowed skipping verification on wakeup - dut.expect_exact('boot: Fast booting app from partition', timeout=2) + # Note: this feature depends on rtc mem + if dut.app.sdkconfig.get('SOC_RTC_MEM_SUPPORTED') is True: + dut.expect_exact('boot: Fast booting app from partition', timeout=2) # Check that it measured 2xxxxms in deep sleep, i.e at least 20 seconds: dut.expect(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms', timeout=2) From 5d6c050376b585d88ce588962f55e9aaa93adaac Mon Sep 17 00:00:00 2001 From: jingli Date: Thu, 14 Jul 2022 11:55:19 +0800 Subject: [PATCH 4/6] examples/wifi/power_save: use 1000Hz freertos tick to lower sleep time threshold --- examples/wifi/power_save/sdkconfig.defaults | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/wifi/power_save/sdkconfig.defaults b/examples/wifi/power_save/sdkconfig.defaults index 774d706160..cb1a0a7317 100644 --- a/examples/wifi/power_save/sdkconfig.defaults +++ b/examples/wifi/power_save/sdkconfig.defaults @@ -12,3 +12,5 @@ CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL=y CONFIG_PM_SLP_DISABLE_GPIO=y # Enable wifi sleep iram optimization CONFIG_ESP_WIFI_SLP_IRAM_OPT=y +# Use 1000Hz freertos tick to lower sleep time threshold +CONFIG_FREERTOS_HZ=1000 From 38c25ebcebe533dd0437f9204c29e2f4f85f7915 Mon Sep 17 00:00:00 2001 From: jingli Date: Thu, 2 Mar 2023 14:17:25 +0800 Subject: [PATCH 5/6] konfig: make rtc fast mem related kconfig depend on SOC_RTC_FAST_MEM_SUPPORTED --- components/esp_system/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_system/Kconfig b/components/esp_system/Kconfig index fd477c2848..0abd2abd9d 100644 --- a/components/esp_system/Kconfig +++ b/components/esp_system/Kconfig @@ -91,7 +91,7 @@ menu "ESP System Settings" default y if IDF_TARGET_ESP32C3 default y if IDF_TARGET_ESP32S3 default y if IDF_TARGET_ESP32H2 - depends on !IDF_TARGET_ESP32C2 + depends on SOC_RTC_FAST_MEM_SUPPORTED config ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP bool "Enable RTC fast memory for dynamic allocations" From cb64ff74fce2c99a0b314ca89f8c748414088e2f Mon Sep 17 00:00:00 2001 From: jingli Date: Mon, 6 Mar 2023 11:56:56 +0800 Subject: [PATCH 6/6] system/test: use TEST_ESP_OK instead of ESP_ERROR_CHECK --- components/esp_system/test/test_sleep.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/components/esp_system/test/test_sleep.c b/components/esp_system/test/test_sleep.c index 655e0b322a..9f2dad6116 100644 --- a/components/esp_system/test/test_sleep.c +++ b/components/esp_system/test/test_sleep.c @@ -531,10 +531,10 @@ static void trigger_deepsleep(void) 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()); + TEST_ESP_OK(nvs_flash_erase()); err = nvs_flash_init(); } - ESP_ERROR_CHECK(err); + TEST_ESP_OK(err); nvs_handle_t nvs_handle; err = nvs_open("storage", NVS_READWRITE, &nvs_handle); @@ -557,12 +557,12 @@ 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)); + TEST_ESP_OK(nvs_set_i32(nvs_handle, "start_sec", start.tv_sec)); + TEST_ESP_OK(nvs_set_i32(nvs_handle, "start_usec", start.tv_usec)); + TEST_ESP_OK(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()); + TEST_ESP_OK(nvs_flash_deinit()); esp_sleep_enable_timer_wakeup(1000); // In function esp_deep_sleep_start() uses function esp_sync_timekeeping_timers() @@ -579,10 +579,10 @@ static void check_time_deepsleep(void) 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()); + TEST_ESP_OK(nvs_flash_erase()); err = nvs_flash_init(); } - ESP_ERROR_CHECK(err); + TEST_ESP_OK(err); nvs_handle_t nvs_handle; err = nvs_open("storage", NVS_READWRITE, &nvs_handle); @@ -593,11 +593,11 @@ static void check_time_deepsleep(void) } // 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)); + TEST_ESP_OK(nvs_get_i32(nvs_handle, "start_sec", (int32_t *)&start.tv_sec)); + TEST_ESP_OK(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()); + TEST_ESP_OK(nvs_flash_deinit()); // Reset must be caused by deep sleep soc_reset_reason_t reason = esp_rom_get_reset_reason(0);