From 14902da344b70a2a8f14bde9434fbe3e38b2a0d3 Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Wed, 15 Apr 2020 16:46:10 +0800 Subject: [PATCH 1/7] esp32: move disabling rom log to esp_rom --- components/esp32/sleep_modes.c | 8 ++------ components/esp_rom/CMakeLists.txt | 5 +++-- components/esp_rom/component.mk | 2 +- components/esp_rom/include/esp32s2/rom/rtc.h | 1 - components/esp_rom/include/esp_rom_sys.h | 5 +++++ components/esp_rom/patches/esp_rom_sys.c | 20 ++++++++++++++++++++ 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/components/esp32/sleep_modes.c b/components/esp32/sleep_modes.c index 090c9a7b83..574ccc079c 100644 --- a/components/esp32/sleep_modes.c +++ b/components/esp32/sleep_modes.c @@ -714,10 +714,6 @@ static uint32_t get_power_down_flags(void) void esp_deep_sleep_disable_rom_logging(void) { - /* To disable logging in the ROM, only the least significant bit of the register is used, - * but since this register is also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG), - * you need to write to this register in the same format. - * Namely, the upper 16 bits and lower should be the same. - */ - REG_SET_BIT(RTC_CNTL_STORE4_REG, RTC_DISABLE_ROM_LOG); + esp_rom_disable_logging(); } + diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 43c2578bb4..930dcd53d2 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -1,6 +1,8 @@ idf_build_get_property(target IDF_TARGET) -idf_component_register(SRCS "patches/esp_rom_crc.c" "patches/esp_rom_sys.c" "patches/esp_rom_uart.c" +idf_component_register(SRCS "patches/esp_rom_crc.c" + "patches/esp_rom_sys.c" + "patches/esp_rom_uart.c" INCLUDE_DIRS include PRIV_INCLUDE_DIRS "${target}" PRIV_REQUIRES soc) @@ -82,7 +84,6 @@ else() # Regular app build endif() target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}") - endif() if(target STREQUAL "esp32s2") diff --git a/components/esp_rom/component.mk b/components/esp_rom/component.mk index e4bebe71a6..f83357ffec 100644 --- a/components/esp_rom/component.mk +++ b/components/esp_rom/component.mk @@ -1,5 +1,5 @@ COMPONENT_ADD_INCLUDEDIRS := include -COMPONENT_SRCDIRS := patches +COMPONENT_SRCDIRS := patches . COMPONENT_PRIV_INCLUDEDIRS := esp32 #Linker scripts used to link the final application. diff --git a/components/esp_rom/include/esp32s2/rom/rtc.h b/components/esp_rom/include/esp32s2/rom/rtc.h index 593e885457..c91916fa35 100644 --- a/components/esp_rom/include/esp32s2/rom/rtc.h +++ b/components/esp_rom/include/esp32s2/rom/rtc.h @@ -71,7 +71,6 @@ extern "C" { #define RTC_RESET_CAUSE_REG RTC_CNTL_STORE6_REG #define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG - typedef enum { AWAKE = 0, // #include "esp_attr.h" +#include "sdkconfig.h" + +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/rom/rtc.h" +#endif + IRAM_ATTR void esp_rom_install_channel_putc(int channel, void (*putc)(char c)) { extern void ets_install_putc1(void (*p)(char c)); @@ -30,3 +38,15 @@ IRAM_ATTR void esp_rom_install_channel_putc(int channel, void (*putc)(char c)) break; } } + +void esp_rom_disable_logging(void) +{ +#if CONFIG_IDF_TARGET_ESP32 // [refactor-todo]: ESP32S2 seem to also reference disabling logging in its ROM code + /* To disable logging in the ROM, only the least significant bit of the register is used, + * but since this register is also used to store the frequency of the main crystal (RTC_XTAL_FREQ_REG), + * you need to write to this register in the same format. + * Namely, the upper 16 bits and lower should be the same. + */ + REG_SET_BIT(RTC_CNTL_STORE4_REG, RTC_DISABLE_ROM_LOG); +#endif +} From b30522f70192a28630d876bc58bf98f9f5177f74 Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Thu, 23 Apr 2020 12:39:07 +0800 Subject: [PATCH 2/7] esp32, esp32s2: move sleep modes code to esp_system --- components/esp32/CMakeLists.txt | 4 +- components/esp32s2/CMakeLists.txt | 4 +- components/esp32s2/include/esp_sleep.h | 359 --------- components/esp32s2/sleep_modes.c | 720 ------------------ components/esp_system/CMakeLists.txt | 2 +- .../{esp32 => esp_system}/include/esp_sleep.h | 29 +- .../{esp32 => esp_system}/sleep_modes.c | 187 ++++- docs/Doxyfile | 2 +- .../main/light_sleep_example_main.c | 1 + 9 files changed, 187 insertions(+), 1121 deletions(-) delete mode 100644 components/esp32s2/include/esp_sleep.h delete mode 100644 components/esp32s2/sleep_modes.c rename components/{esp32 => esp_system}/include/esp_sleep.h (93%) rename components/{esp32 => esp_system}/sleep_modes.c (82%) diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 1296364f55..4166725329 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -22,7 +22,6 @@ else() "intr_alloc.c" "pm_esp32.c" "pm_trace.c" - "sleep_modes.c" "spiram.c" "spiram_psram.c" "system_api_esp32.c") @@ -31,10 +30,9 @@ else() set(requires driver efuse soc) #unfortunately rom/uart uses SOC registers directly - # driver is a public requirement because esp_sleep.h uses gpio_num_t & touch_pad_t # app_update is added here because cpu_start.c uses esp_ota_get_app_description() function. # esp_timer is added here because cpu_start.c uses esp_timer - set(priv_requires app_trace app_update bootloader_support log mbedtls nvs_flash pthread + set(priv_requires app_trace app_update bootloader_support esp_system log mbedtls nvs_flash pthread spi_flash vfs espcoredump esp_common perfmon esp_timer esp_ipc) set(fragments linker.lf ld/esp32_fragments.lf) diff --git a/components/esp32s2/CMakeLists.txt b/components/esp32s2/CMakeLists.txt index 3879c14e7e..dcf3110167 100644 --- a/components/esp32s2/CMakeLists.txt +++ b/components/esp32s2/CMakeLists.txt @@ -21,7 +21,6 @@ else() "intr_alloc.c" "pm_esp32s2.c" "pm_trace.c" - "sleep_modes.c" "spiram.c" "spiram_psram.c" "system_api_esp32s2.c" @@ -33,11 +32,10 @@ else() set(requires driver efuse) - # driver is a public requirement because esp_sleep.h uses gpio_num_t & touch_pad_t # app_update is added here because cpu_start.c uses esp_ota_get_app_description() function. # esp_timer is added here because cpu_start.c uses esp_timer set(priv_requires - app_trace app_update bootloader_support log mbedtls nvs_flash + app_trace app_update bootloader_support esp_system log mbedtls nvs_flash pthread spi_flash vfs espcoredump esp_common esp_timer) set(fragments linker.lf ld/esp32s2_fragments.lf) diff --git a/components/esp32s2/include/esp_sleep.h b/components/esp32s2/include/esp_sleep.h deleted file mode 100644 index 7a1fd0cb30..0000000000 --- a/components/esp32s2/include/esp_sleep.h +++ /dev/null @@ -1,359 +0,0 @@ -// 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 -#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_XTAL, //!< XTAL oscillator - 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_ALL, //!< Not a wakeup cause, used to disable all wakeup sources with esp_sleep_disable_wakeup_source - 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_GPIO, //!< Wakeup caused by GPIO (light sleep only) - ESP_SLEEP_WAKEUP_UART, //!< Wakeup caused by UART (light sleep only) - ESP_SLEEP_WAKEUP_WIFI, //!< Wakeup caused by WIFI (light sleep only) - ESP_SLEEP_WAKEUP_COCPU, //!< Wakeup caused by COCPU int - ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG, //!< Wakeup caused by COCPU crash -} esp_sleep_source_t; - -/* Leave this type define for compatibility */ -typedef esp_sleep_source_t esp_sleep_wakeup_cause_t; - -/** - * @brief Disable wakeup source - * - * This function is used to deactivate wake up trigger for source - * defined as parameter of the function. - * - * @note This function does not modify wake up configuration in RTC. - * It will be performed in esp_sleep_start function. - * - * See docs/sleep-modes.rst for details. - * - * @param source - number of source to disable of type esp_sleep_source_t - * @return - * - ESP_OK on success - * - ESP_ERR_INVALID_STATE if trigger was not active - */ -esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source); - -/** - * @brief Enable wakeup by ULP coprocessor - * - * @return - * - ESP_OK on success - */ -esp_err_t esp_sleep_enable_ulp_wakeup(void); - -/** - * @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. - * - * @note The FSM mode of the touch button should be configured - * as the timer trigger mode. - * - * @return - * - ESP_OK on success - * - ESP_ERR_NOT_SUPPORTED if additional current by touch (CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT) is enabled. - * - ESP_ERR_INVALID_STATE if wakeup triggers conflict - */ -esp_err_t esp_sleep_enable_touchpad_wakeup(void); - -/** - * @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(void); - -/** - * @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 Enable wakeup from light sleep using GPIOs - * - * Each GPIO supports wakeup function, which can be triggered on either low level - * or high level. Unlike EXT0 and EXT1 wakeup sources, this method can be used - * both for all IOs: RTC IOs and digital IOs. It can only be used to wakeup from - * light sleep though. - * - * To enable wakeup, first call gpio_wakeup_enable, specifying gpio number and - * wakeup level, for each GPIO which is used for wakeup. - * Then call this function to enable wakeup feature. - * - * @note In revisions 0 and 1 of the ESP32, GPIO wakeup source - * can not be used together with touch or ULP wakeup sources. - * - * @return - * - ESP_OK on success - * - ESP_ERR_INVALID_STATE if wakeup triggers conflict - */ -esp_err_t esp_sleep_enable_gpio_wakeup(void); - -/** - * @brief Enable wakeup from light sleep using UART - * - * Use uart_set_wakeup_threshold function to configure UART wakeup threshold. - * - * Wakeup from light sleep takes some time, so not every character sent - * to the UART can be received by the application. - * - * @param uart_num UART port to wake up from - * @return - * - ESP_OK on success - * - ESP_ERR_INVALID_ARG if wakeup from given UART is not supported - */ -esp_err_t esp_sleep_enable_uart_wakeup(int uart_num); - -/** - * @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(void); - -/** - * @brief Enable wakeup by WiFi MAC - * @return - * - ESP_OK on success - */ -esp_err_t esp_sleep_enable_wifi_wakeup(void); - -/** - * @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(void) __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(void); - -/** - * @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 Get the wakeup source which caused wakeup from sleep - * - * @return cause of wake up from last sleep (deep sleep or light sleep) - */ -esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void); - - -/** - * @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 diff --git a/components/esp32s2/sleep_modes.c b/components/esp32s2/sleep_modes.c deleted file mode 100644 index a30c0a5ae1..0000000000 --- a/components/esp32s2/sleep_modes.c +++ /dev/null @@ -1,720 +0,0 @@ -// 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. - -#include -#include -#include -#include "esp_attr.h" -#include "esp_sleep.h" -#include "esp_private/esp_timer_private.h" -#include "esp_log.h" -#include "esp32s2/clk.h" -#include "esp_newlib.h" -#include "esp_spi_flash.h" -#include "esp32s2/rom/cache.h" -#include "esp32s2/rom/rtc.h" -#include "esp_rom_uart.h" -#include "esp_rom_sys.h" -#include "soc/cpu.h" -#include "soc/rtc.h" -#include "soc/spi_periph.h" -#include "soc/dport_reg.h" -#include "soc/extmem_reg.h" -#include "soc/soc_memory_layout.h" -#include "soc/uart_caps.h" -#include "hal/wdt_hal.h" -#include "hal/clk_gate_ll.h" -#include "driver/rtc_io.h" -#include "freertos/FreeRTOS.h" -#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 - -// Extra time it takes to enter and exit light sleep and deep sleep -// For deep sleep, this is until the wake stub runs (not the app). -#ifdef CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS -#define LIGHT_SLEEP_TIME_OVERHEAD_US (650 + 30 * 240 / CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ) -#define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ) -#else -#define LIGHT_SLEEP_TIME_OVERHEAD_US (250 + 30 * 240 / CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ) -#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ) -#endif // CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS - -// Minimal amount of time we can sleep for -#define LIGHT_SLEEP_MIN_TIME_US 200 - -#define CHECK_SOURCE(source, value, mask) ((s_config.wakeup_triggers & mask) && \ - (source == value)) - -/** - * Internal structure which holds all requested deep sleep parameters - */ -typedef struct { - esp_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX]; - uint64_t sleep_duration; - uint32_t wakeup_triggers : 15; - uint32_t ext1_trigger_mode : 1; - uint32_t ext1_rtc_gpio_mask : 18; - uint32_t ext0_trigger_level : 1; - uint32_t ext0_rtc_gpio_num : 5; - uint32_t sleep_time_adjustment; - uint64_t rtc_ticks_at_sleep_start; -} sleep_config_t; - -static sleep_config_t s_config = { - .pd_options = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO }, - .wakeup_triggers = 0 -}; - -/* Internal variable used to track if light sleep wakeup sources are to be - expected when determining wakeup cause. */ -static bool s_light_sleep_wakeup = false; - -/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() - is not thread-safe. */ -static _lock_t lock_rtc_memory_crc; - -static const char* TAG = "sleep"; - -static uint32_t get_power_down_flags(void); -static void ext0_wakeup_prepare(void); -static void ext1_wakeup_prepare(void); -static void timer_wakeup_prepare(void); -static void touch_wakeup_prepare(void); - -/* Wake from deep sleep stub - See esp_deepsleep.h esp_wake_deep_sleep() comments for details. -*/ -esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void) -{ - _lock_acquire(&lock_rtc_memory_crc); - uint32_t stored_crc = REG_READ(RTC_MEMORY_CRC_REG); - set_rtc_memory_crc(); - uint32_t calc_crc = REG_READ(RTC_MEMORY_CRC_REG); - REG_WRITE(RTC_MEMORY_CRC_REG, stored_crc); - _lock_release(&lock_rtc_memory_crc); - - if (stored_crc != calc_crc) { - return NULL; - } - esp_deep_sleep_wake_stub_fn_t stub_ptr = (esp_deep_sleep_wake_stub_fn_t) REG_READ(RTC_ENTRY_ADDR_REG); - if (!esp_ptr_executable(stub_ptr)) { - return NULL; - } - return stub_ptr; -} - -void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) -{ - _lock_acquire(&lock_rtc_memory_crc); - REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); - set_rtc_memory_crc(); - _lock_release(&lock_rtc_memory_crc); -} - -void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { - /* Clear MMU for CPU 0 */ - REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN); -} - -void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void); - -void esp_deep_sleep(uint64_t time_in_us) -{ - esp_sleep_enable_timer_wakeup(time_in_us); - esp_deep_sleep_start(); -} - -static void IRAM_ATTR flush_uarts(void) -{ - for (int i = 0; i < SOC_UART_NUM; ++i) { - if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { - esp_rom_uart_tx_wait_idle(i); - } - } -} - -static void IRAM_ATTR suspend_uarts(void) -{ - for (int i = 0; i < SOC_UART_NUM; ++i) { - if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { - REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); - REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); - while (REG_GET_FIELD(UART_FSM_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { - ; - } - } - } -} - -static void IRAM_ATTR resume_uarts(void) -{ - for (int i = 0; i < SOC_UART_NUM; ++i) { - if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { - REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); - REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); - REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XON); - } - } -} - -static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) -{ - // Stop UART output so that output is not lost due to APB frequency change. - // For light sleep, suspend UART output — it will resume after wakeup. - // For deep sleep, wait for the contents of UART FIFO to be sent. - if (pd_flags & RTC_SLEEP_PD_DIG) { - flush_uarts(); - } else { - suspend_uarts(); - } - - // Save current frequency and switch to XTAL - // Save current frequency and switch to XTAL - rtc_cpu_freq_config_t cpu_freq_config; - rtc_clk_cpu_freq_get_config(&cpu_freq_config); - rtc_clk_cpu_freq_set_xtal(); - - // Configure pins for external wakeup - if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { - ext0_wakeup_prepare(); - } - if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) { - ext1_wakeup_prepare(); - } - // Enable ULP wakeup - if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { - // no-op for esp32s2 - } - // Enable Touch wakeup - if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) { - touch_wakeup_prepare(); - } - - uint32_t reject_triggers = 0; - if ((pd_flags & RTC_SLEEP_PD_DIG) == 0) { - /* Light sleep, enable sleep reject for faster return from this function, - * in case the wakeup is already triggerred. - */ - reject_triggers = s_config.wakeup_triggers; - } - - // Enter sleep - rtc_sleep_config_t config = RTC_SLEEP_CONFIG_DEFAULT(pd_flags); - rtc_sleep_init(config); - - // Configure timer wakeup - if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && - s_config.sleep_duration > 0) { - timer_wakeup_prepare(); - } - - uint32_t result = rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); - - // Restore CPU frequency - rtc_clk_cpu_freq_set_config(&cpu_freq_config); - - // re-enable UART output - resume_uarts(); - - return result; -} - -void IRAM_ATTR esp_deep_sleep_start(void) -{ - // record current RTC time - s_config.rtc_ticks_at_sleep_start = rtc_time_get(); - esp_sync_counters_rtc_and_frc(); - // 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(); - - // Correct the sleep time - s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; - - // 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) { - ; - } -} - -/** - * 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 esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline)); - -static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) -{ - // Enter sleep - esp_err_t err = esp_sleep_start(pd_flags); - - // If VDDSDIO regulator was controlled by RTC registers before sleep, - // restore the configuration. - if (vddsdio_config.force) { - rtc_vddsdio_set_config(vddsdio_config); - } - - // 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 - esp_rom_delay_us(flash_enable_time_us); - } - return err; -} - -esp_err_t esp_light_sleep_start(void) -{ - static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL(&light_sleep_lock); - /* We will be calling esp_timer_private_advance inside DPORT access critical - * section. Make sure the code on the other CPU is not holding esp_timer - * lock, otherwise there will be deadlock. - */ - esp_timer_private_lock(); - s_config.rtc_ticks_at_sleep_start = rtc_time_get(); - uint64_t frc_time_at_start = esp_timer_get_time(); - DPORT_STALL_OTHER_CPU_START(); - - // Decide which power domains can be powered down - uint32_t pd_flags = get_power_down_flags(); - - // Amount of time to subtract from actual sleep time. - // This is spent on entering and leaving light sleep. - s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US; - - // Decide if VDD_SDIO 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; - -#ifndef CONFIG_SPIRAM - const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US, - flash_enable_time_us + LIGHT_SLEEP_TIME_OVERHEAD_US + LIGHT_SLEEP_MIN_TIME_US); - - if (s_config.sleep_duration > vddsdio_pd_sleep_duration) { - pd_flags |= RTC_SLEEP_PD_VDDSDIO; - s_config.sleep_time_adjustment += flash_enable_time_us; - } -#endif //CONFIG_SPIRAM - - rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); - - // Safety net: enable WDT in case exit from light sleep fails - wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &RTCCNTL}; - bool wdt_was_enabled = wdt_hal_is_enabled(&rtc_wdt_ctx); // If WDT was enabled in the user code, then do not change it here. - if (!wdt_was_enabled) { - wdt_hal_init(&rtc_wdt_ctx, WDT_RWDT, 0, false); - uint32_t stage_timeout_ticks = (uint32_t)(1000ULL * rtc_clk_slow_freq_get_hz() / 1000ULL); - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_config_stage(&rtc_wdt_ctx, WDT_STAGE0, stage_timeout_ticks, WDT_STAGE_ACTION_RESET_RTC); - wdt_hal_enable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - } - - // Enter sleep, then wait for flash to be ready on wakeup - esp_err_t err = esp_light_sleep_inner(pd_flags, - flash_enable_time_us, vddsdio_config); - - s_light_sleep_wakeup = true; - - // FRC1 has been clock gated for the duration of the sleep, correct for that. - uint64_t rtc_ticks_at_end = rtc_time_get(); - uint64_t frc_time_at_end = esp_timer_get_time(); - - uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, - esp_clk_slowclk_cal_get()); - uint64_t frc_time_diff = frc_time_at_end - frc_time_at_start; - - int64_t time_diff = rtc_time_diff - frc_time_diff; - /* Small negative values (up to 1 RTC_SLOW clock period) are possible, - * for very small values of sleep_duration. Ignore those to keep esp_timer - * monotonic. - */ - if (time_diff > 0) { - esp_timer_private_advance(time_diff); - } - esp_set_time_from_rtc(); - - esp_timer_private_unlock(); - DPORT_STALL_OTHER_CPU_END(); - if (!wdt_was_enabled) { - wdt_hal_write_protect_disable(&rtc_wdt_ctx); - wdt_hal_disable(&rtc_wdt_ctx); - wdt_hal_write_protect_enable(&rtc_wdt_ctx); - } - portEXIT_CRITICAL(&light_sleep_lock); - return err; -} - -esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) -{ - // For most of sources it is enough to set trigger mask in local - // configuration structure. The actual RTC wake up options - // will be updated by esp_sleep_start(). - if (source == ESP_SLEEP_WAKEUP_ALL) { - s_config.wakeup_triggers = 0; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN; - s_config.sleep_duration = 0; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) { - s_config.ext0_rtc_gpio_num = 0; - s_config.ext0_trigger_level = 0; - s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) { - s_config.ext1_rtc_gpio_mask = 0; - s_config.ext1_trigger_mode = 0; - s_config.wakeup_triggers &= ~RTC_EXT1_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TOUCHPAD, RTC_TOUCH_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_TOUCH_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN; - } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) { - s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN); - } -#ifdef CONFIG_ESP32S2_ULP_COPROC_ENABLED - else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) { - s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN; - } -#endif - else { - ESP_LOGE(TAG, "Incorrect wakeup source (%d) to disable.", (int) source); - return ESP_ERR_INVALID_STATE; - } - return ESP_OK; -} - -esp_err_t esp_sleep_enable_ulp_wakeup(void) -{ - s_config.wakeup_triggers |= (RTC_ULP_TRIG_EN | RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); - return ESP_OK; -} - -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; - return ESP_OK; -} - -static void timer_wakeup_prepare(void) -{ - uint32_t period = esp_clk_slowclk_cal_get(); - int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment; - if (sleep_duration < 0) { - sleep_duration = 0; - } - int64_t rtc_count_delta = rtc_time_us_to_slowclk(sleep_duration, period); - rtc_sleep_set_wakeup_time(s_config.rtc_ticks_at_sleep_start + rtc_count_delta); - SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR_M); - SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M); -} - -/* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ -static void touch_wakeup_prepare(void) -{ - touch_pad_sleep_channel_t slp_config; - touch_pad_fsm_stop(); - touch_pad_clear_channel_mask(SOC_TOUCH_SENSOR_BIT_MASK_MAX); - touch_pad_sleep_channel_get_info(&slp_config); - touch_pad_set_channel_mask(BIT(slp_config.touch_num)); - touch_pad_fsm_start(); -} - -esp_err_t esp_sleep_enable_touchpad_wakeup(void) -{ - if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) { - ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0"); - return ESP_ERR_INVALID_STATE; - } - s_config.wakeup_triggers |= RTC_TOUCH_TRIG_EN; - return ESP_OK; -} - -touch_pad_t esp_sleep_get_touchpad_wakeup_status(void) -{ - if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) { - return TOUCH_PAD_MAX; - } - touch_pad_t pad_num; - esp_err_t ret = touch_pad_get_wakeup_status(&pad_num); //TODO 723diff commit id:fda9ada1b - assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero"); - return pad_num; -} - -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; - } - if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) { - return ESP_ERR_INVALID_ARG; - } - if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { - ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP"); - return ESP_ERR_INVALID_STATE; - } - s_config.ext0_rtc_gpio_num = rtc_io_number_get(gpio_num); - s_config.ext0_trigger_level = level; - s_config.wakeup_triggers |= RTC_EXT0_TRIG_EN; - return ESP_OK; -} - -static void ext0_wakeup_prepare(void) -{ - int rtc_gpio_num = s_config.ext0_rtc_gpio_num; - // Set GPIO to be used for wakeup - REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtc_gpio_num); - // Set level which will trigger wakeup - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - s_config.ext0_trigger_level, RTC_CNTL_EXT_WAKEUP0_LV_S); - // Find GPIO descriptor in the rtc_io_desc table and configure the pad - const rtc_io_desc_t* desc = &rtc_io_desc[rtc_gpio_num]; - REG_SET_BIT(desc->reg, desc->mux); - SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); - REG_SET_BIT(desc->reg, desc->ie); -} - -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; - } - // Translate bit map of GPIO numbers into the bit map of RTC IO numbers - uint32_t rtc_gpio_mask = 0; - for (int gpio = 0; mask; ++gpio, mask >>= 1) { - if ((mask & 1) == 0) { - continue; - } - if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { - ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio); - return ESP_ERR_INVALID_ARG; - } - rtc_gpio_mask |= BIT(rtc_io_number_get(gpio)); - } - s_config.ext1_rtc_gpio_mask = rtc_gpio_mask; - s_config.ext1_trigger_mode = mode; - s_config.wakeup_triggers |= RTC_EXT1_TRIG_EN; - return ESP_OK; -} - -static void ext1_wakeup_prepare(void) -{ - // Configure all RTC IOs selected as ext1 wakeup inputs - uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask; - for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) { - int rtc_pin = rtc_io_number_get(gpio); - if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) { - continue; - } - const rtc_io_desc_t* desc = &rtc_io_desc[rtc_pin]; - // Route pad to RTC - REG_SET_BIT(desc->reg, desc->mux); - SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); - // set input enable in sleep mode - REG_SET_BIT(desc->reg, desc->ie); - // Pad configuration depends on RTC_PERIPH state in sleep mode - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { - // RTC_PERIPH will be powered down, so RTC_IO_ registers will - // loose their state. Lock pad configuration. - // Pullups/pulldowns also need to be disabled. - REG_CLR_BIT(desc->reg, desc->pulldown); - REG_CLR_BIT(desc->reg, desc->pullup); - REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, desc->hold_force); - } - // Keep track of pins which are processed to bail out early - rtc_gpio_mask &= ~BIT(rtc_pin); - } - // Clear state from previous wakeup - REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); - // Set pins to be used for wakeup - REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, s_config.ext1_rtc_gpio_mask); - // Set logic function (any low, all high) - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - s_config.ext1_trigger_mode, RTC_CNTL_EXT_WAKEUP1_LV_S); -} - -uint64_t esp_sleep_get_ext1_wakeup_status(void) -{ - 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); - // Translate bit map of RTC IO numbers into the bit map of GPIO numbers - uint64_t gpio_mask = 0; - for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { - if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { - continue; - } - int rtc_pin = rtc_io_number_get(gpio); - if ((status & BIT(rtc_pin)) == 0) { - continue; - } - gpio_mask |= 1ULL << gpio; - } - return gpio_mask; -} - -esp_err_t esp_sleep_enable_gpio_wakeup(void) -{ - if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { - ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP"); - return ESP_ERR_INVALID_STATE; - } - s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN; - return ESP_OK; -} - -esp_err_t esp_sleep_enable_uart_wakeup(int uart_num) -{ - if (uart_num == 0) { - s_config.wakeup_triggers |= RTC_UART0_TRIG_EN; - } else if (uart_num == 1) { - s_config.wakeup_triggers |= RTC_UART1_TRIG_EN; - } else { - return ESP_ERR_INVALID_ARG; - } - - return ESP_OK; -} - -esp_err_t esp_sleep_enable_wifi_wakeup(void) -{ - s_config.wakeup_triggers |= RTC_WIFI_TRIG_EN; - return ESP_OK; -} - -esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) -{ - if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET && !s_light_sleep_wakeup) { - return ESP_SLEEP_WAKEUP_UNDEFINED; - } - - uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE); - if (wakeup_cause & RTC_EXT0_TRIG_EN) { - return ESP_SLEEP_WAKEUP_EXT0; - } else if (wakeup_cause & RTC_EXT1_TRIG_EN) { - return ESP_SLEEP_WAKEUP_EXT1; - } else if (wakeup_cause & RTC_TIMER_TRIG_EN) { - return ESP_SLEEP_WAKEUP_TIMER; - } else if (wakeup_cause & RTC_TOUCH_TRIG_EN) { - return ESP_SLEEP_WAKEUP_TOUCHPAD; - } else if (wakeup_cause & RTC_ULP_TRIG_EN) { - return ESP_SLEEP_WAKEUP_ULP; - } else if (wakeup_cause & RTC_GPIO_TRIG_EN) { - return ESP_SLEEP_WAKEUP_GPIO; - } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) { - return ESP_SLEEP_WAKEUP_UART; - } else if (wakeup_cause & RTC_WIFI_TRIG_EN) { - return ESP_SLEEP_WAKEUP_WIFI; - } else if (wakeup_cause & RTC_COCPU_TRIG_EN) { - return ESP_SLEEP_WAKEUP_ULP; - } else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) { - return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG; - } else { - return ESP_SLEEP_WAKEUP_UNDEFINED; - } -} - -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; - } - s_config.pd_options[domain] = option; - return ESP_OK; -} - -static uint32_t get_power_down_flags(void) -{ - // Where needed, convert AUTO options to ON. Later interpret AUTO as OFF. - - // RTC_SLOW_MEM is needed for the ULP, so keep RTC_SLOW_MEM powered up if ULP - // is used and RTC_SLOW_MEM is Auto. - // If there is any data placed into .rtc.data or .rtc.bss segments, and - // RTC_SLOW_MEM is Auto, keep it powered up as well. - - // Labels are defined in the linker script, see esp32s2.ld. - extern int _rtc_slow_length; - - if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) && - ((size_t) &_rtc_slow_length > 0 || - (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON; - } - - // RTC_FAST_MEM is needed for deep sleep stub. - // If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub - // can run. - // In the new chip revision, deep sleep stub will be optional, - // and this can be changed. - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON; - } - - // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup. - // If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH. - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) { - if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN | RTC_GPIO_TRIG_EN)) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON; - } else if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { - // In both rev. 0 and rev. 1 of ESP32, forcing power up of RTC_PERIPH - // prevents ULP timer and touch FSMs from working correctly. - s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF; - } - } - - if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] == ESP_PD_OPTION_AUTO) { - s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF; - } - - const char* option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; - ESP_LOGD(TAG, "RTC_PERIPH: %s, RTC_SLOW_MEM: %s, RTC_FAST_MEM: %s", - option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]], - option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]], - option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]); - - // Prepare flags based on the selected options - 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; - } - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM; - } - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_PERIPH; - } -// if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] != ESP_PD_OPTION_ON) { -// pd_flags |= RTC_SLEEP_PD_XTAL; -// } - return pd_flags; -} diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index 0856648800..2312b0e59f 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -1,4 +1,4 @@ -idf_component_register(SRCS "panic.c" "system_api.c" "startup.c" "system_time.c" +idf_component_register(SRCS "panic.c" "system_api.c" "startup.c" "sleep_modes.c" "system_time.c" INCLUDE_DIRS include PRIV_REQUIRES spi_flash app_update # requirements due to startup code diff --git a/components/esp32/include/esp_sleep.h b/components/esp_system/include/esp_sleep.h similarity index 93% rename from components/esp32/include/esp_sleep.h rename to components/esp_system/include/esp_sleep.h index a1d912b5e2..e423e6df76 100644 --- a/components/esp32/include/esp_sleep.h +++ b/components/esp_system/include/esp_sleep.h @@ -16,8 +16,9 @@ #include #include "esp_err.h" -#include "driver/gpio.h" -#include "driver/touch_pad.h" + +#include "hal/touch_sensor_types.h" +#include "hal/gpio_types.h" #ifdef __cplusplus extern "C" { @@ -64,6 +65,9 @@ typedef enum { ESP_SLEEP_WAKEUP_ULP, //!< Wakeup caused by ULP program ESP_SLEEP_WAKEUP_GPIO, //!< Wakeup caused by GPIO (light sleep only) ESP_SLEEP_WAKEUP_UART, //!< Wakeup caused by UART (light sleep only) + ESP_SLEEP_WAKEUP_WIFI, //!< Wakeup caused by WIFI (light sleep only) + ESP_SLEEP_WAKEUP_COCPU, //!< Wakeup caused by COCPU int + ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG, //!< Wakeup caused by COCPU crash } esp_sleep_source_t; /* Leave this type define for compatibility */ @@ -89,7 +93,7 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source); /** * @brief Enable wakeup by ULP coprocessor - * @note ULP wakeup source cannot be used when RTC_PERIPH power domain is forced + * @note On ESP32, ULP wakeup source cannot 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 @@ -110,9 +114,8 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us); /** * @brief Enable wakeup by touch sensor * - * @note Touch wakeup source cannot be used when RTC_PERIPH power domain is forced - * to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup - * source is used. + * @note In revisions 0 and 1 of the ESP32, touch wakeup source + * can not be used when RTC_PERIPH power domain is forced * * @note The FSM mode of the touch button should be configured * as the timer trigger mode. @@ -145,7 +148,8 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void); * @note This function does not modify pin configuration. The pin is * configured in esp_sleep_start, immediately before entering sleep mode. * - * @note ext0 wakeup source cannot be used together with touch or ULP wakeup sources. + * @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. @@ -202,7 +206,8 @@ esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode * wakeup level, for each GPIO which is used for wakeup. * Then call this function to enable wakeup feature. * - * @note GPIO wakeup source cannot be used together with touch or ULP wakeup sources. + * @note In revisions 0 and 1 of the ESP32, GPIO wakeup source + * can not be used together with touch or ULP wakeup sources. * * @return * - ESP_OK on success @@ -227,6 +232,14 @@ esp_err_t esp_sleep_enable_gpio_wakeup(void); */ esp_err_t esp_sleep_enable_uart_wakeup(int uart_num); +/** + * @brief Enable wakeup by WiFi MAC + * @return + * - ESP_OK on success + */ +esp_err_t esp_sleep_enable_wifi_wakeup(void); + + /** * @brief Get the bit mask of GPIOs which caused wakeup (ext1) * diff --git a/components/esp32/sleep_modes.c b/components/esp_system/sleep_modes.c similarity index 82% rename from components/esp32/sleep_modes.c rename to components/esp_system/sleep_modes.c index 574ccc079c..c8f64c9218 100644 --- a/components/esp32/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -15,17 +15,12 @@ #include #include #include + #include "esp_attr.h" #include "esp_sleep.h" #include "esp_private/esp_timer_private.h" #include "esp_log.h" -#include "esp32/clk.h" #include "esp_newlib.h" -#include "esp_spi_flash.h" -#include "esp_rom_sys.h" -#include "esp32/rom/cache.h" -#include "esp32/rom/rtc.h" -#include "esp_rom_uart.h" #include "soc/cpu.h" #include "soc/rtc.h" #include "soc/spi_periph.h" @@ -34,9 +29,25 @@ #include "hal/wdt_hal.h" #include "driver/rtc_io.h" #include "driver/uart.h" +#include "driver/touch_sensor_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "soc/uart_caps.h" +#include "hal/clk_gate_ll.h" #include "sdkconfig.h" +#include "esp_rom_uart.h" + +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/cache.h" +#include "esp32/rom/rtc.h" +#include "esp32/clk.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/clk.h" +#include "esp32s2/rom/cache.h" +#include "esp32s2/rom/rtc.h" +#include "esp32s2/rom/ets_sys.h" +#include "soc/extmem_reg.h" +#endif // If light sleep time is less than that, don't power down flash #define FLASH_PD_MIN_SLEEP_TIME_US 2000 @@ -44,15 +55,25 @@ // Time from VDD_SDIO power up to first flash read in ROM code #define VDD_SDIO_POWERUP_TO_FLASH_READ_US 700 -// Extra time it takes to enter and exit light sleep and deep sleep -// For deep sleep, this is until the wake stub runs (not the app). -#ifdef CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS -#define LIGHT_SLEEP_TIME_OVERHEAD_US (650 + 30 * 240 / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) -#define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) +#ifdef CONFIG_IDF_TARGET_ESP32 +#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ +#elif CONFIG_IDF_TARGET_ESP32S2 +#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ +#endif + +#if defined(CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) || defined(CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS) +#define LIGHT_SLEEP_TIME_OVERHEAD_US (650 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ) +#define DEEP_SLEEP_TIME_OVERHEAD_US (650 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) #else -#define LIGHT_SLEEP_TIME_OVERHEAD_US (250 + 30 * 240 / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) -#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ) -#endif // CONFIG_ESP32_RTC_CLK_SRC +#define LIGHT_SLEEP_TIME_OVERHEAD_US (250 + 30 * 240 / DEFAULT_CPU_FREQ_MHZ) +#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ) +#endif + +#if defined(CONFIG_IDF_TARGET_ESP32) && defined(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY) +#define DEEP_SLEEP_WAKEUP_DELAY CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY +#else +#define DEEP_SLEEP_WAKEUP_DELAY 0 +#endif // Minimal amount of time we can sleep for #define LIGHT_SLEEP_MIN_TIME_US 200 @@ -95,6 +116,11 @@ static void ext0_wakeup_prepare(void); static void ext1_wakeup_prepare(void); static void timer_wakeup_prepare(void); + +#ifdef CONFIG_IDF_TARGET_ESP32S2 +static void touch_wakeup_prepare(void); +#endif + /* Wake from deep sleep stub See esp_deepsleep.h esp_wake_deep_sleep() comments for details. */ @@ -127,17 +153,21 @@ void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { /* Clear MMU for CPU 0 */ +#if CONFIG_IDF_TARGET_ESP32 _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) | DPORT_PRO_CACHE_MMU_IA_CLR); _DPORT_REG_WRITE(DPORT_PRO_CACHE_CTRL1_REG, _DPORT_REG_READ(DPORT_PRO_CACHE_CTRL1_REG) & (~DPORT_PRO_CACHE_MMU_IA_CLR)); -#if CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY > 0 +#if DEEP_SLEEP_WAKEUP_DELAY > 0 // ROM code has not started yet, so we need to set delay factor // used by esp_rom_delay_us first. ets_update_cpu_frequency_rom(ets_get_detected_xtal_freq() / 1000000); // This delay is configured in menuconfig, it can be used to give // the flash chip some time to become ready. - esp_rom_delay_us(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY); + esp_rom_delay_us(DEEP_SLEEP_WAKEUP_DELAY); +#endif +#elif CONFIG_IDF_TARGET_ESP32S2 + REG_SET_BIT(EXTMEM_CACHE_DBG_INT_ENA_REG, EXTMEM_CACHE_DBG_EN); #endif } @@ -149,29 +179,57 @@ void esp_deep_sleep(uint64_t time_in_us) esp_deep_sleep_start(); } +// [refactor-todo] provide target logic for body of uart functions below static void IRAM_ATTR flush_uarts(void) { - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < SOC_UART_NUM; ++i) { +#ifdef CONFIG_IDF_TARGET_ESP32 esp_rom_uart_tx_wait_idle(i); +#elif CONFIG_IDF_TARGET_ESP32S2 + if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { + esp_rom_uart_tx_wait_idle(i); + } +#endif } } static void IRAM_ATTR suspend_uarts(void) { - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < SOC_UART_NUM; ++i) { +#ifdef CONFIG_IDF_TARGET_ESP32 + /* Note: Set `UART_FORCE_XOFF` can't stop new Tx request. */ REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); while (REG_GET_FIELD(UART_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { ; } +#elif CONFIG_IDF_TARGET_ESP32S2 + if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { + REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); + REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); + while (REG_GET_FIELD(UART_FSM_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { + ; + } + } +#endif } } static void IRAM_ATTR resume_uarts(void) { - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < SOC_UART_NUM; ++i) { +#ifdef CONFIG_IDF_TARGET_ESP32 REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF); REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); +#elif CONFIG_IDF_TARGET_ESP32S2 + if (periph_ll_periph_enabled(PERIPH_UART0_MODULE + i)) { + REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON); + REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); + while (REG_GET_FIELD(UART_FSM_STATUS_REG(i), UART_ST_UTX_OUT) != 0) { + ; + } + } +#endif } } @@ -198,17 +256,31 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) if (s_config.wakeup_triggers & RTC_EXT1_TRIG_EN) { ext1_wakeup_prepare(); } + +#ifdef CONFIG_IDF_TARGET_ESP32 // Enable ULP wakeup if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_WAKEUP_FORCE_EN); } +#endif + +#ifdef CONFIG_IDF_TARGET_ESP32S2 + // Enable Touch wakeup + if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) { + touch_wakeup_prepare(); + } +#endif uint32_t reject_triggers = 0; if ((pd_flags & RTC_SLEEP_PD_DIG) == 0 && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) { /* Light sleep, enable sleep reject for faster return from this function, * in case the wakeup is already triggerred. */ +#if CONFIG_IDF_TARGET_ESP32 reject_triggers = RTC_CNTL_LIGHT_SLP_REJECT_EN_M | RTC_CNTL_GPIO_REJECT_EN_M; +#elif CONFIG_IDF_TARGET_ESP32S2 + reject_triggers = s_config.wakeup_triggers; +#endif } // Enter sleep @@ -220,7 +292,12 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) s_config.sleep_duration > 0) { timer_wakeup_prepare(); } + +#ifdef CONFIG_IDF_TARGET_ESP32 uint32_t result = rtc_sleep_start(s_config.wakeup_triggers, reject_triggers); +#elif CONFIG_IDF_TARGET_ESP32S2 + uint32_t result = rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, 1); +#endif // Restore CPU frequency rtc_clk_cpu_freq_set_config(&cpu_freq_config); @@ -248,7 +325,11 @@ void IRAM_ATTR esp_deep_sleep_start(void) s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; // Enter sleep +#ifdef CONFIG_IDF_TARGET_ESP32 esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_XTAL | pd_flags); +#elif CONFIG_IDF_TARGET_ESP32S2 + esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags); +#endif // Because RTC is in a slower clock domain than the CPU, it // can take several CPU cycles for the sleep mode to start. @@ -308,8 +389,7 @@ esp_err_t esp_light_sleep_start(void) // Decide if VDD_SDIO 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; + const uint32_t flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US + DEEP_SLEEP_WAKEUP_DELAY; #ifndef CONFIG_SPIRAM const uint32_t vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US, @@ -395,7 +475,7 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) { s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN); } -#ifdef CONFIG_ESP32_ULP_COPROC_ENABLED +#if defined(CONFIG_ESP32_ULP_COPROC_ENABLED) || defined(CONFIG_ESP32S2_ULP_COPROC_ENABLED) else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) { s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN; } @@ -409,9 +489,10 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) esp_err_t esp_sleep_enable_ulp_wakeup(void) { +#ifdef CONFIG_IDF_TARGET_ESP32 #ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT return ESP_ERR_NOT_SUPPORTED; -#endif +#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT #ifdef CONFIG_ESP32_ULP_COPROC_ENABLED if(s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) { ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0"); @@ -419,8 +500,11 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void) } s_config.wakeup_triggers |= RTC_ULP_TRIG_EN; return ESP_OK; -#else +#else // CONFIG_ESP32_ULP_COPROC_ENABLED return ESP_ERR_INVALID_STATE; +#endif // CONFIG_ESP32_ULP_COPROC_ENABLED +#elif CONFIG_IDF_TARGET_ESP32S2 + return ESP_ERR_NOT_SUPPORTED; #endif } @@ -441,8 +525,27 @@ static void timer_wakeup_prepare(void) int64_t rtc_count_delta = rtc_time_us_to_slowclk(sleep_duration, period); rtc_sleep_set_wakeup_time(s_config.rtc_ticks_at_sleep_start + rtc_count_delta); + +#ifdef CONFIG_IDF_TARGET_ESP32S2 + SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR_M); + SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M); +#endif } + +#ifdef CONFIG_IDF_TARGET_ESP32S2 +/* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ +static void touch_wakeup_prepare(void) +{ + touch_pad_sleep_channel_t slp_config; + touch_pad_fsm_stop(); + touch_pad_clear_channel_mask(SOC_TOUCH_SENSOR_BIT_MASK_MAX); + touch_pad_sleep_channel_get_info(&slp_config); + touch_pad_set_channel_mask(BIT(slp_config.touch_num)); + touch_pad_fsm_start(); +} +#endif + esp_err_t esp_sleep_enable_touchpad_wakeup(void) { #ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT @@ -462,7 +565,7 @@ touch_pad_t esp_sleep_get_touchpad_wakeup_status(void) return TOUCH_PAD_MAX; } touch_pad_t pad_num; - esp_err_t ret = touch_pad_get_wakeup_status(&pad_num); + esp_err_t ret = touch_pad_get_wakeup_status(&pad_num); //TODO 723diff commit id:fda9ada1b assert(ret == ESP_OK && "wakeup reason is RTC_TOUCH_TRIG_EN but SENS_TOUCH_MEAS_EN is zero"); return pad_num; } @@ -545,7 +648,11 @@ static void ext1_wakeup_prepare(void) // Pullups/pulldowns also need to be disabled. REG_CLR_BIT(desc->reg, desc->pulldown); REG_CLR_BIT(desc->reg, desc->pullup); +#ifdef CONFIG_IDF_TARGET_ESP32 REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force); +#elif CONFIG_IDF_TARGET_ESP32S2 + REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, desc->hold_force); +#endif } // Keep track of pins which are processed to bail out early rtc_gpio_mask &= ~BIT(rtc_pin); @@ -603,13 +710,29 @@ esp_err_t esp_sleep_enable_uart_wakeup(int uart_num) return ESP_OK; } +esp_err_t esp_sleep_enable_wifi_wakeup(void) +{ +#if CONFIG_IDF_TARGET_ESP32 + return ESP_ERR_NOT_SUPPORTED; +#elif CONFIG_IDF_TARGET_ESP32S2 + s_config.wakeup_triggers |= RTC_WIFI_TRIG_EN; + return ESP_OK; +#endif +} + + esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) { if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET && !s_light_sleep_wakeup) { return ESP_SLEEP_WAKEUP_UNDEFINED; } +#ifdef CONFIG_IDF_TARGET_ESP32 uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE); +#elif CONFIG_IDF_TARGET_ESP32S2 + uint32_t wakeup_cause = REG_GET_FIELD(RTC_CNTL_SLP_WAKEUP_CAUSE_REG, RTC_CNTL_WAKEUP_CAUSE); +#endif + if (wakeup_cause & RTC_EXT0_TRIG_EN) { return ESP_SLEEP_WAKEUP_EXT0; } else if (wakeup_cause & RTC_EXT1_TRIG_EN) { @@ -624,6 +747,14 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) return ESP_SLEEP_WAKEUP_GPIO; } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) { return ESP_SLEEP_WAKEUP_UART; +#if CONFIG_IDF_TARGET_ESP32S2 + } else if (wakeup_cause & RTC_WIFI_TRIG_EN) { + return ESP_SLEEP_WAKEUP_WIFI; + } else if (wakeup_cause & RTC_COCPU_TRIG_EN) { + return ESP_SLEEP_WAKEUP_ULP; + } else if (wakeup_cause & RTC_COCPU_TRAP_TRIG_EN) { + return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG; +#endif } else { return ESP_SLEEP_WAKEUP_UNDEFINED; } @@ -648,7 +779,7 @@ static uint32_t get_power_down_flags(void) // If there is any data placed into .rtc.data or .rtc.bss segments, and // RTC_SLOW_MEM is Auto, keep it powered up as well. - // Labels are defined in the linker script, see esp32.ld. + // Labels are defined in the linker script extern int _rtc_slow_length; if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) && @@ -699,6 +830,8 @@ static uint32_t get_power_down_flags(void) if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_RTC_PERIPH; } + +#ifdef CONFIG_IDF_TARGET_ESP32 if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_XTAL; } @@ -709,6 +842,8 @@ static uint32_t get_power_down_flags(void) pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; #endif } +#endif + return pd_flags; } diff --git a/docs/Doxyfile b/docs/Doxyfile index 4b6388c150..b62b4062a3 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -245,7 +245,7 @@ INPUT = \ ## ESP HTTPS OTA $(IDF_PATH)/components/esp_https_ota/include/esp_https_ota.h \ ## Sleep - $(IDF_PATH)/components/$(IDF_TARGET)/include/esp_sleep.h \ + $(IDF_PATH)/components/esp_system/include/esp_sleep.h \ ## Logging $(IDF_PATH)/components/log/include/esp_log.h \ ## Base MAC address diff --git a/examples/system/light_sleep/main/light_sleep_example_main.c b/examples/system/light_sleep/main/light_sleep_example_main.c index a11a07e473..d10c510aaf 100644 --- a/examples/system/light_sleep/main/light_sleep_example_main.c +++ b/examples/system/light_sleep/main/light_sleep_example_main.c @@ -17,6 +17,7 @@ #include "esp_sleep.h" #include "esp_log.h" #include "driver/uart.h" +#include "driver/gpio.h" /* Most development boards have "boot" button attached to GPIO0. * You can also change this to another pin. From 0b6ead74b5afe99e1c6fd1a7c8726d21b04ac30e Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Thu, 30 Jul 2020 15:30:33 +0800 Subject: [PATCH 3/7] soc: ll and hal for sleep related code --- components/soc/include/hal/rtc_hal.h | 33 +++++++++++ components/soc/include/hal/rtc_io_hal.h | 7 +++ components/soc/include/hal/soc_hal.h | 4 +- .../soc/include/hal/touch_sensor_types.h | 3 + components/soc/soc/esp32s2/include/soc/rtc.h | 8 --- .../soc/src/esp32/include/hal/rtc_cntl_ll.h | 55 ++++++++++++++++++ .../soc/src/esp32/include/hal/rtc_io_ll.h | 8 +++ components/soc/src/esp32/include/hal/soc_ll.h | 1 + .../soc/src/esp32s2/include/hal/rtc_cntl_ll.h | 58 +++++++++++++++++++ .../soc/src/esp32s2/include/hal/rtc_io_ll.h | 8 +++ .../soc/src/esp32s2/include/hal/soc_ll.h | 1 + .../soc/src/esp32s3/include/hal/rtc_cntl_ll.h | 58 +++++++++++++++++++ .../soc/src/esp32s3/include/hal/rtc_io_ll.h | 10 ++++ .../soc/src/esp32s3/include/hal/soc_ll.h | 1 + components/soc/src/hal/soc_hal.c | 2 + 15 files changed, 247 insertions(+), 10 deletions(-) create mode 100644 components/soc/include/hal/rtc_hal.h create mode 100644 components/soc/src/esp32/include/hal/rtc_cntl_ll.h create mode 100644 components/soc/src/esp32s2/include/hal/rtc_cntl_ll.h create mode 100644 components/soc/src/esp32s3/include/hal/rtc_cntl_ll.h diff --git a/components/soc/include/hal/rtc_hal.h b/components/soc/include/hal/rtc_hal.h new file mode 100644 index 0000000000..a700c90a93 --- /dev/null +++ b/components/soc/include/hal/rtc_hal.h @@ -0,0 +1,33 @@ +// Copyright 2020 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 "hal/gpio_types.h" +#include "hal/rtc_io_ll.h" +#include "hal/rtc_cntl_ll.h" + +#define rtc_hal_ext1_get_wakeup_pins() rtc_cntl_ll_ext1_get_wakeup_pins() + +#define rtc_hal_ext1_set_wakeup_pins(mask, mode) rtc_cntl_ll_ext1_set_wakeup_pins(mask, mode) + +#define rtc_hal_ext1_clear_wakeup_pins() rtc_cntl_ll_ext1_clear_wakeup_pins() + +#define rtc_hal_set_wakeup_timer(ticks) rtc_cntl_ll_set_wakeup_timer(ticks) + +/* + * Enable wakeup from ULP coprocessor. + */ +#define rtc_hal_ulp_wakeup_enable() rtc_cntl_ll_ulp_wakeup_enable() + diff --git a/components/soc/include/hal/rtc_io_hal.h b/components/soc/include/hal/rtc_io_hal.h index d1a8b11784..8bf0d64c00 100644 --- a/components/soc/include/hal/rtc_io_hal.h +++ b/components/soc/include/hal/rtc_io_hal.h @@ -219,6 +219,13 @@ void rtcio_hal_set_direction_in_sleep(int rtcio_num, rtc_gpio_mode_t mode); */ #define rtcio_hal_wakeup_disable(rtcio_num) rtcio_ll_wakeup_disable(rtcio_num) +/** + * Disable wakeup function from light sleep status for rtcio. + * + * @param rtcio_num The index of rtcio. 0 ~ SOC_RTC_IO_PIN_COUNT. + */ +#define rtcio_hal_ext0_set_wakeup_pin(rtcio_num, level) rtcio_ll_ext0_set_wakeup_pin(rtcio_num, level) + /** * Helper function to disconnect internal circuits from an RTC IO * This function disables input, output, pullup, pulldown, and enables diff --git a/components/soc/include/hal/soc_hal.h b/components/soc/include/hal/soc_hal.h index 6a4ab30c0a..e4400d0e07 100644 --- a/components/soc/include/hal/soc_hal.h +++ b/components/soc/include/hal/soc_hal.h @@ -17,12 +17,12 @@ #include #include +#include "esp_err.h" + #include "soc/soc_caps.h" #include "hal/cpu_hal.h" #include "hal/soc_ll.h" -#include "esp_err.h" - #ifdef __cplusplus extern "C" { #endif diff --git a/components/soc/include/hal/touch_sensor_types.h b/components/soc/include/hal/touch_sensor_types.h index cbadc1eade..d2ddf33e20 100644 --- a/components/soc/include/hal/touch_sensor_types.h +++ b/components/soc/include/hal/touch_sensor_types.h @@ -14,6 +14,9 @@ #pragma once +#include + +#include "soc/soc.h" #include "soc/touch_sensor_caps.h" #include "sdkconfig.h" #include "esp_attr.h" diff --git a/components/soc/soc/esp32s2/include/soc/rtc.h b/components/soc/soc/esp32s2/include/soc/rtc.h index a69be33266..d90804e312 100644 --- a/components/soc/soc/esp32s2/include/soc/rtc.h +++ b/components/soc/soc/esp32s2/include/soc/rtc.h @@ -687,14 +687,6 @@ typedef struct { void rtc_sleep_init(rtc_sleep_config_t cfg); -/** - * @brief Set target value of RTC counter for RTC_TIMER_TRIG_EN wakeup source - * @param t value of RTC counter at which wakeup from sleep will happen; - * only the lower 48 bits are used - */ -void rtc_sleep_set_wakeup_time(uint64_t t); - - #define RTC_EXT0_TRIG_EN BIT(0) //!< EXT0 GPIO wakeup #define RTC_EXT1_TRIG_EN BIT(1) //!< EXT1 GPIO wakeup #define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup (light sleep only) diff --git a/components/soc/src/esp32/include/hal/rtc_cntl_ll.h b/components/soc/src/esp32/include/hal/rtc_cntl_ll.h new file mode 100644 index 0000000000..3c77d4c0cb --- /dev/null +++ b/components/soc/src/esp32/include/hal/rtc_cntl_ll.h @@ -0,0 +1,55 @@ +// Copyright 2020 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 "soc/soc.h" +#include "soc/rtc.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t) +{ + WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX); + WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32); +} + +static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void) +{ + REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); +} + +static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void) +{ + return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); +} + +static inline void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +{ + REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask); + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + mode, RTC_CNTL_EXT_WAKEUP1_LV_S); +} + +static inline void rtc_cntl_ll_ulp_wakeup_enable(void) +{ + SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_WAKEUP_FORCE_EN); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/esp32/include/hal/rtc_io_ll.h b/components/soc/src/esp32/include/hal/rtc_io_ll.h index 07ecad5647..3a404299b6 100644 --- a/components/soc/src/esp32/include/hal/rtc_io_ll.h +++ b/components/soc/src/esp32/include/hal/rtc_io_ll.h @@ -353,6 +353,14 @@ static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num) CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpsel); } +static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level) +{ + REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtcio_num); + // Set level which will trigger wakeup + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + level , RTC_CNTL_EXT_WAKEUP0_LV_S); +} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/components/soc/src/esp32/include/hal/soc_ll.h b/components/soc/src/esp32/include/hal/soc_ll.h index b83a0756bc..93f4bbf640 100644 --- a/components/soc/src/esp32/include/hal/soc_ll.h +++ b/components/soc/src/esp32/include/hal/soc_ll.h @@ -16,6 +16,7 @@ #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "soc/soc_caps.h" +#include "soc/rtc.h" #ifdef __cplusplus extern "C" { diff --git a/components/soc/src/esp32s2/include/hal/rtc_cntl_ll.h b/components/soc/src/esp32s2/include/hal/rtc_cntl_ll.h new file mode 100644 index 0000000000..47bb21953e --- /dev/null +++ b/components/soc/src/esp32s2/include/hal/rtc_cntl_ll.h @@ -0,0 +1,58 @@ +// Copyright 2020 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 "soc/soc.h" +#include "soc/rtc.h" +#include "soc/rtc_cntl_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t) +{ + WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX); + WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32); + + SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR_M); + SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M); +} + +static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void) +{ + return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); +} + +static inline void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +{ + REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask); + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + mode, RTC_CNTL_EXT_WAKEUP1_LV_S); +} + +static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void) +{ + REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); +} + +static inline void rtc_cntl_ll_ulp_wakeup_enable(void) +{ + SET_PERI_REG_BITS(RTC_CNTL_STATE0_REG, RTC_CNTL_WAKEUP_ENA_V, 0x800, RTC_CNTL_WAKEUP_ENA_S); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/esp32s2/include/hal/rtc_io_ll.h b/components/soc/src/esp32s2/include/hal/rtc_io_ll.h index bce105496b..c687915ec0 100644 --- a/components/soc/src/esp32s2/include/hal/rtc_io_ll.h +++ b/components/soc/src/esp32s2/include/hal/rtc_io_ll.h @@ -354,6 +354,14 @@ static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num) CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpsel); } +static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level) +{ + REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtcio_num); + // Set level which will trigger wakeup + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + level , RTC_CNTL_EXT_WAKEUP0_LV_S); +} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/components/soc/src/esp32s2/include/hal/soc_ll.h b/components/soc/src/esp32s2/include/hal/soc_ll.h index e61651581e..e195c93574 100644 --- a/components/soc/src/esp32s2/include/hal/soc_ll.h +++ b/components/soc/src/esp32s2/include/hal/soc_ll.h @@ -16,6 +16,7 @@ #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "soc/soc_caps.h" +#include "soc/rtc.h" #ifdef __cplusplus extern "C" { diff --git a/components/soc/src/esp32s3/include/hal/rtc_cntl_ll.h b/components/soc/src/esp32s3/include/hal/rtc_cntl_ll.h new file mode 100644 index 0000000000..47bb21953e --- /dev/null +++ b/components/soc/src/esp32s3/include/hal/rtc_cntl_ll.h @@ -0,0 +1,58 @@ +// Copyright 2020 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 "soc/soc.h" +#include "soc/rtc.h" +#include "soc/rtc_cntl_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void rtc_cntl_ll_set_wakeup_timer(uint64_t t) +{ + WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX); + WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32); + + SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR_M); + SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M); +} + +static inline uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void) +{ + return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); +} + +static inline void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t mask, int mode) +{ + REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, mask); + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + mode, RTC_CNTL_EXT_WAKEUP1_LV_S); +} + +static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void) +{ + REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); +} + +static inline void rtc_cntl_ll_ulp_wakeup_enable(void) +{ + SET_PERI_REG_BITS(RTC_CNTL_STATE0_REG, RTC_CNTL_WAKEUP_ENA_V, 0x800, RTC_CNTL_WAKEUP_ENA_S); +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/soc/src/esp32s3/include/hal/rtc_io_ll.h b/components/soc/src/esp32s3/include/hal/rtc_io_ll.h index 04de23eb49..ebb83ba659 100644 --- a/components/soc/src/esp32s3/include/hal/rtc_io_ll.h +++ b/components/soc/src/esp32s3/include/hal/rtc_io_ll.h @@ -55,12 +55,14 @@ typedef enum { static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func) { if (func == RTCIO_FUNC_RTC) { + SENS.sar_io_mux_conf.iomux_clk_gate_en = 1; // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux)); //0:RTC FUNCTION 1,2,3:Reserved SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, SOC_PIN_FUNC_RTC_IO, rtc_io_desc[rtcio_num].func); } else if (func == RTCIO_FUNC_DIGITAL) { CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux)); + SENS.sar_io_mux_conf.iomux_clk_gate_en = 0; } } @@ -352,6 +354,14 @@ static inline void rtcio_ll_disable_sleep_setting(gpio_num_t gpio_num) CLEAR_PERI_REG_MASK(rtc_io_desc[gpio_num].reg, rtc_io_desc[gpio_num].slpsel); } +static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level) +{ + REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtcio_num); + // Set level which will trigger wakeup + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + level , RTC_CNTL_EXT_WAKEUP0_LV_S); +} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/components/soc/src/esp32s3/include/hal/soc_ll.h b/components/soc/src/esp32s3/include/hal/soc_ll.h index b83a0756bc..93f4bbf640 100644 --- a/components/soc/src/esp32s3/include/hal/soc_ll.h +++ b/components/soc/src/esp32s3/include/hal/soc_ll.h @@ -16,6 +16,7 @@ #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "soc/soc_caps.h" +#include "soc/rtc.h" #ifdef __cplusplus extern "C" { diff --git a/components/soc/src/hal/soc_hal.c b/components/soc/src/hal/soc_hal.c index c01ab3e628..b0c6304faf 100644 --- a/components/soc/src/hal/soc_hal.c +++ b/components/soc/src/hal/soc_hal.c @@ -19,7 +19,9 @@ #include "hal/soc_hal.h" #include "hal/soc_ll.h" +#include "hal/rtc_cntl_ll.h" #include "soc/soc_caps.h" +#include "soc/rtc.h" #if SOC_CPU_CORES_NUM > 1 void soc_hal_stall_core(int core) From 4f5135030f42d9a794c8dd4d19ae60bc2eca7ef8 Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Mon, 4 May 2020 18:17:06 +0800 Subject: [PATCH 4/7] esp_system: remove register level operations for timer wakeup --- components/esp_system/sleep_modes.c | 40 +++++++++++++++----------- components/soc/src/esp32/rtc_sleep.c | 5 ++-- components/soc/src/esp32s2/rtc_sleep.c | 5 ++-- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index c8f64c9218..6127c136bc 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -21,32 +21,41 @@ #include "esp_private/esp_timer_private.h" #include "esp_log.h" #include "esp_newlib.h" -#include "soc/cpu.h" -#include "soc/rtc.h" -#include "soc/spi_periph.h" -#include "soc/dport_reg.h" -#include "soc/soc_memory_layout.h" -#include "hal/wdt_hal.h" -#include "driver/rtc_io.h" -#include "driver/uart.h" -#include "driver/touch_sensor_common.h" +#include "esp_timer.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "driver/touch_sensor.h" +#include "driver/touch_sensor_common.h" +#include "driver/rtc_io.h" +#include "driver/uart.h" + +#include "soc/cpu.h" +#include "soc/rtc.h" +#include "soc/dport_reg.h" #include "soc/uart_caps.h" + +#include "hal/wdt_hal.h" +#include "hal/rtc_io_hal.h" +#include "hal/rtc_hal.h" +#include "hal/uart_hal.h" +#include "hal/touch_sensor_hal.h" #include "hal/clk_gate_ll.h" + #include "sdkconfig.h" #include "esp_rom_uart.h" #ifdef CONFIG_IDF_TARGET_ESP32 #include "esp32/rom/cache.h" -#include "esp32/rom/rtc.h" #include "esp32/clk.h" +#include "esp32/rom/rtc.h" +#include "esp32/rom/uart.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/clk.h" #include "esp32s2/rom/cache.h" #include "esp32s2/rom/rtc.h" #include "esp32s2/rom/ets_sys.h" #include "soc/extmem_reg.h" +#include "esp32s2/rom/uart.h" #endif // If light sleep time is less than that, don't power down flash @@ -312,6 +321,8 @@ void IRAM_ATTR esp_deep_sleep_start(void) { // record current RTC time s_config.rtc_ticks_at_sleep_start = rtc_time_get(); + + // record current RTC time esp_sync_counters_rtc_and_frc(); // Configure wake stub if (esp_get_deep_sleep_wake_stub() == NULL) { @@ -522,14 +533,9 @@ static void timer_wakeup_prepare(void) if (sleep_duration < 0) { sleep_duration = 0; } - int64_t rtc_count_delta = rtc_time_us_to_slowclk(sleep_duration, period); - rtc_sleep_set_wakeup_time(s_config.rtc_ticks_at_sleep_start + rtc_count_delta); - -#ifdef CONFIG_IDF_TARGET_ESP32S2 - SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR_M); - SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN_M); -#endif + int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, period); + rtc_hal_set_wakeup_timer(s_config.rtc_ticks_at_sleep_start + ticks); } diff --git a/components/soc/src/esp32/rtc_sleep.c b/components/soc/src/esp32/rtc_sleep.c index 86ec8e7423..d1db52fc42 100644 --- a/components/soc/src/esp32/rtc_sleep.c +++ b/components/soc/src/esp32/rtc_sleep.c @@ -23,6 +23,8 @@ #include "soc/nrx_reg.h" #include "soc/fe_reg.h" #include "soc/rtc.h" +#include "esp32/rom/ets_sys.h" +#include "hal/rtc_cntl_ll.h" #define MHZ (1000000) @@ -218,8 +220,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) void rtc_sleep_set_wakeup_time(uint64_t t) { - WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX); - WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32); + rtc_cntl_ll_set_wakeup_timer(t); } uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt) diff --git a/components/soc/src/esp32s2/rtc_sleep.c b/components/soc/src/esp32s2/rtc_sleep.c index 9ed548eaf5..f212654bcc 100644 --- a/components/soc/src/esp32s2/rtc_sleep.c +++ b/components/soc/src/esp32s2/rtc_sleep.c @@ -25,6 +25,8 @@ #include "soc/nrx_reg.h" #include "soc/fe_reg.h" #include "soc/rtc.h" +#include "esp32s2/rom/ets_sys.h" +#include "hal/rtc_cntl_ll.h" /** * Configure whether certain peripherals are powered down in deep sleep @@ -126,8 +128,7 @@ void rtc_sleep_init(rtc_sleep_config_t cfg) void rtc_sleep_set_wakeup_time(uint64_t t) { - WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX); - WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32); + rtc_cntl_ll_set_wakeup_timer(t); } uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu) From fe65bf00b16fdb5315023e88bbfeacd4f360fe4a Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Mon, 27 Apr 2020 14:01:30 +0800 Subject: [PATCH 5/7] esp_system: use ext0, ext1, ulp wakeup prepare hal --- components/esp_system/sleep_modes.c | 49 +++++++++++------------------ 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index 6127c136bc..50f86840cb 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -269,7 +269,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) #ifdef CONFIG_IDF_TARGET_ESP32 // Enable ULP wakeup if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) { - SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_WAKEUP_FORCE_EN); + rtc_hal_ulp_wakeup_enable(); } #endif @@ -500,7 +500,7 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) esp_err_t esp_sleep_enable_ulp_wakeup(void) { -#ifdef CONFIG_IDF_TARGET_ESP32 +#if CONFIG_IDF_TARGET_ESP32 #ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT return ESP_ERR_NOT_SUPPORTED; #endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT @@ -515,7 +515,8 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void) return ESP_ERR_INVALID_STATE; #endif // CONFIG_ESP32_ULP_COPROC_ENABLED #elif CONFIG_IDF_TARGET_ESP32S2 - return ESP_ERR_NOT_SUPPORTED; + s_config.wakeup_triggers |= (RTC_ULP_TRIG_EN | RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); + return ESP_OK; #endif } @@ -597,16 +598,9 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) static void ext0_wakeup_prepare(void) { int rtc_gpio_num = s_config.ext0_rtc_gpio_num; - // Set GPIO to be used for wakeup - REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtc_gpio_num); - // Set level which will trigger wakeup - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - s_config.ext0_trigger_level, RTC_CNTL_EXT_WAKEUP0_LV_S); - // Find GPIO descriptor in the rtc_io_desc table and configure the pad - const rtc_io_desc_t* desc = &rtc_io_desc[rtc_gpio_num]; - REG_SET_BIT(desc->reg, desc->mux); - SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); - REG_SET_BIT(desc->reg, desc->ie); + rtcio_hal_ext0_set_wakeup_pin(rtc_gpio_num, s_config.ext0_trigger_level); + rtcio_hal_function_select(rtc_gpio_num, RTCIO_FUNC_RTC); + rtcio_hal_input_enable(rtc_gpio_num); } esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode) @@ -641,35 +635,28 @@ static void ext1_wakeup_prepare(void) if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) { continue; } - const rtc_io_desc_t* desc = &rtc_io_desc[rtc_pin]; // Route pad to RTC - REG_SET_BIT(desc->reg, desc->mux); - SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); + rtcio_hal_function_select(rtc_pin, RTCIO_FUNC_RTC); // set input enable in sleep mode - REG_SET_BIT(desc->reg, desc->ie); + rtcio_hal_input_enable(rtc_pin); + // Pad configuration depends on RTC_PERIPH state in sleep mode if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { // RTC_PERIPH will be powered down, so RTC_IO_ registers will // loose their state. Lock pad configuration. // Pullups/pulldowns also need to be disabled. - REG_CLR_BIT(desc->reg, desc->pulldown); - REG_CLR_BIT(desc->reg, desc->pullup); -#ifdef CONFIG_IDF_TARGET_ESP32 - REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold_force); -#elif CONFIG_IDF_TARGET_ESP32S2 - REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, desc->hold_force); -#endif + rtcio_hal_pullup_disable(rtc_pin); + rtcio_hal_pulldown_disable(rtc_pin); + rtcio_hal_hold_enable(rtc_pin); } // Keep track of pins which are processed to bail out early rtc_gpio_mask &= ~BIT(rtc_pin); } + // Clear state from previous wakeup - REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); - // Set pins to be used for wakeup - REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, s_config.ext1_rtc_gpio_mask); - // Set logic function (any low, all high) - SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, - s_config.ext1_trigger_mode, RTC_CNTL_EXT_WAKEUP1_LV_S); + rtc_hal_ext1_clear_wakeup_pins(); + // Set RTC IO pins and mode (any high, all low) to be used for wakeup + rtc_hal_ext1_set_wakeup_pins(s_config.ext1_rtc_gpio_mask, s_config.ext1_trigger_mode); } uint64_t esp_sleep_get_ext1_wakeup_status(void) @@ -677,7 +664,7 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void) 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); + uint32_t status = rtc_hal_ext1_get_wakeup_pins(); // Translate bit map of RTC IO numbers into the bit map of GPIO numbers uint64_t gpio_mask = 0; for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { From 0db3edd4902d12d02f8e79cf2697f19e90db3806 Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Tue, 5 May 2020 13:21:29 +0800 Subject: [PATCH 6/7] esp32: move sleep test to esp_system --- components/esp_system/test/CMakeLists.txt | 3 +++ components/esp_system/test/component.mk | 5 +++++ components/{esp32 => esp_system}/test/test_sleep.c | 14 +++++++++++--- tools/unit-test-app/configs/default | 2 +- tools/unit-test-app/configs/default_2 | 2 +- tools/unit-test-app/configs/default_2_s2 | 2 +- tools/unit-test-app/configs/default_s2_1 | 2 +- tools/unit-test-app/configs/freertos_compliance_s2 | 2 +- tools/unit-test-app/configs/psram | 2 +- tools/unit-test-app/configs/psram_2 | 2 +- tools/unit-test-app/configs/release | 2 +- tools/unit-test-app/configs/release_2 | 2 +- tools/unit-test-app/configs/release_2_s2 | 2 +- tools/unit-test-app/configs/release_s2 | 2 +- tools/unit-test-app/configs/single_core | 2 +- tools/unit-test-app/configs/single_core_2 | 2 +- tools/unit-test-app/configs/single_core_2_s2 | 2 +- tools/unit-test-app/configs/single_core_s2 | 2 +- 18 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 components/esp_system/test/CMakeLists.txt create mode 100644 components/esp_system/test/component.mk rename components/{esp32 => esp_system}/test/test_sleep.c (98%) diff --git a/components/esp_system/test/CMakeLists.txt b/components/esp_system/test/CMakeLists.txt new file mode 100644 index 0000000000..aff56d67ca --- /dev/null +++ b/components/esp_system/test/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRC_DIRS . + PRIV_INCLUDE_DIRS . + PRIV_REQUIRES unity test_utils) \ No newline at end of file diff --git a/components/esp_system/test/component.mk b/components/esp_system/test/component.mk new file mode 100644 index 0000000000..5dd172bdb7 --- /dev/null +++ b/components/esp_system/test/component.mk @@ -0,0 +1,5 @@ +# +#Component Makefile +# + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/esp32/test/test_sleep.c b/components/esp_system/test/test_sleep.c similarity index 98% rename from components/esp32/test/test_sleep.c rename to components/esp_system/test/test_sleep.c index 6fdea61bf5..9113287eaf 100644 --- a/components/esp32/test/test_sleep.c +++ b/components/esp_system/test/test_sleep.c @@ -2,7 +2,6 @@ #include #include #include "esp_sleep.h" -#include "esp32/clk.h" #include "driver/rtc_io.h" #include "esp_rom_uart.h" #include "freertos/FreeRTOS.h" @@ -14,13 +13,22 @@ #include "soc/rtc.h" // for wakeup trigger defines #include "soc/rtc_periph.h" // for read rtc registers directly (cause) #include "soc/soc.h" // for direct register read macros -#include "esp32/rom/rtc.h" +#include "hal/rtc_cntl_ll.h" #include "esp_newlib.h" #include "test_utils.h" #include "sdkconfig.h" #include "esp_rom_sys.h" +#if CONFIG_IDF_TARGET_ESP32 +#include "esp32/clk.h" +#include "esp32/rom/rtc.h" +#elif CONFIG_IDF_TARGET_ESP32S2 +#include "esp32s2/clk.h" +#include "esp32s2/rom/rtc.h" +#endif + + #define ESP_EXT0_WAKEUP_LEVEL_LOW 0 #define ESP_EXT0_WAKEUP_LEVEL_HIGH 1 @@ -127,7 +135,7 @@ TEST_CASE("light sleep stress test with periodic esp_timer", "[deepsleep]") } -#ifdef CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS +#if defined(CONFIG_ESP_SYSTEM_RTC_EXT_XTAL) #define MAX_SLEEP_TIME_ERROR_US 200 #else #define MAX_SLEEP_TIME_ERROR_US 100 diff --git a/tools/unit-test-app/configs/default b/tools/unit-test-app/configs/default index 390400d277..28a89faba7 100644 --- a/tools/unit-test-app/configs/default +++ b/tools/unit-test-app/configs/default @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_COMPONENTS=freertos esp32 esp_ipc esp_timer driver heap pthread soc spi_flash vfs \ No newline at end of file +TEST_COMPONENTS=freertos esp32 esp_ipc esp_system esp_timer driver heap pthread soc spi_flash vfs diff --git a/tools/unit-test-app/configs/default_2 b/tools/unit-test-app/configs/default_2 index 416badb565..60c41dda13 100644 --- a/tools/unit-test-app/configs/default_2 +++ b/tools/unit-test-app/configs/default_2 @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_ipc esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_ipc esp_system esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component diff --git a/tools/unit-test-app/configs/default_2_s2 b/tools/unit-test-app/configs/default_2_s2 index a99b0e083f..97fb925f23 100644 --- a/tools/unit-test-app/configs/default_2_s2 +++ b/tools/unit-test-app/configs/default_2_s2 @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_timer driver heap pthread soc spi_flash vfs experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_system esp_timer driver heap pthread soc spi_flash vfs experimental_cpp_component diff --git a/tools/unit-test-app/configs/default_s2_1 b/tools/unit-test-app/configs/default_s2_1 index 41177c52bd..06d7613e2a 100644 --- a/tools/unit-test-app/configs/default_s2_1 +++ b/tools/unit-test-app/configs/default_s2_1 @@ -1,3 +1,3 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap \ No newline at end of file +TEST_COMPONENTS=freertos esp32s2 esp_system esp_timer driver heap diff --git a/tools/unit-test-app/configs/freertos_compliance_s2 b/tools/unit-test-app/configs/freertos_compliance_s2 index afb0ccb316..5e33aa7992 100644 --- a/tools/unit-test-app/configs/freertos_compliance_s2 +++ b/tools/unit-test-app/configs/freertos_compliance_s2 @@ -1,4 +1,4 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_COMPONENTS=driver esp32s2 esp_timer spi_flash +TEST_COMPONENTS=driver esp32s2 esp_system esp_timer spi_flash CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y diff --git a/tools/unit-test-app/configs/psram b/tools/unit-test-app/configs/psram index d7b5876d99..ce3bf964a7 100644 --- a/tools/unit-test-app/configs/psram +++ b/tools/unit-test-app/configs/psram @@ -1,5 +1,5 @@ CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update driver esp32 esp_ipc esp_timer mbedtls spi_flash test_utils heap pthread soc experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update driver esp32 esp_ipc esp_system esp_timer mbedtls spi_flash test_utils heap pthread soc experimental_cpp_component CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_SPIRAM_OCCUPY_NO_HOST=y diff --git a/tools/unit-test-app/configs/psram_2 b/tools/unit-test-app/configs/psram_2 index 36551e04b6..867006f3f7 100644 --- a/tools/unit-test-app/configs/psram_2 +++ b/tools/unit-test-app/configs/psram_2 @@ -1,5 +1,5 @@ CONFIG_IDF_TARGET="esp32" -TEST_COMPONENTS=esp32 esp_ipc esp_timer mbedtls spi_flash heap pthread soc +TEST_COMPONENTS=esp32 esp_ipc esp_system esp_timer mbedtls spi_flash heap pthread soc CONFIG_ESP32_SPIRAM_SUPPORT=y CONFIG_ESP_INT_WDT_TIMEOUT_MS=800 CONFIG_SPIRAM_OCCUPY_NO_HOST=y diff --git a/tools/unit-test-app/configs/release b/tools/unit-test-app/configs/release index 40d835983f..074d867ffe 100644 --- a/tools/unit-test-app/configs/release +++ b/tools/unit-test-app/configs/release @@ -1,5 +1,5 @@ CONFIG_IDF_TARGET="esp32" -TEST_COMPONENTS=freertos esp32 esp_ipc esp_timer driver heap pthread soc spi_flash vfs +TEST_COMPONENTS=freertos esp32 esp_system esp_ipc esp_timer driver heap pthread soc spi_flash vfs CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/tools/unit-test-app/configs/release_2 b/tools/unit-test-app/configs/release_2 index a2d90b290b..aa232643c7 100644 --- a/tools/unit-test-app/configs/release_2 +++ b/tools/unit-test-app/configs/release_2 @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_ipc esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_ipc esp_system esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/tools/unit-test-app/configs/release_2_s2 b/tools/unit-test-app/configs/release_2_s2 index ae624b14ba..1fd6337f19 100644 --- a/tools/unit-test-app/configs/release_2_s2 +++ b/tools/unit-test-app/configs/release_2_s2 @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_system esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/tools/unit-test-app/configs/release_s2 b/tools/unit-test-app/configs/release_s2 index 2df70fef8c..06adf282b2 100644 --- a/tools/unit-test-app/configs/release_s2 +++ b/tools/unit-test-app/configs/release_s2 @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_COMPONENTS=freertos esp32s2 esp_timer driver heap pthread soc spi_flash vfs +TEST_COMPONENTS=freertos esp32s2 esp_system esp_timer driver heap pthread soc spi_flash vfs CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/tools/unit-test-app/configs/single_core b/tools/unit-test-app/configs/single_core index 5e9a50491a..2967da2efa 100644 --- a/tools/unit-test-app/configs/single_core +++ b/tools/unit-test-app/configs/single_core @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_COMPONENTS=freertos esp32 esp_timer driver heap pthread soc spi_flash vfs +TEST_COMPONENTS=freertos esp32 esp_system esp_timer driver heap pthread soc spi_flash vfs CONFIG_MEMMAP_SMP=n CONFIG_FREERTOS_UNICORE=y CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY=y diff --git a/tools/unit-test-app/configs/single_core_2 b/tools/unit-test-app/configs/single_core_2 index a1a173e4da..2201584c71 100644 --- a/tools/unit-test-app/configs/single_core_2 +++ b/tools/unit-test-app/configs/single_core_2 @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32" -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_ipc esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32 esp_system esp_ipc esp_timer driver heap pthread soc spi_flash vfs test_utils experimental_cpp_component CONFIG_MEMMAP_SMP=n CONFIG_FREERTOS_UNICORE=y CONFIG_ESP32_RTCDATA_IN_FAST_MEM=y diff --git a/tools/unit-test-app/configs/single_core_2_s2 b/tools/unit-test-app/configs/single_core_2_s2 index 9cf2ed8ed4..e953927e4c 100644 --- a/tools/unit-test-app/configs/single_core_2_s2 +++ b/tools/unit-test-app/configs/single_core_2_s2 @@ -1,6 +1,6 @@ # This config is split between targets since different component needs to be excluded (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_timer driver heap pthread soc spi_flash vfs experimental_cpp_component +TEST_EXCLUDE_COMPONENTS=libsodium bt app_update freertos esp32s2 esp_ipc esp_system esp_timer driver heap pthread soc spi_flash vfs experimental_cpp_component CONFIG_MEMMAP_SMP=n CONFIG_FREERTOS_UNICORE=y CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y diff --git a/tools/unit-test-app/configs/single_core_s2 b/tools/unit-test-app/configs/single_core_s2 index 5b47520d6c..783edfd8c3 100644 --- a/tools/unit-test-app/configs/single_core_s2 +++ b/tools/unit-test-app/configs/single_core_s2 @@ -1,4 +1,4 @@ # This config is split between targets since different component needs to be included (esp32, esp32s2) CONFIG_IDF_TARGET="esp32s2" -TEST_COMPONENTS=esp32s2 esp_timer driver heap soc spi_flash test_utils +TEST_COMPONENTS=esp32s2 esp_system esp_timer driver heap soc spi_flash test_utils CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y From 3f6e366f5691f7d97ab295a23dc9a06f308234a0 Mon Sep 17 00:00:00 2001 From: Renz Bagaporo Date: Sun, 10 May 2020 16:18:50 +0800 Subject: [PATCH 7/7] esp_system: force RTC_SLEEP_PD_XTAL on ESP32 via get pdflags Based on the original code (`esp32/sleep_modes.c`), `RTC_SLEEP_PD_XTAL` is always given as an argument to `esp_sleep_start`. Enforce this in function to get power down flags to avoid redundancy. --- components/esp_system/sleep_modes.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index 50f86840cb..4d16a19913 100644 --- a/components/esp_system/sleep_modes.c +++ b/components/esp_system/sleep_modes.c @@ -336,11 +336,7 @@ void IRAM_ATTR esp_deep_sleep_start(void) s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US; // Enter sleep -#ifdef CONFIG_IDF_TARGET_ESP32 - esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | RTC_SLEEP_PD_XTAL | pd_flags); -#elif CONFIG_IDF_TARGET_ESP32S2 esp_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags); -#endif // Because RTC is in a slower clock domain than the CPU, it // can take several CPU cycles for the sleep mode to start. @@ -825,15 +821,13 @@ static uint32_t get_power_down_flags(void) } #ifdef CONFIG_IDF_TARGET_ESP32 - if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_XTAL; - } + pd_flags |= RTC_SLEEP_PD_XTAL; +#endif +#if ((defined CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT)) if ((s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) == 0) { // If enabled EXT1 only and enable the additional current by touch, should be keep RTC_PERIPH power on. -#if ((defined CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT)) - pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; -#endif + pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; } #endif