Merge branch 'feature/light_sleep' into 'master'

Rename esp_deep_sleep_ APIs to esp_sleep_, introduce light sleep function

See merge request !1168
This commit is contained in:
Ivan Grokhotkov 2017-09-01 11:10:52 +08:00
commit 98e5c475b3
26 changed files with 749 additions and 491 deletions

View file

@ -268,7 +268,7 @@ void start_cpu0_default(void)
_GLOBAL_REENT->_stderr = (FILE*) &__sf_fake_stderr;
#endif
esp_timer_init();
esp_setup_time_syscalls();
esp_set_time_from_rtc();
#if CONFIG_ESP32_APPTRACE_ENABLE
esp_err_t err = esp_apptrace_init();
if (err != ESP_OK) {

View file

@ -184,7 +184,7 @@ void esp_dport_access_int_init(void)
assert(res == pdTRUE);
}
void esp_dport_access_int_deinit(void)
void esp_dport_access_int_pause(void)
{
portENTER_CRITICAL_ISR(&g_dport_mux);
dport_core_state[0] = DPORT_CORE_STATE_IDLE;
@ -193,3 +193,14 @@ void esp_dport_access_int_deinit(void)
#endif
portEXIT_CRITICAL_ISR(&g_dport_mux);
}
void esp_dport_access_int_resume(void)
{
portENTER_CRITICAL_ISR(&g_dport_mux);
dport_core_state[0] = DPORT_CORE_STATE_RUNNING;
#ifndef CONFIG_FREERTOS_UNICORE
dport_core_state[1] = DPORT_CORE_STATE_RUNNING;
#endif
portEXIT_CRITICAL_ISR(&g_dport_mux);
}

View file

@ -1,4 +1,4 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -14,281 +14,81 @@
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "driver/gpio.h"
#include "driver/touch_pad.h"
/**
* @file esp_deep_sleep.h
* @brief legacy definitions of esp_deep_sleep APIs
*
* This file provides compatibility for applications using esp_deep_sleep_* APIs.
* New applications should use functions defined in "esp_sleep.h" instead.
* These functions and types will be deprecated at some point.
*/
#warning esp_deep_sleep.h will be deprecated in the next release. Use esp_sleep.h instead.
#include "esp_sleep.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Logic function used for EXT1 wakeup mode.
*/
typedef enum {
ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low
ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high
} esp_ext1_wakeup_mode_t;
typedef esp_sleep_pd_domain_t esp_deep_sleep_pd_domain_t;
typedef esp_sleep_pd_option_t esp_deep_sleep_pd_option_t;
typedef esp_sleep_ext1_wakeup_mode_t esp_ext1_wakeup_mode_t;
typedef esp_sleep_wakeup_cause_t esp_deep_sleep_wakeup_cause_t;
/**
* @brief Power domains which can be powered down in deep sleep
*/
typedef enum {
ESP_PD_DOMAIN_RTC_PERIPH, //!< RTC IO, sensors and ULP co-processor
ESP_PD_DOMAIN_RTC_SLOW_MEM, //!< RTC slow memory
ESP_PD_DOMAIN_RTC_FAST_MEM, //!< RTC fast memory
ESP_PD_DOMAIN_MAX //!< Number of domains
} esp_deep_sleep_pd_domain_t;
inline static esp_err_t esp_deep_sleep_enable_ulp_wakeup(void)
{
return esp_sleep_enable_ulp_wakeup();
}
/**
* @brief Power down options
*/
typedef enum {
ESP_PD_OPTION_OFF, //!< Power down the power domain in deep sleep
ESP_PD_OPTION_ON, //!< Keep power domain enabled during deep sleep
ESP_PD_OPTION_AUTO //!< Keep power domain enabled in deep sleep, if it is needed by one of the wakeup options. Otherwise power it down.
} esp_deep_sleep_pd_option_t;
inline static esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
{
return esp_sleep_enable_timer_wakeup(time_in_us);
}
/**
* @brief Deep sleep wakeup cause
*/
typedef enum {
ESP_DEEP_SLEEP_WAKEUP_UNDEFINED, //! Wakeup was not caused by deep sleep
ESP_DEEP_SLEEP_WAKEUP_EXT0, //! Wakeup caused by external signal using RTC_IO
ESP_DEEP_SLEEP_WAKEUP_EXT1, //! Wakeup caused by external signal using RTC_CNTL
ESP_DEEP_SLEEP_WAKEUP_TIMER, //! Wakeup caused by timer
ESP_DEEP_SLEEP_WAKEUP_TOUCHPAD, //! Wakeup caused by touchpad
ESP_DEEP_SLEEP_WAKEUP_ULP, //! Wakeup caused by ULP program
} esp_deep_sleep_wakeup_cause_t;
inline static esp_err_t esp_deep_sleep_enable_touchpad_wakeup(void)
{
return esp_sleep_enable_touchpad_wakeup();
}
inline static touch_pad_t esp_deep_sleep_get_touchpad_wakeup_status()
{
return esp_sleep_get_touchpad_wakeup_status();
}
/**
* @brief Enable wakeup by ULP coprocessor
* @note In revisions 0 and 1 of the ESP32, ULP wakeup source
* can not be used when RTC_PERIPH power domain is forced
* to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup
* source is used.
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if ULP co-processor is not enabled or if wakeup triggers conflict
*/
esp_err_t esp_deep_sleep_enable_ulp_wakeup();
inline static esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
{
return esp_sleep_enable_ext0_wakeup(gpio_num, level);
}
/**
* @brief Enable wakeup by timer
* @param time_in_us time before wakeup, in microseconds
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if value is out of range (TBD)
*/
esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us);
inline static esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode)
{
return esp_sleep_enable_ext1_wakeup(mask, mode);
}
/**
* @brief Enable wakeup by touch sensor
*
* @note In revisions 0 and 1 of the ESP32, touch wakeup source
* can not be used when RTC_PERIPH power domain is forced
* to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup
* source is used.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if wakeup triggers conflict
*/
esp_err_t esp_deep_sleep_enable_touchpad_wakeup();
inline static esp_err_t esp_deep_sleep_pd_config(
esp_deep_sleep_pd_domain_t domain,
esp_deep_sleep_pd_option_t option)
{
return esp_sleep_pd_config(domain, option);
}
/**
* @brief Get the touch pad which caused wakeup
*
* If wakeup was caused by another source, this function will return TOUCH_PAD_MAX;
*
* @return touch pad which caused wakeup
*/
touch_pad_t esp_deep_sleep_get_touchpad_wakeup_status();
inline static esp_deep_sleep_wakeup_cause_t esp_deep_sleep_get_wakeup_cause()
{
return esp_sleep_get_wakeup_cause();
}
/**
* @brief Enable wakeup using a pin
*
* This function uses external wakeup feature of RTC_IO peripheral.
* It will work only if RTC peripherals are kept on during deep sleep.
*
* This feature can monitor any pin which is an RTC IO. Once the pin transitions
* into the state given by level argument, the chip will be woken up.
*
* @note This function does not modify pin configuration. The pin is
* configured in esp_deep_sleep_start, immediately before
* entering deep sleep.
*
* @note In revisions 0 and 1 of the ESP32, ext0 wakeup source
* can not be used together with touch or ULP wakeup sources.
*
* @param gpio_num GPIO number used as wakeup source. Only GPIOs which are have RTC
* functionality can be used: 0,2,4,12-15,25-27,32-39.
* @param level input level which will trigger wakeup (0=low, 1=high)
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if the selected GPIO is not an RTC GPIO,
* or the mode is invalid
* - ESP_ERR_INVALID_STATE if wakeup triggers conflict
*/
esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
#define ESP_DEEP_SLEEP_WAKEUP_UNDEFINED ESP_SLEEP_WAKEUP_UNDEFINED
#define ESP_DEEP_SLEEP_WAKEUP_EXT0 ESP_SLEEP_WAKEUP_EXT0
#define ESP_DEEP_SLEEP_WAKEUP_EXT1 ESP_SLEEP_WAKEUP_EXT1
#define ESP_DEEP_SLEEP_WAKEUP_TIMER ESP_SLEEP_WAKEUP_TIMER
#define ESP_DEEP_SLEEP_WAKEUP_TOUCHPAD ESP_SLEEP_WAKEUP_TOUCHPAD
#define ESP_DEEP_SLEEP_WAKEUP_ULP ESP_SLEEP_WAKEUP_ULP
/**
* @brief Enable wakeup using multiple pins
*
* This function uses external wakeup feature of RTC controller.
* It will work even if RTC peripherals are shut down during deep sleep.
*
* This feature can monitor any number of pins which are in RTC IOs.
* Once any of the selected pins goes into the state given by mode argument,
* the chip will be woken up.
*
* @note This function does not modify pin configuration. The pins are
* configured in esp_deep_sleep_start, immediately before
* entering deep sleep.
*
* @note internal pullups and pulldowns don't work when RTC peripherals are
* shut down. In this case, external resistors need to be added.
* Alternatively, RTC peripherals (and pullups/pulldowns) may be
* kept enabled using esp_deep_sleep_pd_config function.
*
* @param mask bit mask of GPIO numbers which will cause wakeup. Only GPIOs
* which are have RTC functionality can be used in this bit map:
* 0,2,4,12-15,25-27,32-39.
* @param mode select logic function used to determine wakeup condition:
* - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
* - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO,
* or mode is invalid
*/
esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode);
/**
* @brief Get the bit mask of GPIOs which caused wakeup (ext1)
*
* If wakeup was caused by another source, this function will return 0.
*
* @return bit mask, if GPIOn caused wakeup, BIT(n) will be set
*/
uint64_t esp_deep_sleep_get_ext1_wakeup_status();
/**
* @brief Set power down mode for an RTC power domain in deep sleep
*
* If not set set using this API, all power domains default to ESP_PD_OPTION_AUTO.
*
* @param domain power domain to configure
* @param option power down option (ESP_PD_OPTION_OFF, ESP_PD_OPTION_ON, or ESP_PD_OPTION_AUTO)
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
*/
esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain,
esp_deep_sleep_pd_option_t option);
/**
* @brief Enter deep sleep with the configured wakeup options
*
* This function does not return.
*/
void esp_deep_sleep_start() __attribute__((noreturn));
/**
* @brief Enter deep-sleep mode
*
* The device will automatically wake up after the deep-sleep time
* Upon waking up, the device calls deep sleep wake stub, and then proceeds
* to load application.
*
* Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup
* followed by a call to esp_deep_sleep_start.
*
* esp_deep_sleep does not shut down WiFi, BT, and higher level protocol
* connections gracefully.
* Make sure relevant WiFi and BT stack functions are called to close any
* connections and deinitialize the peripherals. These include:
* - esp_bluedroid_disable
* - esp_bt_controller_disable
* - esp_wifi_stop
*
* This function does not return.
*
* @param time_in_us deep-sleep time, unit: microsecond
*/
void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn));
/**
* @brief Enter deep-sleep mode
*
* Function has been renamed to esp_deep_sleep.
* This name is deprecated and will be removed in a future version.
*
* @param time_in_us deep-sleep time, unit: microsecond
*/
void system_deep_sleep(uint64_t time_in_us) __attribute__((noreturn, deprecated));
/**
* @brief Get the source which caused deep sleep wakeup
*
* @return wakeup cause, or ESP_DEEP_SLEEP_WAKEUP_UNDEFINED if reset reason is other than deep sleep reset.
*/
esp_deep_sleep_wakeup_cause_t esp_deep_sleep_get_wakeup_cause();
/**
* @brief Default stub to run on wake from deep sleep.
*
* Allows for executing code immediately on wake from sleep, before
* the software bootloader or ESP-IDF app has started up.
*
* This function is weak-linked, so you can implement your own version
* to run code immediately when the chip wakes from
* sleep.
*
* See docs/deep-sleep-stub.rst for details.
*/
void esp_wake_deep_sleep(void);
/**
* @brief Function type for stub to run on wake from sleep.
*
*/
typedef void (*esp_deep_sleep_wake_stub_fn_t)(void);
/**
* @brief Install a new stub at runtime to run on wake from deep sleep
*
* If implementing esp_wake_deep_sleep() then it is not necessary to
* call this function.
*
* However, it is possible to call this function to substitute a
* different deep sleep stub. Any function used as a deep sleep stub
* must be marked RTC_IRAM_ATTR, and must obey the same rules given
* for esp_wake_deep_sleep().
*/
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub);
/**
* @brief Get current wake from deep sleep stub
* @return Return current wake from deep sleep stub, or NULL if
* no stub is installed.
*/
esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
/**
* @brief The default esp-idf-provided esp_wake_deep_sleep() stub.
*
* See docs/deep-sleep-stub.rst for details.
*/
void esp_default_wake_deep_sleep(void);
#ifdef __cplusplus
}
#endif

