1 /*
2  * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "unity.h"
8 #include <sys/time.h>
9 #include <sys/param.h>
10 #include "esp_sleep.h"
11 #include "driver/rtc_io.h"
12 #include "freertos/FreeRTOS.h"
13 #include "freertos/task.h"
14 #include "freertos/semphr.h"
15 #include "soc/gpio_periph.h"
16 #include "hal/uart_types.h"
17 #include "hal/uart_ll.h"
18 #include "soc/rtc.h"            // for wakeup trigger defines
19 #include "soc/rtc_periph.h"     // for read rtc registers directly (cause)
20 #include "soc/soc.h"            // for direct register read macros
21 #include "hal/rtc_cntl_ll.h"
22 #include "esp_newlib.h"
23 #include "test_utils.h"
24 #include "sdkconfig.h"
25 #include "esp_rom_uart.h"
26 #include "esp_rom_sys.h"
27 #include "esp_timer.h"
28 
29 #if CONFIG_IDF_TARGET_ESP32
30 #include "esp32/clk.h"
31 #elif CONFIG_IDF_TARGET_ESP32S2
32 #include "esp32s2/clk.h"
33 #elif CONFIG_IDF_TARGET_ESP32S3
34 #include "esp32s3/clk.h"
35 #elif CONFIG_IDF_TARGET_ESP32C3
36 #include "esp32c3/clk.h"
37 #elif CONFIG_IDF_TARGET_ESP32H2
38 #include "esp32h2/clk.h"
39 #endif
40 
41 #define ESP_EXT0_WAKEUP_LEVEL_LOW 0
42 #define ESP_EXT0_WAKEUP_LEVEL_HIGH 1
43 
44 __attribute__((unused)) static struct timeval tv_start, tv_stop;
45 
46 #ifndef CONFIG_FREERTOS_UNICORE
deep_sleep_task(void * arg)47 static void deep_sleep_task(void *arg)
48 {
49     esp_deep_sleep_start();
50 }
51 
do_deep_sleep_from_app_cpu(void)52 static void do_deep_sleep_from_app_cpu(void)
53 {
54     xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1);
55 
56     // keep running some non-IRAM code
57     vTaskSuspendAll();
58 
59     while (true) {
60         ;
61     }
62 }
63 #endif
64 
65 TEST_CASE("wake up from deep sleep using timer", "[deepsleep][reset=DEEPSLEEP_RESET]")
66 {
67     esp_sleep_enable_timer_wakeup(2000000);
68     esp_deep_sleep_start();
69 }
70 
71 TEST_CASE("light sleep followed by deep sleep", "[deepsleep][reset=DEEPSLEEP_RESET]")
72 {
73     esp_sleep_enable_timer_wakeup(1000000);
74     esp_light_sleep_start();
75     esp_deep_sleep_start();
76 }
77 
78 TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
79 {
80     esp_sleep_enable_timer_wakeup(2000000);
81     struct timeval tv_start, tv_stop;
82     gettimeofday(&tv_start, NULL);
83     esp_light_sleep_start();
84     gettimeofday(&tv_stop, NULL);
85     float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f +
86                (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
87     TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
88 }
89 
test_light_sleep(void * arg)90 static void test_light_sleep(void* arg)
91 {
92     vTaskDelay(2);
93     for (int i = 0; i < 1000; ++i) {
94         printf("%d %d\n", xPortGetCoreID(), i);
95         fflush(stdout);
96         esp_light_sleep_start();
97     }
98     SemaphoreHandle_t done = (SemaphoreHandle_t) arg;
99     xSemaphoreGive(done);
100     vTaskDelete(NULL);
101 }
102 
103 TEST_CASE("light sleep stress test", "[deepsleep]")
104 {
105     SemaphoreHandle_t done = xSemaphoreCreateCounting(2, 0);
106     esp_sleep_enable_timer_wakeup(1000);
107     xTaskCreatePinnedToCore(&test_light_sleep, "ls0", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 0);
108 #if portNUM_PROCESSORS == 2
109     xTaskCreatePinnedToCore(&test_light_sleep, "ls1", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 1);
110 #endif
111     xSemaphoreTake(done, portMAX_DELAY);
112 #if portNUM_PROCESSORS == 2
113     xSemaphoreTake(done, portMAX_DELAY);
114 #endif
115     vSemaphoreDelete(done);
116 }
117 
timer_func(void * arg)118 static void timer_func(void* arg)
119 {
120     esp_rom_delay_us(50);
121 }
122 
123 TEST_CASE("light sleep stress test with periodic esp_timer", "[deepsleep]")
124 {
125     SemaphoreHandle_t done = xSemaphoreCreateCounting(2, 0);
126     esp_sleep_enable_timer_wakeup(1000);
127     esp_timer_handle_t timer;
128     esp_timer_create_args_t config = {
129             .callback = &timer_func,
130     };
131     TEST_ESP_OK(esp_timer_create(&config, &timer));
132     esp_timer_start_periodic(timer, 500);
133     xTaskCreatePinnedToCore(&test_light_sleep, "ls1", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 0);
134 #if portNUM_PROCESSORS == 2
135     xTaskCreatePinnedToCore(&test_light_sleep, "ls1", 4096, done, UNITY_FREERTOS_PRIORITY + 1, NULL, 1);
136 #endif
137     xSemaphoreTake(done, portMAX_DELAY);
138 #if portNUM_PROCESSORS == 2
139     xSemaphoreTake(done, portMAX_DELAY);
140 #endif
141     vSemaphoreDelete(done);
142     esp_timer_stop(timer);
143     esp_timer_delete(timer);
144 }
145 
146 
147 #if defined(CONFIG_ESP_SYSTEM_RTC_EXT_XTAL)
148 #define MAX_SLEEP_TIME_ERROR_US 200
149 #else
150 #define MAX_SLEEP_TIME_ERROR_US 100
151 #endif
152 
153 
154 TEST_CASE("light sleep duration is correct", "[deepsleep][ignore]")
155 {
156     // don't power down XTAL — powering it up takes different time on
157     // different boards
158     esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
159 
160     // run one light sleep without checking timing, to warm up the cache
161     esp_sleep_enable_timer_wakeup(1000);
162     esp_light_sleep_start();
163 
164     const int sleep_intervals_ms[] = {
165             1, 1, 2, 3, 4, 5, 6, 7, 8, 10, 15,
166             20, 25, 50, 100, 200, 500,
167     };
168 
169     const int sleep_intervals_count = sizeof(sleep_intervals_ms)/sizeof(sleep_intervals_ms[0]);
170     for (int i = 0; i < sleep_intervals_count; ++i) {
171         uint64_t sleep_time = sleep_intervals_ms[i] * 1000;
172         esp_sleep_enable_timer_wakeup(sleep_time);
173         for (int repeat = 0; repeat < 5; ++repeat) {
174             uint64_t start = esp_clk_rtc_time();
175             int64_t start_hs = esp_timer_get_time();
176             esp_light_sleep_start();
177             int64_t stop_hs = esp_timer_get_time();
178             uint64_t stop = esp_clk_rtc_time();
179 
180             int diff_us = (int) (stop - start);
181             int diff_hs_us = (int) (stop_hs - start_hs);
182             printf("%lld %d\n", sleep_time, (int) (diff_us - sleep_time));
183             int32_t threshold = MAX(sleep_time / 100, MAX_SLEEP_TIME_ERROR_US);
184             TEST_ASSERT_INT32_WITHIN(threshold, sleep_time, diff_us);
185             TEST_ASSERT_INT32_WITHIN(threshold, sleep_time, diff_hs_us);
186             fflush(stdout);
187         }
188 
189         vTaskDelay(10/portTICK_PERIOD_MS);
190     }
191 }
192 
193 
194 TEST_CASE("light sleep and frequency switching", "[deepsleep]")
195 {
196 #ifndef CONFIG_PM_ENABLE
197 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
198     uart_sclk_t clk_source = UART_SCLK_REF_TICK;
199 #else
200     uart_sclk_t clk_source = UART_SCLK_XTAL;
201 #endif
202     uart_ll_set_sclk(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), clk_source);
203     uart_ll_set_baudrate(UART_LL_GET_HW(CONFIG_ESP_CONSOLE_UART_NUM), CONFIG_ESP_CONSOLE_UART_BAUDRATE);
204 #endif
205 
206     rtc_cpu_freq_config_t config_xtal, config_default;
207     rtc_clk_cpu_freq_get_config(&config_default);
208     rtc_clk_cpu_freq_mhz_to_config((int) rtc_clk_xtal_freq_get(), &config_xtal);
209 
210     esp_sleep_enable_timer_wakeup(1000);
211     for (int i = 0; i < 1000; ++i) {
212         if (i % 2 == 0) {
213             rtc_clk_cpu_freq_set_config_fast(&config_xtal);
214         } else {
215             rtc_clk_cpu_freq_set_config_fast(&config_default);
216         }
217         printf("%d\n", i);
218         fflush(stdout);
219         esp_light_sleep_start();
220     }
221 }
222 
223 #ifndef CONFIG_FREERTOS_UNICORE
224 TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]")
225 {
226     esp_sleep_enable_timer_wakeup(2000000);
227     do_deep_sleep_from_app_cpu();
228 }
229 #endif
230 
do_deep_sleep(void)231 static void do_deep_sleep(void)
232 {
233     esp_sleep_enable_timer_wakeup(100000);
234     esp_deep_sleep_start();
235 }
236 
check_sleep_reset_and_sleep(void)237 static void check_sleep_reset_and_sleep(void)
238 {
239     TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason());
240     esp_sleep_enable_timer_wakeup(100000);
241     esp_deep_sleep_start();
242 }
243 
check_sleep_reset(void)244 static void check_sleep_reset(void)
245 {
246     TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason());
247 }
248 
249 TEST_CASE_MULTIPLE_STAGES("enter deep sleep more than once", "[deepsleep][reset=DEEPSLEEP_RESET,DEEPSLEEP_RESET,DEEPSLEEP_RESET]",
250         do_deep_sleep,
251         check_sleep_reset_and_sleep,
252         check_sleep_reset_and_sleep,
253         check_sleep_reset);
254 
do_abort(void)255 static void do_abort(void)
256 {
257     abort();
258 }
259 
check_abort_reset_and_sleep(void)260 static void check_abort_reset_and_sleep(void)
261 {
262     TEST_ASSERT_EQUAL(ESP_RST_PANIC, esp_reset_reason());
263     esp_sleep_enable_timer_wakeup(100000);
264     esp_deep_sleep_start();
265 }
266 
267 TEST_CASE_MULTIPLE_STAGES("enter deep sleep after abort", "[deepsleep][reset=abort,SW_CPU_RESET,DEEPSLEEP_RESET]",
268         do_abort,
269         check_abort_reset_and_sleep,
270         check_sleep_reset);
271 
272 static RTC_DATA_ATTR uint32_t s_wake_stub_var;
273 
wake_stub(void)274 static RTC_IRAM_ATTR void wake_stub(void)
275 {
276     esp_default_wake_deep_sleep();
277     s_wake_stub_var = (uint32_t) &wake_stub;
278 }
279 
prepare_wake_stub(void)280 static void prepare_wake_stub(void)
281 {
282     esp_set_deep_sleep_wake_stub(&wake_stub);
283     esp_sleep_enable_timer_wakeup(100000);
284     esp_deep_sleep_start();
285 }
286 
check_wake_stub(void)287 static void check_wake_stub(void)
288 {
289     TEST_ASSERT_EQUAL(ESP_RST_DEEPSLEEP, esp_reset_reason());
290     TEST_ASSERT_EQUAL_HEX32((uint32_t) &wake_stub, s_wake_stub_var);
291 #if !CONFIG_IDF_TARGET_ESP32S3
292     /* ROM code clears wake stub entry address */
293     TEST_ASSERT_NULL(esp_get_deep_sleep_wake_stub());
294 #endif
295 }
296 
297 TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub", "[deepsleep][reset=DEEPSLEEP_RESET]",
298         prepare_wake_stub,
299         check_wake_stub);
300 
301 
302 #if CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
303 
304 /* Version of prepare_wake_stub() that sets up the deep sleep call while running
305    from RTC memory as stack, with a high frequency timer also writing RTC FAST
306    memory.
307 
308    This is important because the ROM code (ESP32 & ESP32-S2) requires software
309    trigger a CRC calculation (done in hardware) for the entire RTC FAST memory
310    before going to deep sleep and if it's invalid then the stub is not
311    run. Also, while the CRC is being calculated the RTC FAST memory is not
312    accesible by the CPU (reads all zeros).
313 */
314 
increment_rtc_memory_cb(void * arg)315 static void increment_rtc_memory_cb(void *arg)
316 {
317     static volatile RTC_FAST_ATTR unsigned counter;
318     counter++;
319 }
320 
prepare_wake_stub_from_rtc(void)321 static void prepare_wake_stub_from_rtc(void)
322 {
323     /* RTC memory can be used as heap, however there is no API call that returns this as
324        a memory capability (as it's an implementation detail). So to test this we need to allocate
325        the stack statically.
326     */
327    #define STACK_SIZE 1500
328 #if CONFIG_IDF_TARGET_ESP32S3
329     uint8_t *sleep_stack = (uint8_t *)heap_caps_malloc(STACK_SIZE, MALLOC_CAP_RTCRAM);
330     TEST_ASSERT((uint32_t)sleep_stack >= SOC_RTC_DRAM_LOW && (uint32_t)sleep_stack < SOC_RTC_DRAM_HIGH);
331 #else
332     static RTC_FAST_ATTR uint8_t sleep_stack[STACK_SIZE];
333 #endif
334     static RTC_FAST_ATTR StaticTask_t sleep_task;
335 
336     /* normally BSS like sleep_stack will be cleared on reset, but RTC memory is not cleared on
337      * wake from deep sleep. So to ensure unused stack is different if test is re-run without a full reset,
338      * fill with some random bytes
339      */
340     esp_fill_random(sleep_stack, STACK_SIZE);
341 
342     /* to make things extra sure, start a periodic timer to write to RTC FAST RAM at high frequency */
343     const esp_timer_create_args_t timer_args = {
344                                           .callback = increment_rtc_memory_cb,
345                                           .arg = NULL,
346                                           .dispatch_method = ESP_TIMER_TASK,
347                                           .name = "Write RTC MEM"
348     };
349     esp_timer_handle_t timer;
350     ESP_ERROR_CHECK( esp_timer_create(&timer_args, &timer) );
351     ESP_ERROR_CHECK( esp_timer_start_periodic(timer, 200) );
352 
353     printf("Creating test task with stack %p\n", sleep_stack);
354     TEST_ASSERT_NOT_NULL(xTaskCreateStatic( (void *)prepare_wake_stub, "sleep", STACK_SIZE, NULL,
355                                             UNITY_FREERTOS_PRIORITY, sleep_stack, &sleep_task));
356     vTaskDelay(1000 / portTICK_PERIOD_MS);
357     TEST_FAIL_MESSAGE("Should be asleep by now");
358 }
359 
360 TEST_CASE_MULTIPLE_STAGES("can set sleep wake stub from stack in RTC RAM", "[deepsleep][reset=DEEPSLEEP_RESET]",
361         prepare_wake_stub_from_rtc,
362         check_wake_stub);
363 
364 #endif // CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
365 
366 #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
367 
368 TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
369 {
370     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
371     ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
372     ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
373     ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
374     esp_deep_sleep_start();
375 }
376 
377 TEST_CASE("wake up using ext0 (13 low)", "[deepsleep][ignore]")
378 {
379     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
380     ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
381     ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
382     ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_LOW));
383     esp_deep_sleep_start();
384 }
385 
386 TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ignore]")
387 {
388     // This test needs external pulldown
389     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
390     ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
391     esp_deep_sleep_start();
392 }
393 
394 TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ignore]")
395 {
396     // This test needs external pullup
397     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
398     ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
399     esp_deep_sleep_start();
400 }
401 
402 TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep][ignore]")
403 {
404     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
405     ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
406     ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
407     ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
408     ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
409     esp_deep_sleep_start();
410 }
411 
412 TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][ignore]")
413 {
414     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
415     ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
416     ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
417     ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
418     ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
419     esp_deep_sleep_start();
420 }
421 
get_time_ms(void)422 __attribute__((unused)) static float get_time_ms(void)
423 {
424     gettimeofday(&tv_stop, NULL);
425 
426     float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f +
427                 (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
428     return fabs(dt);
429 }
430 
get_cause(void)431 __attribute__((unused)) static uint32_t get_cause(void)
432 {
433     uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, \
434                                             RTC_CNTL_WAKEUP_CAUSE);
435     return wakeup_cause;
436 }
437 
438 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
439 // Fails on S2 IDF-2903
440 
441 // This test case verifies deactivation of trigger for wake up sources
442 TEST_CASE("disable source trigger behavior", "[deepsleep]")
443 {
444     float dt = 0;
445 
446     printf("Setup timer and ext0 to wake up immediately from GPIO_13 \n");
447 
448     // Setup ext0 configuration to wake up almost immediately
449     // The wakeup time is proportional to input capacitance * pullup resistance
450     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
451     ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
452     ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
453     ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
454 
455     // Setup timer to wakeup with timeout
456     esp_sleep_enable_timer_wakeup(2000000);
457 
458     // Save start time
459     gettimeofday(&tv_start, NULL);
460     esp_light_sleep_start();
461 
462     dt = get_time_ms();
463     printf("Ext0 sleep time = %d \n", (int) dt);
464 
465     // Check wakeup from Ext0 using time measurement because wakeup cause is
466     // not available in light sleep mode
467     TEST_ASSERT_INT32_WITHIN(100, 100, (int) dt);
468 
469     TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0);
470 
471     // Disable Ext0 source. Timer source should be triggered
472     ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0));
473     printf("Disable ext0 trigger and leave timer active.\n");
474 
475     gettimeofday(&tv_start, NULL);
476     esp_light_sleep_start();
477 
478     dt = get_time_ms();
479     printf("Timer sleep time = %d \n", (int) dt);
480 
481     TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
482 
483     // Additionally check wakeup cause
484     TEST_ASSERT((get_cause() & RTC_TIMER_TRIG_EN) != 0);
485 
486     // Disable timer source.
487     ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER));
488 
489     // Setup ext0 configuration to wake up immediately
490     ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
491     ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
492     ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
493     ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
494 
495     printf("Disable timer trigger to wake up from ext0 source.\n");
496 
497     gettimeofday(&tv_start, NULL);
498     esp_light_sleep_start();
499 
500     dt = get_time_ms();
501     printf("Ext0 sleep time = %d \n", (int) dt);
502 
503     TEST_ASSERT_INT32_WITHIN(100, 100, (int) dt);
504     TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0);
505 
506     // Check error message when source is already disabled
507     esp_err_t err_code = esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
508     TEST_ASSERT(err_code == ESP_ERR_INVALID_STATE);
509 
510     // Disable ext0 wakeup source, as this might interfere with other tests
511     ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0));
512 }
513 #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
514 
515 #endif //SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
516 
517 static RTC_DATA_ATTR struct timeval start;
trigger_deepsleep(void)518 static void trigger_deepsleep(void)
519 {
520     printf("Trigger deep sleep. Waiting for 10 sec ...\n");
521 
522     // Simulate the dispersion of the calibration coefficients at start-up.
523     // Corrupt the calibration factor.
524     esp_clk_slowclk_cal_set(esp_clk_slowclk_cal_get() / 2);
525     esp_set_time_from_rtc();
526 
527     // Delay for time error accumulation.
528     vTaskDelay(10000/portTICK_RATE_MS);
529 
530     // Save start time. Deep sleep.
531     gettimeofday(&start, NULL);
532     esp_sleep_enable_timer_wakeup(1000);
533     // In function esp_deep_sleep_start() uses function esp_sync_counters_rtc_and_frc()
534     // to prevent a negative time after wake up.
535     esp_deep_sleep_start();
536 }
537 
check_time_deepsleep(void)538 static void check_time_deepsleep(void)
539 {
540     struct timeval stop;
541     soc_reset_reason_t reason = esp_rom_get_reset_reason(0);
542     TEST_ASSERT(reason == RESET_REASON_CORE_DEEP_SLEEP);
543     gettimeofday(&stop, NULL);
544     // Time dt_ms must in any case be positive.
545     int dt_ms = (stop.tv_sec - start.tv_sec) * 1000 + (stop.tv_usec - start.tv_usec) / 1000;
546     printf("delta time = %d \n", dt_ms);
547     TEST_ASSERT_MESSAGE(dt_ms > 0, "Time in deep sleep is negative");
548 }
549 
550 TEST_CASE_MULTIPLE_STAGES("check a time after wakeup from deep sleep", "[deepsleep][reset=DEEPSLEEP_RESET]", trigger_deepsleep, check_time_deepsleep);
551 
552 #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
gpio_deepsleep_wakeup_config(void)553 static void gpio_deepsleep_wakeup_config(void)
554 {
555     gpio_config_t io_conf = {
556         .mode = GPIO_MODE_INPUT,
557         .pin_bit_mask = ((1ULL << 2) | (1ULL << 4))
558     };
559     ESP_ERROR_CHECK(gpio_config(&io_conf));
560 }
561 
562 TEST_CASE("wake up using GPIO (2 or 4 high)", "[deepsleep][ignore]")
563 {
564     gpio_deepsleep_wakeup_config();
565     ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(((1ULL << 2) | (1ULL << 4)) , ESP_GPIO_WAKEUP_GPIO_HIGH));
566     esp_deep_sleep_start();
567 }
568 
569 TEST_CASE("wake up using GPIO (2 or 4 low)", "[deepsleep][ignore]")
570 {
571     gpio_deepsleep_wakeup_config();
572     ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(((1ULL << 2) | (1ULL << 4)) , ESP_GPIO_WAKEUP_GPIO_LOW));
573     esp_deep_sleep_start();
574 }
575 #endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP
576