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