View file

@ -1,2 +1,2 @@
#warning esp_deepsleep.h has been renamed to esp_deep_sleep.h, please update include directives
#include "esp_deep_sleep.h"
#warning esp_deepsleep.h has been renamed to esp_sleep.h, please update include directives
#include "esp_sleep.h"

View file

@ -24,7 +24,8 @@ extern "C" {
void esp_dport_access_stall_other_cpu_start(void);
void esp_dport_access_stall_other_cpu_end(void);
void esp_dport_access_int_init(void);
void esp_dport_access_int_deinit(void);
void esp_dport_access_int_pause(void);
void esp_dport_access_int_resume(void);
#if defined(BOOTLOADER_BUILD) || defined(CONFIG_FREERTOS_UNICORE) || !defined(ESP_PLATFORM)
#define DPORT_STALL_OTHER_CPU_START()

View file

@ -0,0 +1,301 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "driver/gpio.h"
#include "driver/touch_pad.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Logic function used for EXT1 wakeup mode.
*/
typedef enum {
ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low
ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high
} esp_sleep_ext1_wakeup_mode_t;
/**
* @brief Power domains which can be powered down in sleep mode
*/
typedef enum {
ESP_PD_DOMAIN_RTC_PERIPH, //!< RTC IO, sensors and ULP co-processor
ESP_PD_DOMAIN_RTC_SLOW_MEM, //!< RTC slow memory
ESP_PD_DOMAIN_RTC_FAST_MEM, //!< RTC fast memory
ESP_PD_DOMAIN_MAX //!< Number of domains
} esp_sleep_pd_domain_t;
/**
* @brief Power down options
*/
typedef enum {
ESP_PD_OPTION_OFF, //!< Power down the power domain in sleep mode
ESP_PD_OPTION_ON, //!< Keep power domain enabled during sleep mode
ESP_PD_OPTION_AUTO //!< Keep power domain enabled in sleep mode, if it is needed by one of the wakeup options. Otherwise power it down.
} esp_sleep_pd_option_t;
/**
* @brief Sleep wakeup cause
*/
typedef enum {
ESP_SLEEP_WAKEUP_UNDEFINED, //! In case of deep sleep, reset was not caused by exit from deep sleep
ESP_SLEEP_WAKEUP_EXT0, //! Wakeup caused by external signal using RTC_IO
ESP_SLEEP_WAKEUP_EXT1, //! Wakeup caused by external signal using RTC_CNTL
ESP_SLEEP_WAKEUP_TIMER, //! Wakeup caused by timer
ESP_SLEEP_WAKEUP_TOUCHPAD, //! Wakeup caused by touchpad
ESP_SLEEP_WAKEUP_ULP, //! Wakeup caused by ULP program
} esp_sleep_wakeup_cause_t;
/**
* @brief Enable wakeup by ULP coprocessor
* @note In revisions 0 and 1 of the ESP32, ULP wakeup source
* can not be used when RTC_PERIPH power domain is forced
* to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup
* source is used.
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if ULP co-processor is not enabled or if wakeup triggers conflict
*/
esp_err_t esp_sleep_enable_ulp_wakeup();
/**
* @brief Enable wakeup by timer
* @param time_in_us time before wakeup, in microseconds
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if value is out of range (TBD)
*/
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us);
/**
* @brief Enable wakeup by touch sensor
*
* @note In revisions 0 and 1 of the ESP32, touch wakeup source
* can not be used when RTC_PERIPH power domain is forced
* to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup
* source is used.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if wakeup triggers conflict
*/
esp_err_t esp_sleep_enable_touchpad_wakeup();
/**
* @brief Get the touch pad which caused wakeup
*
* If wakeup was caused by another source, this function will return TOUCH_PAD_MAX;
*
* @return touch pad which caused wakeup
*/
touch_pad_t esp_sleep_get_touchpad_wakeup_status();
/**
* @brief Enable wakeup using a pin
*
* This function uses external wakeup feature of RTC_IO peripheral.
* It will work only if RTC peripherals are kept on during sleep.
*
* This feature can monitor any pin which is an RTC IO. Once the pin transitions
* into the state given by level argument, the chip will be woken up.
*
* @note This function does not modify pin configuration. The pin is
* configured in esp_sleep_start, immediately before entering sleep mode.
*
* @note In revisions 0 and 1 of the ESP32, ext0 wakeup source
* can not be used together with touch or ULP wakeup sources.
*
* @param gpio_num GPIO number used as wakeup source. Only GPIOs which are have RTC
* functionality can be used: 0,2,4,12-15,25-27,32-39.
* @param level input level which will trigger wakeup (0=low, 1=high)
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if the selected GPIO is not an RTC GPIO,
* or the mode is invalid
* - ESP_ERR_INVALID_STATE if wakeup triggers conflict
*/
esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
/**
* @brief Enable wakeup using multiple pins
*
* This function uses external wakeup feature of RTC controller.
* It will work even if RTC peripherals are shut down during sleep.
*
* This feature can monitor any number of pins which are in RTC IOs.
* Once any of the selected pins goes into the state given by mode argument,
* the chip will be woken up.
*
* @note This function does not modify pin configuration. The pins are
* configured in esp_sleep_start, immediately before
* entering sleep mode.
*
* @note internal pullups and pulldowns don't work when RTC peripherals are
* shut down. In this case, external resistors need to be added.
* Alternatively, RTC peripherals (and pullups/pulldowns) may be
* kept enabled using esp_sleep_pd_config function.
*
* @param mask bit mask of GPIO numbers which will cause wakeup. Only GPIOs
* which are have RTC functionality can be used in this bit map:
* 0,2,4,12-15,25-27,32-39.
* @param mode select logic function used to determine wakeup condition:
* - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
* - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO,
* or mode is invalid
*/
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode);
/**
* @brief Get the bit mask of GPIOs which caused wakeup (ext1)
*
* If wakeup was caused by another source, this function will return 0.
*
* @return bit mask, if GPIOn caused wakeup, BIT(n) will be set
*/
uint64_t esp_sleep_get_ext1_wakeup_status();
/**
* @brief Set power down mode for an RTC power domain in sleep mode
*
* If not set set using this API, all power domains default to ESP_PD_OPTION_AUTO.
*
* @param domain power domain to configure
* @param option power down option (ESP_PD_OPTION_OFF, ESP_PD_OPTION_ON, or ESP_PD_OPTION_AUTO)
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG if either of the arguments is out of range
*/
esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain,
esp_sleep_pd_option_t option);
/**
* @brief Enter deep sleep with the configured wakeup options
*
* This function does not return.
*/
void esp_deep_sleep_start() __attribute__((noreturn));
/**
* @brief Enter light sleep with the configured wakeup options
*
* @return
* - ESP_OK on success (returned after wakeup)
* - ESP_ERR_INVALID_STATE if WiFi or BT is not stopped
*/
esp_err_t esp_light_sleep_start();
/**
* @brief Enter deep-sleep mode
*
* The device will automatically wake up after the deep-sleep time
* Upon waking up, the device calls deep sleep wake stub, and then proceeds
* to load application.
*
* Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup
* followed by a call to esp_deep_sleep_start.
*
* esp_deep_sleep does not shut down WiFi, BT, and higher level protocol
* connections gracefully.
* Make sure relevant WiFi and BT stack functions are called to close any
* connections and deinitialize the peripherals. These include:
* - esp_bluedroid_disable
* - esp_bt_controller_disable
* - esp_wifi_stop
*
* This function does not return.
*
* @param time_in_us deep-sleep time, unit: microsecond
*/
void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn));
/**
* @brief Enter deep-sleep mode
*
* Function has been renamed to esp_deep_sleep.
* This name is deprecated and will be removed in a future version.
*
* @param time_in_us deep-sleep time, unit: microsecond
*/
void system_deep_sleep(uint64_t time_in_us) __attribute__((noreturn, deprecated));
/**
* @brief Get the source which caused wakeup from sleep
*
* @return wakeup cause, or ESP_DEEP_SLEEP_WAKEUP_UNDEFINED if reset happened for reason other than deep sleep wakeup
*/
esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause();
/**
* @brief Default stub to run on wake from deep sleep.
*
* Allows for executing code immediately on wake from sleep, before
* the software bootloader or ESP-IDF app has started up.
*
* This function is weak-linked, so you can implement your own version
* to run code immediately when the chip wakes from
* sleep.
*
* See docs/deep-sleep-stub.rst for details.
*/
void esp_wake_deep_sleep(void);
/**
* @brief Function type for stub to run on wake from sleep.
*
*/
typedef void (*esp_deep_sleep_wake_stub_fn_t)(void);
/**
* @brief Install a new stub at runtime to run on wake from deep sleep
*
* If implementing esp_wake_deep_sleep() then it is not necessary to
* call this function.
*
* However, it is possible to call this function to substitute a
* different deep sleep stub. Any function used as a deep sleep stub
* must be marked RTC_IRAM_ATTR, and must obey the same rules given
* for esp_wake_deep_sleep().
*/
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub);
/**
* @brief Get current wake from deep sleep stub
* @return Return current wake from deep sleep stub, or NULL if
* no stub is installed.
*/
esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
/**
* @brief The default esp-idf-provided esp_wake_deep_sleep() stub.
*
* See docs/deep-sleep-stub.rst for details.
*/
void esp_default_wake_deep_sleep(void);
#ifdef __cplusplus
}
#endif

