Skip to content

Commit

Permalink
Merge branch 'bugfix/some_small_fix_for_sleep_examples' into 'master'
Browse files Browse the repository at this point in the history
examples: some small fix for sleep examples

See merge request espressif/esp-idf!19052
  • Loading branch information
jack0c committed Mar 7, 2023
2 parents ab8e3ef + e38e5be commit d1adc45
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 20 deletions.
2 changes: 1 addition & 1 deletion components/esp_system/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ menu "ESP System Settings"
default y if IDF_TARGET_ESP32H4
default y if IDF_TARGET_ESP32C6
default n if IDF_TARGET_ESP32H2 # IDF-5667 & IDF-6847
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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,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);
Expand All @@ -579,12 +579,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()
Expand All @@ -601,10 +601,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);
Expand All @@ -615,11 +615,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);
Expand Down
4 changes: 2 additions & 2 deletions examples/system/.build-test-rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ examples/system/console/basic:

examples/system/deep_sleep:
disable:
- if: IDF_TARGET in ["esp32c2", "esp32h2"]
- if: IDF_TARGET in ["esp32h2"]
temporary: true
reason: target(s) not supported yet # IDF-5432 / IDF-6268
reason: target(s) not supported yet # IDF-6268

examples/system/deep_sleep_wake_stub:
disable:
Expand Down
4 changes: 2 additions & 2 deletions examples/system/deep_sleep/README.md
Original file line number Diff line number Diff line change
@@ -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 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

# Deep Sleep Example

Expand Down
50 changes: 48 additions & 2 deletions examples/system/deep_sleep/main/deep_sleep_example_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -226,8 +261,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();
}

Expand Down
6 changes: 4 additions & 2 deletions examples/system/deep_sleep/pytest_deep_sleep.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

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.mark.esp32c6]),
pytest.param('basic', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32c3, pytest.mark.esp32c6, pytest.mark.esp32c2]),
]


Expand Down Expand Up @@ -60,7 +60,9 @@ def expect_enable_deep_sleep_no_touch() -> 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)
Expand Down
5 changes: 5 additions & 0 deletions examples/system/light_sleep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions examples/wifi/power_save/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit d1adc45

Please sign in to comment.