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