View file

@ -18,7 +18,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "esp_deep_sleep.h"
#include "esp_sleep.h"
#ifdef __cplusplus
extern "C" {

View file

@ -211,7 +211,7 @@ void panicHandler(XtExcFrame *frame)
return;
}
haltOtherCore();
esp_dport_access_int_deinit();
esp_dport_access_int_pause();
panicPutStr("Guru Meditation Error: Core ");
panicPutDec(core_id);
panicPutStr(" panic'ed (");
@ -264,7 +264,7 @@ void panicHandler(XtExcFrame *frame)
void xt_unhandled_exception(XtExcFrame *frame)
{
haltOtherCore();
esp_dport_access_int_deinit();
esp_dport_access_int_pause();
if (!abort_called) {
panicPutStr("Guru Meditation Error of type ");
int exccause = frame->exccause;

View file

@ -1,4 +1,4 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -14,10 +14,13 @@
#include <stddef.h>
#include <sys/lock.h>
#include <sys/param.h>
#include "esp_attr.h"
#include "esp_deep_sleep.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp_clk.h"
#include "esp_newlib.h"
#include "esp_spi_flash.h"
#include "rom/cache.h"
#include "rom/rtc.h"
#include "rom/uart.h"
@ -25,6 +28,7 @@
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/spi_reg.h"
#include "soc/sens_reg.h"
#include "soc/dport_reg.h"
#include "driver/rtc_io.h"
@ -32,11 +36,17 @@
#include "freertos/task.h"
#include "sdkconfig.h"
// If light sleep time is less than that, don't power down flash
#define FLASH_PD_MIN_SLEEP_TIME_US 2000
// Time from VDD_SDIO power up to first flash read in ROM code
#define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700
/**
* Internal structure which holds all requested deep sleep parameters
*/
typedef struct {
esp_deep_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX];
esp_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX];
uint64_t sleep_duration;
uint32_t wakeup_triggers : 11;
uint32_t ext1_trigger_mode : 1;
@ -54,7 +64,7 @@ static deep_sleep_config_t s_config = {
is not thread-safe. */
static _lock_t lock_rtc_memory_crc;
static const char* TAG = "deepsleep";
static const char* TAG = "sleep";
static uint32_t get_power_down_flags();
static void ext0_wakeup_prepare();
@ -106,31 +116,17 @@ void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_s
void esp_deep_sleep(uint64_t time_in_us)
{
esp_deep_sleep_enable_timer_wakeup(time_in_us);
esp_sleep_enable_timer_wakeup(time_in_us);
esp_deep_sleep_start();
}
void IRAM_ATTR esp_deep_sleep_start()
static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
{
// Decide which power domains can be powered down
uint32_t pd_flags = get_power_down_flags();
// Shut down parts of RTC which may have been left enabled by the wireless drivers
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_M, 0, SENS_FORCE_XPD_SAR_S);
// Flush UARTs so that output is not lost due to APB frequency change
uart_tx_wait_idle(0);
uart_tx_wait_idle(1);
uart_tx_wait_idle(2);
if (esp_get_deep_sleep_wake_stub() == NULL) {
esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
}
// Configure pins for external wakeup
if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
ext0_wakeup_prepare();
@ -148,10 +144,25 @@ void IRAM_ATTR esp_deep_sleep_start()
timer_wakeup_prepare();
}
// Enter deep sleep
// Enter sleep
rtc_sleep_config_t config = RTC_SLEEP_CONFIG_DEFAULT(pd_flags);
rtc_sleep_init(config);
rtc_sleep_start(s_config.wakeup_triggers, 0);
return rtc_sleep_start(s_config.wakeup_triggers, 0);
}
void IRAM_ATTR esp_deep_sleep_start()
{
// Configure wake stub
if (esp_get_deep_sleep_wake_stub() == NULL) {
esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep);
}
// Decide which power domains can be powered down
uint32_t pd_flags = get_power_down_flags();
// Enter sleep
esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags);
// Because RTC is in a slower clock domain than the CPU, it
// can take several CPU cycles for the sleep mode to start.
while (1) {
@ -159,9 +170,101 @@ void IRAM_ATTR esp_deep_sleep_start()
}
}
static void rtc_wdt_enable(int time_ms)
{
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, 7);
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, 7);
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_RESET_RTC);
WRITE_PERI_REG(RTC_CNTL_WDTCONFIG1_REG, rtc_clk_slow_freq_get_hz() * time_ms / 1000);
SET_PERI_REG_MASK(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN | RTC_CNTL_WDT_PAUSE_IN_SLP);
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
}
static void rtc_wdt_disable()
{
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
WRITE_PERI_REG(RTC_CNTL_WDTFEED_REG, 1);
REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, RTC_WDT_STG_SEL_OFF);
REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
}
/**
* Helper function which handles entry to and exit from light sleep
* Placed into IRAM as flash may need some time to be powered on.
*/
static esp_err_t IRAM_ATTR esp_light_sleep_inner(uint32_t pd_flags,
rtc_cpu_freq_t cpu_freq, uint32_t flash_enable_time_us)
{
// Enter sleep
esp_err_t err = esp_sleep_start(pd_flags);
// Restore CPU frequency
rtc_clk_cpu_freq_set(cpu_freq);
// If SPI flash was powered down, wait for it to become ready
if (pd_flags & RTC_SLEEP_PD_VDDSDIO) {
// Wait for the flash chip to start up
ets_delay_us(flash_enable_time_us);
}
return err;
}
esp_err_t esp_light_sleep_start()
{
static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&light_sleep_lock);
int other_cpu = xPortGetCoreID() ? 0 : 1;
esp_cpu_stall(other_cpu);
// Other CPU is stalled, need to disable DPORT protection
esp_dport_access_int_pause();
// Decide which power domains can be powered down
uint32_t pd_flags = get_power_down_flags();
// Decide if flash needs to be powered down;
// If it needs to be powered down, adjust sleep time
const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US
+ CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY;
if (s_config.sleep_duration > FLASH_PD_MIN_SLEEP_TIME_US &&
s_config.sleep_duration > flash_enable_time_us) {
pd_flags |= RTC_SLEEP_PD_VDDSDIO;
s_config.sleep_duration -= flash_enable_time_us;
}
// Safety net: enable WDT in case exit from light sleep fails
rtc_wdt_enable(1000);
// Save current CPU frequency, light sleep will switch to XTAL
rtc_cpu_freq_t cpu_freq = rtc_clk_cpu_freq_get();
// Enter sleep, then wait for flash to be ready on wakeup
esp_err_t err = esp_light_sleep_inner(pd_flags, cpu_freq, flash_enable_time_us);
// At this point, if FRC1 is used for timekeeping, time will be lagging behind.
// This will update the microsecond count based on RTC timer.
esp_set_time_from_rtc();
// However, we do not advance RTOS ticks here; doing so would be rather messy,
// as ticks can only be advanced on CPU0.
// If this is needed by the application, automatic light sleep (tickless idle)
// will handle that better.
esp_cpu_unstall(other_cpu);
esp_dport_access_int_resume();
rtc_wdt_disable();
portEXIT_CRITICAL(&light_sleep_lock);
return err;
}
void system_deep_sleep(uint64_t) __attribute__((alias("esp_deep_sleep")));
esp_err_t esp_deep_sleep_enable_ulp_wakeup()
esp_err_t esp_sleep_enable_ulp_wakeup()
{
#ifdef CONFIG_ULP_COPROC_ENABLED
if(s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
@ -175,7 +278,7 @@ esp_err_t esp_deep_sleep_enable_ulp_wakeup()
#endif
}
esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us)
{
s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
s_config.sleep_duration = time_in_us;
@ -190,7 +293,7 @@ static void timer_wakeup_prepare()
rtc_sleep_set_wakeup_time(cur_rtc_count + rtc_count_delta);
}
esp_err_t esp_deep_sleep_enable_touchpad_wakeup()
esp_err_t esp_sleep_enable_touchpad_wakeup()
{
if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) {
ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
@ -200,9 +303,9 @@ esp_err_t esp_deep_sleep_enable_touchpad_wakeup()
return ESP_OK;
}
touch_pad_t esp_deep_sleep_get_touchpad_wakeup_status()
touch_pad_t esp_sleep_get_touchpad_wakeup_status()
{
if (esp_deep_sleep_get_wakeup_cause() != ESP_DEEP_SLEEP_WAKEUP_TOUCHPAD) {
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) {
return TOUCH_PAD_MAX;
}
uint32_t touch_mask = REG_GET_FIELD(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN);
@ -210,7 +313,7 @@ touch_pad_t esp_deep_sleep_get_touchpad_wakeup_status()
return (touch_pad_t) (__builtin_ffs(touch_mask) - 1);
}
esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
{
if (level < 0 || level > 1) {
return ESP_ERR_INVALID_ARG;
@ -249,7 +352,7 @@ static void ext0_wakeup_prepare()
}
}
esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode)
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode)
{
if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) {
return ESP_ERR_INVALID_ARG;
@ -311,9 +414,9 @@ static void ext1_wakeup_prepare()
s_config.ext1_trigger_mode, RTC_CNTL_EXT_WAKEUP1_LV_S);
}
uint64_t esp_deep_sleep_get_ext1_wakeup_status()
uint64_t esp_sleep_get_ext1_wakeup_status()
{
if (esp_deep_sleep_get_wakeup_cause() != ESP_DEEP_SLEEP_WAKEUP_EXT1) {
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_EXT1) {
return 0;
}
uint32_t status = REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS);
@ -332,30 +435,30 @@ uint64_t esp_deep_sleep_get_ext1_wakeup_status()
return gpio_mask;
}
esp_deep_sleep_wakeup_cause_t esp_deep_sleep_get_wakeup_cause()
esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause()
{
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
return ESP_DEEP_SLEEP_WAKEUP_UNDEFINED;
return ESP_SLEEP_WAKEUP_UNDEFINED;
}
uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE);
if (wakeup_cause & RTC_EXT0_TRIG_EN) {
return ESP_DEEP_SLEEP_WAKEUP_EXT0;
return ESP_SLEEP_WAKEUP_EXT0;
} else if (wakeup_cause & RTC_EXT1_TRIG_EN) {
return ESP_DEEP_SLEEP_WAKEUP_EXT1;
return ESP_SLEEP_WAKEUP_EXT1;
} else if (wakeup_cause & RTC_TIMER_TRIG_EN) {
return ESP_DEEP_SLEEP_WAKEUP_TIMER;
return ESP_SLEEP_WAKEUP_TIMER;
} else if (wakeup_cause & RTC_TOUCH_TRIG_EN) {
return ESP_DEEP_SLEEP_WAKEUP_TOUCHPAD;
return ESP_SLEEP_WAKEUP_TOUCHPAD;
} else if (wakeup_cause & RTC_ULP_TRIG_EN) {
return ESP_DEEP_SLEEP_WAKEUP_ULP;
return ESP_SLEEP_WAKEUP_ULP;
} else {
return ESP_DEEP_SLEEP_WAKEUP_UNDEFINED;
return ESP_SLEEP_WAKEUP_UNDEFINED;
}
}
esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain,
esp_deep_sleep_pd_option_t option)
esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain,
esp_sleep_pd_option_t option)
{
if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) {
return ESP_ERR_INVALID_ARG;
@ -410,7 +513,7 @@ static uint32_t get_power_down_flags()
option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]);
// Prepare flags based on the selected options
uint32_t pd_flags = RTC_SLEEP_PD_DIG;
uint32_t pd_flags = 0;
if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) {
pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM;
}

