test_sleep.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "unity.h"
  2. #include <sys/time.h>
  3. #include "esp_sleep.h"
  4. #include "driver/rtc_io.h"
  5. #include "freertos/FreeRTOS.h"
  6. #include "freertos/task.h"
  7. #include "soc/rtc.h" // for wakeup trigger defines
  8. #include "soc/rtc_cntl_reg.h" // for read rtc registers directly (cause)
  9. #include "soc/soc.h" // for direct register read macros
  10. #define ESP_EXT0_WAKEUP_LEVEL_LOW 0
  11. #define ESP_EXT0_WAKEUP_LEVEL_HIGH 1
  12. static struct timeval tv_start, tv_stop;
  13. TEST_CASE("esp_deepsleep works", "[deepsleep][reset=DEEPSLEEP_RESET]")
  14. {
  15. esp_deep_sleep(2000000);
  16. }
  17. static void deep_sleep_task(void *arg)
  18. {
  19. esp_deep_sleep_start();
  20. }
  21. static void do_deep_sleep_from_app_cpu()
  22. {
  23. xTaskCreatePinnedToCore(&deep_sleep_task, "ds", 2048, NULL, 5, NULL, 1);
  24. // keep running some non-IRAM code
  25. vTaskSuspendAll();
  26. while (true) {
  27. ;
  28. }
  29. }
  30. TEST_CASE("wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]")
  31. {
  32. esp_sleep_enable_timer_wakeup(2000000);
  33. esp_deep_sleep_start();
  34. }
  35. TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
  36. {
  37. esp_sleep_enable_timer_wakeup(2000000);
  38. struct timeval tv_start, tv_stop;
  39. gettimeofday(&tv_start, NULL);
  40. esp_light_sleep_start();
  41. gettimeofday(&tv_stop, NULL);
  42. float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f +
  43. (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
  44. TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
  45. }
  46. #ifndef CONFIG_FREERTOS_UNICORE
  47. TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]")
  48. {
  49. esp_sleep_enable_timer_wakeup(2000000);
  50. do_deep_sleep_from_app_cpu();
  51. }
  52. #endif
  53. TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
  54. {
  55. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  56. ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
  57. ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
  58. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
  59. esp_deep_sleep_start();
  60. }
  61. TEST_CASE("wake up using ext0 (13 low)", "[deepsleep][ignore]")
  62. {
  63. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  64. ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
  65. ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
  66. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_LOW));
  67. esp_deep_sleep_start();
  68. }
  69. TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ignore]")
  70. {
  71. // This test needs external pulldown
  72. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  73. ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
  74. esp_deep_sleep_start();
  75. }
  76. TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ignore]")
  77. {
  78. // This test needs external pullup
  79. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  80. ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
  81. esp_deep_sleep_start();
  82. }
  83. TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep][ignore]")
  84. {
  85. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  86. ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
  87. ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
  88. ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
  89. ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
  90. esp_deep_sleep_start();
  91. }
  92. TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][ignore]")
  93. {
  94. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  95. ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
  96. ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
  97. ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
  98. ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
  99. esp_deep_sleep_start();
  100. }
  101. static float get_time_ms(void)
  102. {
  103. gettimeofday(&tv_stop, NULL);
  104. float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f +
  105. (tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
  106. return fabs(dt);
  107. }
  108. static uint32_t get_cause()
  109. {
  110. uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, \
  111. RTC_CNTL_WAKEUP_CAUSE);
  112. return wakeup_cause;
  113. }
  114. // This test case verifies deactivation of trigger for wake up sources
  115. TEST_CASE("disable source trigger behavior", "[deepsleep]")
  116. {
  117. float dt = 0;
  118. printf("Setup timer and ext0 to wakeup imediately from GPIO_13 \n");
  119. // Setup ext0 configuration to wake up almost immediately
  120. // The wakeup time is proportional to input capacitance * pullup resistance
  121. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  122. ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
  123. ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
  124. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
  125. // Setup timer to wakeup with timeout
  126. esp_sleep_enable_timer_wakeup(2000000);
  127. // Save start time
  128. gettimeofday(&tv_start, NULL);
  129. esp_light_sleep_start();
  130. dt = get_time_ms();
  131. printf("Ext0 sleep time = %d \n", (int) dt);
  132. // Check wakeup from Ext0 using time measurement because wakeup cause is
  133. // not available in light sleep mode
  134. TEST_ASSERT_INT32_WITHIN(299, 300, (int) dt);
  135. TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0);
  136. // Disable Ext0 source. Timer source should be triggered
  137. ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0));
  138. printf("Disable ext0 trigger and leave timer active.\n");
  139. gettimeofday(&tv_start, NULL);
  140. esp_light_sleep_start();
  141. dt = get_time_ms();
  142. printf("Timer sleep time = %d \n", (int) dt);
  143. TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
  144. // Additionaly check wakeup cause
  145. TEST_ASSERT((get_cause() & RTC_TIMER_TRIG_EN) != 0);
  146. // Disable timer source.
  147. ESP_ERROR_CHECK(esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER));
  148. // Setup ext0 configuration to wake up immediately
  149. ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
  150. ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
  151. ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
  152. ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
  153. printf("Disable timer trigger to wake up from ext0 source.\n");
  154. gettimeofday(&tv_start, NULL);
  155. esp_light_sleep_start();
  156. dt = get_time_ms();
  157. printf("Ext0 sleep time = %d \n", (int) dt);
  158. TEST_ASSERT_INT32_WITHIN(199, 200, (int) dt);
  159. TEST_ASSERT((get_cause() & RTC_EXT0_TRIG_EN) != 0);
  160. // Check error message when source is already disabled
  161. esp_err_t err_code = esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
  162. TEST_ASSERT(err_code == ESP_ERR_INVALID_STATE);
  163. printf("Test case completed successfully.");
  164. }