mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 04:25:32 +00:00
sleep: add light sleep, factor out APIs common for deep/light sleep
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
301
components/esp32/include/esp_sleep.h
Normal file
301
components/esp32/include/esp_sleep.h
Normal 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
|
@@ -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" {
|
||||
|
@@ -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_setup_time_syscalls();
|
||||
|
||||
// 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;
|
||||
}
|
@@ -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();
|
||||
}
|
Reference in New Issue
Block a user