View file

@ -270,7 +270,7 @@ void IRAM_ATTR esp_restart_noos()
esp_cpu_stall(other_core_id);
// other core is now stalled, can access DPORT registers directly
esp_dport_access_int_deinit();
esp_dport_access_int_pause();
// We need to disable TG0/TG1 watchdogs
// First enable RTC watchdog for 1 second

View file

@ -1,5 +1,6 @@
#include "unity.h"
#include "esp_deep_sleep.h"
#include <sys/time.h>
#include "esp_sleep.h"
#include "driver/rtc_io.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@ -25,15 +26,27 @@ static void do_deep_sleep_from_app_cpu()
}
}
TEST_CASE("wake up using timer", "[deepsleep][ignore]")
TEST_CASE("wake up from deep sleep using timer", "[deepsleep][ignore]")
{
esp_deep_sleep_enable_timer_wakeup(2000000);
esp_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();
}
TEST_CASE("wake up from light sleep using timer", "[deepsleep]")
{
esp_sleep_enable_timer_wakeup(2000000);
struct timeval tv_start, tv_stop;
gettimeofday(&tv_start, NULL);
esp_light_sleep_start();
gettimeofday(&tv_stop, NULL);
float dt = (tv_stop.tv_sec - tv_start.tv_sec) * 1e3f +
(tv_stop.tv_usec - tv_start.tv_usec) * 1e-3f;
TEST_ASSERT_INT32_WITHIN(500, 2000, (int) dt);
}
TEST_CASE("enter deep sleep on APP CPU and wake up using timer", "[deepsleep][ignore]")
{
esp_deep_sleep_enable_timer_wakeup(2000000);
esp_sleep_enable_timer_wakeup(2000000);
do_deep_sleep_from_app_cpu();
}
@ -43,7 +56,7 @@ TEST_CASE("wake up using ext0 (13 high)", "[deepsleep][ignore]")
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_deep_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1));
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1));
esp_deep_sleep_start();
}
@ -52,7 +65,7 @@ TEST_CASE("wake up using ext0 (13 low)", "[deepsleep][ignore]")
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_deep_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0));
ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0));
esp_deep_sleep_start();
}
@ -60,7 +73,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 high)", "[deepsleep][ig
{
// This test needs external pulldown
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
esp_deep_sleep_start();
}
@ -68,7 +81,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is off (13 low)", "[deepsleep][ign
{
// This test needs external pullup
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
esp_deep_sleep_start();
}
@ -77,8 +90,8 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 high)", "[deepsleep][ign
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_dis(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pulldown_en(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ANY_HIGH));
esp_deep_sleep_start();
}
@ -87,7 +100,7 @@ TEST_CASE("wake up using ext1 when RTC_PERIPH is on (13 low)", "[deepsleep][igno
ESP_ERROR_CHECK(rtc_gpio_init(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pullup_en(GPIO_NUM_13));
ESP_ERROR_CHECK(gpio_pulldown_dis(GPIO_NUM_13));
ESP_ERROR_CHECK(esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
ESP_ERROR_CHECK(esp_deep_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(BIT(GPIO_NUM_13), ESP_EXT1_WAKEUP_ALL_LOW));
esp_deep_sleep_start();
}

View file

@ -34,10 +34,8 @@ void esp_reent_init(struct _reent* r);
void esp_setup_syscall_table();
/**
* Initialize hardware timer used as time source for newlib time functions.
*
* Called from the startup code, not intended to be called from application.
* Update current microsecond time from RTC
*/
void esp_setup_time_syscalls();
void esp_set_time_from_rtc();
#endif //__ESP_NEWLIB_H__

View file

@ -137,14 +137,12 @@ uint32_t esp_clk_slowclk_cal_get()
return REG_READ(RTC_SLOW_CLK_CAL_REG);
}
void esp_setup_time_syscalls()
void esp_set_time_from_rtc()
{
#if defined( WITH_FRC1 )
#if defined( WITH_RTC )
#if defined( WITH_FRC1 ) && defined( WITH_RTC )
// initialize time from RTC clock
s_microseconds_offset = get_rtc_time_us() - esp_timer_get_time();
#endif //WITH_RTC
#endif // WITH_FRC1
#endif // WITH_FRC1 && WITH_RTC
}
clock_t IRAM_ATTR _times_r(struct _reent *r, struct tms *ptms)

View file

@ -393,6 +393,7 @@ typedef struct {
uint32_t rtc_dbias_wak : 3; //!< set bias for RTC domain, in active mode
uint32_t rtc_dbias_slp : 3; //!< set bias for RTC domain, in sleep mode
uint32_t lslp_meminf_pd : 1; //!< remove all peripheral force power up flags
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
} rtc_sleep_config_t;
/**
@ -419,7 +420,8 @@ typedef struct {
.dig_dbias_slp = RTC_CNTL_DBIAS_0V90, \
.rtc_dbias_wak = RTC_CNTL_DBIAS_0V90, \
.rtc_dbias_slp = RTC_CNTL_DBIAS_0V90, \
.lslp_meminf_pd = 1 \
.lslp_meminf_pd = 1, \
.vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \
};
#define RTC_SLEEP_PD_DIG BIT(0) //!< Deep sleep (power down digital domain)
@ -427,6 +429,7 @@ typedef struct {
#define RTC_SLEEP_PD_RTC_SLOW_MEM BIT(2) //!< Power down RTC SLOW memory
#define RTC_SLEEP_PD_RTC_FAST_MEM BIT(3) //!< Power down RTC FAST memory
#define RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU BIT(4) //!< RTC FAST and SLOW memories are automatically powered up and down along with the CPU
#define RTC_SLEEP_PD_VDDSDIO BIT(5) //!< Power down VDDSDIO regulator
/**
* @brief Prepare the chip to enter sleep mode

View file

@ -188,11 +188,22 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG,
RTC_CNTL_DG_WRAP_FORCE_PU | RTC_CNTL_DG_WRAP_FORCE_PD);
CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_FORCE_NOSLEEP);
// Shut down parts of RTC which may have been left enabled by the wireless drivers
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_FORCE_NOSLEEP);
}
if (cfg.vddsdio_pd_en) {
SET_PERI_REG_MASK(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN);
} else {
CLEAR_PERI_REG_MASK(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN);
}
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_SLP, cfg.rtc_dbias_slp);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, cfg.rtc_dbias_wak);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, cfg.dig_dbias_wak);

View file

@ -22,7 +22,7 @@
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_deep_sleep.h"
#include "esp_sleep.h"
#include "esp32/ulp.h"
@ -120,7 +120,7 @@ TEST_CASE("ulp wakeup test", "[ulp][ignore]")
size_t size = sizeof(program)/sizeof(ulp_insn_t);
ulp_process_macros_and_load(0, program, &size);
ulp_run(0);
esp_deep_sleep_enable_ulp_wakeup();
esp_sleep_enable_ulp_wakeup();
esp_deep_sleep_start();
}
@ -263,7 +263,7 @@ TEST_CASE("ulp controls RTC_IO", "[ulp][ignore]")
size_t size = sizeof(program)/sizeof(ulp_insn_t);
ulp_process_macros_and_load(0, program, &size);
ulp_run(0);
esp_deep_sleep_enable_ulp_wakeup();
esp_sleep_enable_ulp_wakeup();
esp_deep_sleep_start();
}
@ -277,8 +277,8 @@ TEST_CASE("ulp power consumption in deep sleep", "[ulp][ignore]")
ulp_run(0);
esp_deep_sleep_enable_ulp_wakeup();
esp_deep_sleep_enable_timer_wakeup(10 * 1000000);
esp_sleep_enable_ulp_wakeup();
esp_sleep_enable_timer_wakeup(10 * 1000000);
esp_deep_sleep_start();
}
@ -377,8 +377,8 @@ TEST_CASE("ulp can use TSENS in deep sleep", "[ulp][ignore]")
assert(offset >= size);
TEST_ESP_OK(ulp_run(0));
esp_deep_sleep_enable_timer_wakeup(4000000);
esp_deep_sleep_enable_ulp_wakeup();
esp_sleep_enable_timer_wakeup(4000000);
esp_sleep_enable_ulp_wakeup();
esp_deep_sleep_start();
}
@ -454,7 +454,7 @@ TEST_CASE("can use ADC in deep sleep", "[ulp][ignore]")
assert(offset >= size);
TEST_ESP_OK(ulp_run(0));
esp_deep_sleep_enable_timer_wakeup(4000000);
esp_sleep_enable_timer_wakeup(4000000);
esp_deep_sleep_start();
}

View file

@ -118,9 +118,9 @@ INPUT = \
../components/esp32/include/esp_task_wdt.h \
## Over The Air Updates (OTA)
../components/app_update/include/esp_ota_ops.h \
## Deep Sleep
## Sleep
## NOTE: for line below header_file.inc is not used
../components/esp32/include/esp_deep_sleep.h \
../components/esp32/include/esp_sleep.h \
## Logging
../components/log/include/esp_log.h \
## Base MAC address

View file

@ -1,123 +0,0 @@
Deep Sleep
==========
Overview
--------
ESP32 is capable of deep sleep power saving mode. In this mode CPUs, most of the RAM, and all the digital peripherals which are clocked from APB_CLK are powered off. The only parts of the chip which can still be powered on are: RTC controller, RTC peripherals (including ULP coprocessor), and RTC memories (slow and fast).
Wakeup from deep sleep mode can be done using several sources. These sources can be combined, in this case the chip will wake up when any one of the sources is triggered. Wakeup sources can be enabled using ``esp_deep_sleep_enable_X_wakeup`` APIs. Next section describes these APIs in detail. Wakeup sources can be configured at any moment before entering deep sleep mode.
Additionally, the application can force specific powerdown modes for the RTC peripherals and RTC memories using ``esp_deep_sleep_pd_config`` API.
Once wakeup sources are configured, application can start deep sleep using ``esp_deep_sleep_start`` API. At this point the hardware will be configured according to the requested wakeup sources, and RTC controller will power down the CPUs and digital peripherals.
Wakeup sources
--------------
Timer
^^^^^
RTC controller has a built in timer which can be used to wake up the chip after a predefined amount of time. Time is specified at microsecond precision, but the actual resolution depends on the clock source selected for RTC SLOW_CLK. See chapter "Reset and Clock" of the ESP32 Technical Reference Manual for details about RTC clock options.
This wakeup mode doesn't require RTC peripherals or RTC memories to be powered on during deep sleep.
The following function can be used to enable deep sleep wakeup using a timer.
.. doxygenfunction:: esp_deep_sleep_enable_timer_wakeup
Touch pad
^^^^^^^^^
RTC IO module contains logic to trigger wakeup when a touch sensor interrupt occurs. You need to configure the touch pad interrupt before the chip starts deep sleep.
Revisions 0 and 1 of the ESP32 only support this wakeup mode when RTC peripherals are not forced to be powered on (i.e. ESP_PD_DOMAIN_RTC_PERIPH should be set to ESP_PD_OPTION_AUTO).
.. doxygenfunction:: esp_deep_sleep_enable_touchpad_wakeup
External wakeup (ext0)
^^^^^^^^^^^^^^^^^^^^^^
RTC IO module contains logic to trigger wakeup when one of RTC GPIOs is set to a predefined logic level. RTC IO is part of RTC peripherals power domain, so RTC peripherals will be kept powered on during deep sleep if this wakeup source is requested.
Because RTC IO module is enabled in this mode, internal pullup or pulldown resistors can also be used. They need to be configured by the application using ``rtc_gpio_pullup_en`` and ``rtc_gpio_pulldown_en`` functions, before calling ``esp_deep_sleep_start``.
In revisions 0 and 1 of the ESP32, this wakeup source is incompatible with ULP and touch wakeup sources.
.. warning:: After wake up from deep sleep, IO pad used for wakeup will be configured as RTC IO. Before using this pad as digital GPIO, reconfigure it using ``rtc_gpio_deinit(gpio_num)`` function.
.. doxygenfunction:: esp_deep_sleep_enable_ext0_wakeup
External wakeup (ext1)
^^^^^^^^^^^^^^^^^^^^^^
RTC controller contains logic to trigger wakeup using multiple RTC GPIOs. One of the two logic functions can be used to trigger wakeup:
- wake up if any of the selected pins is high (``ESP_EXT1_WAKEUP_ANY_HIGH``)
- wake up if all the selected pins are low (``ESP_EXT1_WAKEUP_ALL_LOW``)
This wakeup source is implemented by the RTC controller. As such, RTC peripherals and RTC memories can be powered off in this mode. However, if RTC peripherals are powered down, internal pullup and pulldown resistors will be disabled. To use internal pullup or pulldown resistors, request RTC peripherals power domain to be kept on during deep sleep, and configure pullup/pulldown resistors using ``rtc_gpio_`` functions, before entering deep sleep::
esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
gpio_pullup_dis(gpio_num);
gpio_pulldown_en(gpio_num);
.. warning:: After wake up from deep sleep, IO pad(s) used for wakeup will be configured as RTC IO. Before using these pads as digital GPIOs, reconfigure them using ``rtc_gpio_deinit(gpio_num)`` function.
The following function can be used to enable this wakeup mode:
.. doxygenfunction:: esp_deep_sleep_enable_ext1_wakeup
.. doxygenenum:: esp_ext1_wakeup_mode_t
ULP coprocessor wakeup
^^^^^^^^^^^^^^^^^^^^^^
ULP coprocessor can run while the chip is in deep sleep, and may be used to poll sensors, monitor ADC or touch sensor values, and wake up the chip when a specific event is detected. ULP coprocessor is part of RTC peripherals power domain, and it runs the program stored in RTC slow memeory. RTC slow memory will be powered on during deep sleep if this wakeup mode is requested. RTC peripherals will be automatically powered on before ULP coprocessor starts running the program; once the program stops running, RTC peripherals are automatically powered down again.
Revisions 0 and 1 of the ESP32 only support this wakeup mode when RTC peripherals are not forced to be powered on (i.e. ESP_PD_DOMAIN_RTC_PERIPH should be set to ESP_PD_OPTION_AUTO).
The following function can be used to enable this wakeup mode:
.. doxygenfunction:: esp_deep_sleep_enable_ulp_wakeup
Power-down of RTC peripherals and memories
------------------------------------------
By default, ``esp_deep_sleep_start`` function will power down all RTC power domains which are not needed by the enabled wakeup sources. To override this behaviour, the following function is provided:
Note: in revision 0 of the ESP32, RTC fast memory will always be kept enabled in deep sleep, so that the deep sleep stub can run after reset. This can be overriden, if the application doesn't need clean reset behaviour after deep sleep.
If some variables in the program are placed into RTC slow memory (for example, using ``RTC_DATA_ATTR`` attribute), RTC slow memory will be kept powered on by default. This can be overriden using ``esp_deep_sleep_pd_config`` function, if desired.
.. doxygenfunction:: esp_deep_sleep_pd_config
.. doxygenenum:: esp_deep_sleep_pd_domain_t
.. doxygenenum:: esp_deep_sleep_pd_option_t
Entering deep sleep
-------------------
The following function can be used to enter deep sleep once wakeup sources are configured. It is also possible to go into deep sleep with no wakeup sources configured, in this case the chip will be in deep sleep mode indefinetly, until external reset is applied.
.. doxygenfunction:: esp_deep_sleep_start
Checking deep sleep wakeup cause
--------------------------------
The following function can be used to check which wakeup source has triggered wakeup from deep sleep mode. For touch pad and ext1 wakeup sources, it is possible to identify pin or touch pad which has caused wakeup.
.. doxygenfunction:: esp_deep_sleep_get_wakeup_cause
.. doxygenenum:: esp_deep_sleep_wakeup_cause_t
.. doxygenfunction:: esp_deep_sleep_get_touchpad_wakeup_status
.. doxygenfunction:: esp_deep_sleep_get_ext1_wakeup_status
Application Example
-------------------
Implementation of basic functionality of deep sleep is shown in :example:`protocols/sntp` example, where ESP module is periodically waken up to retrive time from NTP server.
More extensive example in :example:`system/deep_sleep` illustrates usage of various deep sleep wakeup triggers and ULP coprocessor programming.

View file

@ -8,7 +8,7 @@ System API
Interrupt Allocation <intr_alloc>
Watchdogs <wdts>
Over The Air Updates (OTA) <ota>
Deep Sleep <deep_sleep>
Sleep Modes <sleep_modes>
Logging <log>
Base MAC address <base_mac_address>
Application Level Tracing <app_trace>

View file

@ -0,0 +1,141 @@
Sleep Modes
===========
Overview
--------
ESP32 is capable of light sleep and deep sleep power saving modes.
In light sleep mode, digital peripherals, most of the RAM, and CPUs are clock-gated, and supply voltage is reduced. Upon exit from light sleep, peripherals and CPUs resume operation, their internal state is preserved.
In deep sleep mode, CPUs, most of the RAM, and all the digital peripherals which are clocked from APB_CLK are powered off. The only parts of the chip which can still be powered on are: RTC controller, RTC peripherals (including ULP coprocessor), and RTC memories (slow and fast).
Wakeup from deep and light sleep modes can be done using several sources. These sources can be combined, in this case the chip will wake up when any one of the sources is triggered. Wakeup sources can be enabled using ``esp_sleep_enable_X_wakeup`` APIs. Next section describes these APIs in detail. Wakeup sources can be configured at any moment before entering light or deep sleep mode.
Additionally, the application can force specific powerdown modes for the RTC peripherals and RTC memories using ``esp_sleep_pd_config`` API.
Once wakeup sources are configured, application can enter sleep mode using ``esp_light_sleep_start`` or ``esp_deep_sleep_start`` APIs. At this point the hardware will be configured according to the requested wakeup sources, and RTC controller will either power down or power off the CPUs and digital peripherals.
WiFi/BT and sleep modes
-----------------------
In deep sleep mode, wireless peripherals are powered down. Before entering sleep mode, applications must disable WiFi and BT using appropriate calls ( ``esp_bluedroid_disable``, ``esp_bt_controller_disable``, ``esp_wifi_stop``).
WiFi can coexist with light sleep mode, allowing the chip to go into light sleep mode when there is no network activity, and waking up the chip from light sleep mode when required. However **APIs described in this section can not be used for that purpose**. ``esp_light_sleep_start`` forces the chip to enter light sleep mode, regardless of whether WiFi is active or not. Automatic entry into light sleep mode, coordinated with WiFi driver, will be supported using a separate set of APIs.
Wakeup sources
--------------
Timer
^^^^^
RTC controller has a built in timer which can be used to wake up the chip after a predefined amount of time. Time is specified at microsecond precision, but the actual resolution depends on the clock source selected for RTC SLOW_CLK. See chapter "Reset and Clock" of the ESP32 Technical Reference Manual for details about RTC clock options.
This wakeup mode doesn't require RTC peripherals or RTC memories to be powered on during sleep.
The following function can be used to enable deep sleep wakeup using a timer.
.. doxygenfunction:: esp_sleep_enable_timer_wakeup
Touch pad
^^^^^^^^^
RTC IO module contains logic to trigger wakeup when a touch sensor interrupt occurs. You need to configure the touch pad interrupt before the chip starts deep sleep.
Revisions 0 and 1 of the ESP32 only support this wakeup mode when RTC peripherals are not forced to be powered on (i.e. ESP_PD_DOMAIN_RTC_PERIPH should be set to ESP_PD_OPTION_AUTO).
.. doxygenfunction:: esp_sleep_enable_touchpad_wakeup
External wakeup (ext0)
^^^^^^^^^^^^^^^^^^^^^^
RTC IO module contains logic to trigger wakeup when one of RTC GPIOs is set to a predefined logic level. RTC IO is part of RTC peripherals power domain, so RTC peripherals will be kept powered on during deep sleep if this wakeup source is requested.
Because RTC IO module is enabled in this mode, internal pullup or pulldown resistors can also be used. They need to be configured by the application using ``rtc_gpio_pullup_en`` and ``rtc_gpio_pulldown_en`` functions, before calling ``esp_sleep_start``.
In revisions 0 and 1 of the ESP32, this wakeup source is incompatible with ULP and touch wakeup sources.
.. warning:: After wake up from sleep, IO pad used for wakeup will be configured as RTC IO. Before using this pad as digital GPIO, reconfigure it using ``rtc_gpio_deinit(gpio_num)`` function.
.. doxygenfunction:: esp_sleep_enable_ext0_wakeup
External wakeup (ext1)
^^^^^^^^^^^^^^^^^^^^^^
RTC controller contains logic to trigger wakeup using multiple RTC GPIOs. One of the two logic functions can be used to trigger wakeup:
- wake up if any of the selected pins is high (``ESP_EXT1_WAKEUP_ANY_HIGH``)
- wake up if all the selected pins are low (``ESP_EXT1_WAKEUP_ALL_LOW``)
This wakeup source is implemented by the RTC controller. As such, RTC peripherals and RTC memories can be powered down in this mode. However, if RTC peripherals are powered down, internal pullup and pulldown resistors will be disabled. To use internal pullup or pulldown resistors, request RTC peripherals power domain to be kept on during sleep, and configure pullup/pulldown resistors using ``rtc_gpio_`` functions, before entering sleep::
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
gpio_pullup_dis(gpio_num);
gpio_pulldown_en(gpio_num);
.. warning:: After wake up from sleep, IO pad(s) used for wakeup will be configured as RTC IO. Before using these pads as digital GPIOs, reconfigure them using ``rtc_gpio_deinit(gpio_num)`` function.
The following function can be used to enable this wakeup mode:
.. doxygenfunction:: esp_sleep_enable_ext1_wakeup
.. doxygenenum:: esp_sleep_ext1_wakeup_mode_t
ULP coprocessor wakeup
^^^^^^^^^^^^^^^^^^^^^^
ULP coprocessor can run while the chip is in sleep mode, and may be used to poll sensors, monitor ADC or touch sensor values, and wake up the chip when a specific event is detected. ULP coprocessor is part of RTC peripherals power domain, and it runs the program stored in RTC slow memeory. RTC slow memory will be powered on during sleep if this wakeup mode is requested. RTC peripherals will be automatically powered on before ULP coprocessor starts running the program; once the program stops running, RTC peripherals are automatically powered down again.
Revisions 0 and 1 of the ESP32 only support this wakeup mode when RTC peripherals are not forced to be powered on (i.e. ESP_PD_DOMAIN_RTC_PERIPH should be set to ESP_PD_OPTION_AUTO).
The following function can be used to enable this wakeup mode:
.. doxygenfunction:: esp_sleep_enable_ulp_wakeup
Power-down of RTC peripherals and memories
------------------------------------------
By default, ``esp_deep_sleep_start`` and ``esp_light_sleep_start`` functions will power down all RTC power domains which are not needed by the enabled wakeup sources. To override this behaviour, ``esp_sleep_pd_config`` function is provided.
Note: in revision 0 of the ESP32, RTC fast memory will always be kept enabled in deep sleep, so that the deep sleep stub can run after reset. This can be overriden, if the application doesn't need clean reset behaviour after deep sleep.
If some variables in the program are placed into RTC slow memory (for example, using ``RTC_DATA_ATTR`` attribute), RTC slow memory will be kept powered on by default. This can be overriden using ``esp_sleep_pd_config`` function, if desired.
.. doxygenfunction:: esp_sleep_pd_config
.. doxygenenum:: esp_sleep_pd_domain_t
.. doxygenenum:: esp_sleep_pd_option_t
Entering light sleep
--------------------
The following function can be used to enter light sleep once wakeup sources are configured. It is also possible to go into light sleep with no wakeup sources configured, in this case the chip will be in light sleep mode indefinetly, until external reset is applied.
.. doxygenfunction:: esp_light_sleep_start
Entering deep sleep
-------------------
The following function can be used to enter deep sleep once wakeup sources are configured. It is also possible to go into deep sleep with no wakeup sources configured, in this case the chip will be in deep sleep mode indefinetly, until external reset is applied.
.. doxygenfunction:: esp_deep_sleep_start
Checking sleep wakeup cause
---------------------------
The following function can be used to check which wakeup source has triggered wakeup from sleep mode. For touch pad and ext1 wakeup sources, it is possible to identify pin or touch pad which has caused wakeup.
.. doxygenfunction:: esp_sleep_get_wakeup_cause
.. doxygenenum:: esp_sleep_wakeup_cause_t
.. doxygenfunction:: esp_sleep_get_touchpad_wakeup_status
.. doxygenfunction:: esp_sleep_get_ext1_wakeup_status
Application Example
-------------------
Implementation of basic functionality of deep sleep is shown in :example:`protocols/sntp` example, where ESP module is periodically waken up to retrive time from NTP server.
More extensive example in :example:`system/deep_sleep` illustrates usage of various deep sleep wakeup triggers and ULP coprocessor programming.

View file

@ -17,7 +17,7 @@
#include "esp_event_loop.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "esp_deep_sleep.h"
#include "esp_sleep.h"
#include "nvs_flash.h"
#include "lwip/err.h"

View file

@ -13,6 +13,7 @@
#include "esp_log.h"
#include "esp_console.h"
#include "esp_system.h"
#include "esp_sleep.h"
#include "driver/rtc_io.h"
#include "argtable3/argtable3.h"
#include "cmd_decl.h"
@ -91,7 +92,7 @@ static int deep_sleep(int argc, char** argv)
if (deep_sleep_args.wakeup_time->count) {
uint64_t timeout = 1000ULL * deep_sleep_args.wakeup_time->ival[0];
ESP_LOGI(__func__, "Enabling timer wakeup, timeout=%lluus", timeout);
ESP_ERROR_CHECK( esp_deep_sleep_enable_timer_wakeup(timeout) );
ESP_ERROR_CHECK( esp_sleep_enable_timer_wakeup(timeout) );
}
if (deep_sleep_args.wakeup_gpio_num->count) {
int io_num = deep_sleep_args.wakeup_gpio_num->ival[0];
@ -110,7 +111,7 @@ static int deep_sleep(int argc, char** argv)
ESP_LOGI(__func__, "Enabling wakeup on GPIO%d, wakeup on %s level",
io_num, level ? "HIGH" : "LOW");
ESP_ERROR_CHECK( esp_deep_sleep_enable_ext1_wakeup(1ULL << io_num, level) );
ESP_ERROR_CHECK( esp_sleep_enable_ext1_wakeup(1ULL << io_num, level) );
}
esp_deep_sleep_start();
}

View file

@ -14,7 +14,7 @@
#include <sys/time.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_deep_sleep.h"
#include "esp_sleep.h"
#include "esp_log.h"
#include "esp32/ulp.h"
#include "driver/touch_pad.h"
@ -82,9 +82,9 @@ void app_main()
gettimeofday(&now, NULL);
int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000;
switch (esp_deep_sleep_get_wakeup_cause()) {
case ESP_DEEP_SLEEP_WAKEUP_EXT1: {
uint64_t wakeup_pin_mask = esp_deep_sleep_get_ext1_wakeup_status();
switch (esp_sleep_get_wakeup_cause()) {
case ESP_SLEEP_WAKEUP_EXT1: {
uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status();
if (wakeup_pin_mask != 0) {
int pin = __builtin_ffsll(wakeup_pin_mask) - 1;
printf("Wake up from GPIO %d\n", pin);
@ -93,18 +93,18 @@ void app_main()
}
break;
}
case ESP_DEEP_SLEEP_WAKEUP_TIMER: {
case ESP_SLEEP_WAKEUP_TIMER: {
printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms);
break;
}
#ifdef CONFIG_ENABLE_TOUCH_WAKEUP
case ESP_DEEP_SLEEP_WAKEUP_TOUCHPAD: {
printf("Wake up from touch on pad %d\n", esp_deep_sleep_get_touchpad_wakeup_status());
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
printf("Wake up from touch on pad %d\n", esp_sleep_get_touchpad_wakeup_status());
break;
}
#endif // CONFIG_ENABLE_TOUCH_WAKEUP
#ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP
case ESP_DEEP_SLEEP_WAKEUP_ULP: {
case ESP_SLEEP_WAKEUP_ULP: {
printf("Wake up from ULP\n");
int16_t diff_high = (int16_t) ulp_data_read(3);
int16_t diff_low = (int16_t) ulp_data_read(4);
@ -118,13 +118,13 @@ void app_main()
break;
}
#endif // CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP
case ESP_DEEP_SLEEP_WAKEUP_UNDEFINED:
case ESP_SLEEP_WAKEUP_UNDEFINED:
default:
printf("Not a deep sleep reset\n");
}
#ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP
if (esp_deep_sleep_get_wakeup_cause() != ESP_DEEP_SLEEP_WAKEUP_UNDEFINED) {
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED) {
printf("ULP did %d temperature measurements in %d ms\n", ulp_data_read(1), sleep_time_ms);
printf("Initial T=%d, latest T=%d\n", ulp_data_read(0), ulp_data_read(2));
}
@ -134,7 +134,7 @@ void app_main()
const int wakeup_time_sec = 20;
printf("Enabling timer wakeup, %ds\n", wakeup_time_sec);
esp_deep_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000);
esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000);
const int ext_wakeup_pin_1 = 25;
const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1;
@ -142,19 +142,19 @@ void app_main()
const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2;
printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2);
esp_deep_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH);
esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH);
#ifdef CONFIG_ENABLE_TOUCH_WAKEUP
touch_pad_init();
calibrate_touch_pad(TOUCH_PAD_NUM8);
calibrate_touch_pad(TOUCH_PAD_NUM9);
printf("Enabling touch pad wakeup\n");
esp_deep_sleep_enable_touchpad_wakeup();
esp_sleep_enable_touchpad_wakeup();
#endif // CONFIG_ENABLE_TOUCH_WAKEUP
#ifdef CONFIG_ENABLE_ULP_TEMPERATURE_WAKEUP
printf("Enabling ULP wakeup\n");
esp_deep_sleep_enable_ulp_wakeup();
esp_sleep_enable_ulp_wakeup();
#endif
printf("Entering deep sleep\n");

View file

@ -8,7 +8,7 @@
*/
#include <stdio.h>
#include "esp_deep_sleep.h"
#include "esp_sleep.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "soc/rtc_cntl_reg.h"
@ -26,8 +26,8 @@ static void update_pulse_count();
void app_main()
{
esp_deep_sleep_wakeup_cause_t cause = esp_deep_sleep_get_wakeup_cause();
if (cause != ESP_DEEP_SLEEP_WAKEUP_ULP) {
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
if (cause != ESP_SLEEP_WAKEUP_ULP) {
printf("Not ULP wakeup, initializing ULP\n");
init_ulp_program();
} else {
@ -36,7 +36,7 @@ void app_main()
}
printf("Entering deep sleep\n\n");
ESP_ERROR_CHECK( esp_deep_sleep_enable_ulp_wakeup() );
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
esp_deep_sleep_start();
}

View file

@ -9,7 +9,7 @@
#include <stdio.h>
#include <string.h>
#include "esp_deep_sleep.h"
#include "esp_sleep.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "soc/rtc_cntl_reg.h"
@ -36,8 +36,8 @@ static void start_ulp_program();
void app_main()
{
esp_deep_sleep_wakeup_cause_t cause = esp_deep_sleep_get_wakeup_cause();
if (cause != ESP_DEEP_SLEEP_WAKEUP_ULP) {
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
if (cause != ESP_SLEEP_WAKEUP_ULP) {
printf("Not ULP wakeup\n");
init_ulp_program();
} else {
@ -50,7 +50,7 @@ void app_main()
}
printf("Entering deep sleep\n\n");
start_ulp_program();
ESP_ERROR_CHECK( esp_deep_sleep_enable_ulp_wakeup() );
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
esp_deep_sleep_start();
}

View file

@ -168,7 +168,7 @@ CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set
CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024
CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=0
CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000
# CONFIG_ESP32_XTAL_FREQ_40 is not set
# CONFIG_ESP32_XTAL_FREQ_26 is not set
CONFIG_ESP32_XTAL_FREQ_AUTO=y