Skip to content

Commit 2d90da0

Browse files
committed
esp32: Deactivate wakeup trigger after first wakeup
The timer wakeup function once activated cannot be disabled later using existing api. If user wants to use different wakeup sources after first sleep but it does not work. This change disables timer wakeup trigger in configuration that will be set into appropriate RTC registers in esp_light_sleep_start() function. Added function esp_sleep_disable_wakeup_source() to deactivate wakeup trigger for selected source. Updated documentation for this function in sleep_modes.rst file to pass make html. Updated unit test to check this functionality for light sleep. The test_sleep.c unit test is updated to add reliability for auto unit testing. (TW#18952) Closes #1677
1 parent 77eae33 commit 2d90da0

File tree

5 files changed

+86
-4
lines changed

5 files changed

+86
-4
lines changed

components/esp32/include/esp_deep_sleep.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ inline static esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
4747
return esp_sleep_enable_timer_wakeup(time_in_us);
4848
}
4949

50+
inline static esp_err_t esp_deep_sleep_disable_timer_wakeup(void)
51+
{
52+
return esp_sleep_disable_timer_wakeup();
53+
}
54+
5055
inline static esp_err_t esp_deep_sleep_enable_touchpad_wakeup(void)
5156
{
5257
return esp_sleep_enable_touchpad_wakeup();

components/esp32/include/esp_sleep.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ typedef enum {
7575
*/
7676
esp_err_t esp_sleep_enable_ulp_wakeup();
7777

78-
/**
78+
/**
7979
* @brief Enable wakeup by timer
8080
* @param time_in_us time before wakeup, in microseconds
8181
* @return
@@ -84,6 +84,23 @@ esp_err_t esp_sleep_enable_ulp_wakeup();
8484
*/
8585
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us);
8686

87+
/**
88+
* @brief Disable timer wakeup
89+
*
90+
* This function is used to deactivate timer wakeup trigger
91+
* after first sleep for example to allow wakeup from other sources.
92+
*
93+
* @note This function does not modify wakeup configuration in RTC.
94+
* It will be performed in esp_sleep_start function.
95+
*
96+
* See docs/sleep-modes.rst for details.
97+
*
98+
* @return
99+
* - ESP_OK on success
100+
* - ESP_ERR_INVALID_STATE if trigger was not active
101+
*/
102+
esp_err_t esp_sleep_disable_timer_wakeup();
103+
87104
/**
88105
* @brief Enable wakeup by touch sensor
89106
*

components/esp32/sleep_modes.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,22 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
303303
return ESP_OK;
304304
}
305305

306+
esp_err_t esp_sleep_disable_timer_wakeup()
307+
{
308+
if (s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) {
309+
// The only timer wakeup trigger should be disabled, setup will
310+
// be performed in rtc_sleep_start() which updates wakeup options
311+
// in RTC peripheral registers
312+
s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN;
313+
s_config.sleep_duration = 0;
314+
}
315+
else {
316+
ESP_LOGE(TAG, "The timer wake-up trigger is not set.");
317+
return ESP_ERR_INVALID_STATE;
318+
}
319+
return ESP_OK;
320+
}
321+
306322
static void timer_wakeup_prepare()
307323
{
308324
uint32_t period = esp_clk_slowclk_cal_get();

components/esp32/test/test_sleep.c

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#include "freertos/FreeRTOS.h"
66
#include "freertos/task.h"
77

8+
#define ESP_EXT0_WAKEUP_LEVEL_LOW 0
9+
#define ESP_EXT0_WAKEUP_LEVEL_HIGH 1
10+
811
TEST_CASE("esp_deepsleep works", "[deepsleep][reset=DEEPSLEEP_RESET]")
912
{
1013
esp_deep_sleep(2000000);
@@ -33,7 +36,6 @@ TEST_CASE("wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]")
3336
esp_deep_sleep_start();
3437
}
3538

36-
3739
TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
3840
{
3941
esp_sleep_enable_timer_wakeup(2000000);
@@ -46,6 +48,44 @@ TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
4648
TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
4749
}
4850

51+
TEST_CASE("wake up disable timer for ext0 wakeup (13 low)", "[deepsleep][ignore]")
52+
{
53+
// Setup timer to wakeup with timeout
54+
esp_sleep_enable_timer_wakeup(2000000);
55+
struct timeval tv_start, tv_stop;
56+
gettimeofday(&tv_start, NULL);
57+
esp_light_sleep_start();
58+
gettimeofday(&tv_stop, NULL);
59+
float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f +
60+
(tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
61+
printf("Timer sleep time = %d\r\n", (int)dt);
62+
63+
TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
64+
65+
// Setup ext0 configuration to wake up
66+
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
67+
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
68+
ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
69+
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_LOW));
70+
71+
// Disable timer wakeup trigger to wakeup from ext0 source
72+
// instead of timer wakeup
73+
ESP_ERROR_CHECK(esp_sleep_disable_timer_wakeup());
74+
printf("Waiting low level on GPIO_13\r\n");
75+
76+
gettimeofday(&tv_start, NULL);
77+
esp_light_sleep_start();
78+
gettimeofday(&tv_stop, NULL);
79+
80+
dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f +
81+
(tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
82+
printf("Ext0 sleep time = %d\r\n", (int)dt);
83+
84+
// Check error message
85+
esp_err_t err_code = esp_sleep_disable_timer_wakeup();
86+
TEST_ASSERT(err_code == ESP_ERR_INVALID_STATE);
87+
}
88+
4989
#ifndef CONFIG_FREERTOS_UNICORE
5090
TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][reset=DEEPSLEEP_RESET]")
5191
{
@@ -60,7 +100,7 @@ TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
60100
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
61101
ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
62102
ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
63-
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1));
103+
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_HIGH));
64104
esp_deep_sleep_start();
65105
}
66106

@@ -69,7 +109,7 @@ TEST_CASE("wake up using ext0 (13 low)", "[deepsleep][ignore]")
69109
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
70110
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
71111
ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
72-
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0));
112+
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, ESP_EXT0_WAKEUP_LEVEL_LOW));
73113
esp_deep_sleep_start();
74114
}
75115

docs/api-reference/system/sleep_modes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ The following function can be used to enable deep sleep wakeup using a timer.
3737

3838
.. doxygenfunction:: esp_sleep_enable_timer_wakeup
3939

40+
The timer wakeup functionality can be disabled to use other wakeup sources instead of timer after first sleep. The function below can be used in this case.
41+
42+
.. doxygenfunction:: esp_sleep_disable_timer_wakeup
43+
4044
Touch pad
4145
^^^^^^^^^
4246

0 commit comments

Comments
 (0)