Ver código fonte

Merge branch 'feature/support_sleep_for_esp32c2' into 'master'

esp32c2: support power management

Closes IDF-4440 and IDF-4617

See merge request espressif/esp-idf!18174
Jiang Jiang Jian 3 anos atrás
pai
commit
2bc5d58807

+ 3 - 1
components/bootloader/Kconfig.projbuild

@@ -323,7 +323,7 @@ menu "Bootloader config"
         # options, allowing to turn on "allow insecure options" and have secure boot with
         # "skip validation when existing deep sleep". Keeping this to avoid a breaking change,
         # but - as noted in help - it invalidates the integrity of Secure Boot checks
-        depends on (SECURE_BOOT && SECURE_BOOT_INSECURE) || !SECURE_BOOT
+        depends on SOC_RTC_FAST_MEM_SUPPORTED && ((SECURE_BOOT && SECURE_BOOT_INSECURE) || !SECURE_BOOT)
         default n
         help
             This option disables the normal validation of an image coming out of
@@ -379,6 +379,7 @@ menu "Bootloader config"
 
     config BOOTLOADER_RESERVE_RTC_SIZE
         hex
+        depends on SOC_RTC_FAST_MEM_SUPPORTED
         default 0x10 if BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP || BOOTLOADER_CUSTOM_RESERVE_RTC
         default 0
         help
@@ -390,6 +391,7 @@ menu "Bootloader config"
 
     config BOOTLOADER_CUSTOM_RESERVE_RTC
         bool "Reserve RTC FAST memory for custom purposes"
+        depends on SOC_RTC_FAST_MEM_SUPPORTED
         default n
         help
             This option allows the customer to place data in the RTC FAST memory,

+ 6 - 1
components/bootloader_support/src/bootloader_common.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -21,6 +21,7 @@
 #include "soc/gpio_periph.h"
 #include "soc/rtc.h"
 #include "soc/efuse_reg.h"
+#include "soc/soc_caps.h"
 #include "hal/gpio_ll.h"
 #include "esp_image_format.h"
 #include "bootloader_sha.h"
@@ -195,6 +196,7 @@ RESET_REASON bootloader_common_get_reset_reason(int cpu_no)
 
 uint8_t bootloader_flash_get_cs_io(void)
 {
+#if SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
     uint8_t cs_io;
     const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info();
     if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) {
@@ -203,4 +205,7 @@ uint8_t bootloader_flash_get_cs_io(void)
         cs_io = (spiconfig >> 18) & 0x3f;
     }
     return cs_io;
+#else
+    return SPI_CS0_GPIO_NUM;
+#endif
 }

+ 2 - 2
components/esp_hw_support/include/esp_sleep.h

@@ -40,10 +40,10 @@ typedef enum {
 #if SOC_PM_SUPPORT_RTC_PERIPH_PD
     ESP_PD_DOMAIN_RTC_PERIPH,      //!< RTC IO, sensors and ULP co-processor
 #endif
-#if SOC_RTC_SLOW_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
     ESP_PD_DOMAIN_RTC_SLOW_MEM,    //!< RTC slow memory
 #endif
-#if SOC_RTC_FAST_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
     ESP_PD_DOMAIN_RTC_FAST_MEM,    //!< RTC fast memory
 #endif
     ESP_PD_DOMAIN_XTAL,            //!< XTAL oscillator

+ 8 - 0
components/esp_hw_support/port/esp32c2/rtc_clk.c

@@ -19,6 +19,8 @@
 #include "soc/efuse_reg.h"
 #include "soc/syscon_reg.h"
 #include "soc/system_reg.h"
+#include "soc/io_mux_reg.h"
+#include "soc/soc.h"
 #include "regi2c_ctrl.h"
 #include "regi2c_bbpll.h"
 #include "esp_hw_log.h"
@@ -35,6 +37,12 @@ static int s_cur_pll_freq;
 
 static void rtc_clk_cpu_freq_to_8m(void);
 
+void rtc_clk_32k_enable_external(void)
+{
+    REG_SET_BIT(PERIPHS_IO_MUX_XTAL_32K_P_U, FUN_IE);
+    REG_SET_BIT(RTC_CNTL_PAD_HOLD_REG, RTC_CNTL_GPIO_PIN0_HOLD);
+}
+
 void rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
 {
     if (clk_8m_en) {

+ 30 - 10
components/esp_hw_support/sleep_modes.c

@@ -101,8 +101,8 @@
 #define DEFAULT_SLEEP_OUT_OVERHEAD_US       (105)
 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US    (37)
 #elif CONFIG_IDF_TARGET_ESP32C2
-#define DEFAULT_SLEEP_OUT_OVERHEAD_US       (105)
-#define DEFAULT_HARDWARE_OUT_OVERHEAD_US    (37)
+#define DEFAULT_SLEEP_OUT_OVERHEAD_US       (118)
+#define DEFAULT_HARDWARE_OUT_OVERHEAD_US    (9)
 #endif
 
 #define LIGHT_SLEEP_TIME_OVERHEAD_US        DEFAULT_HARDWARE_OUT_OVERHEAD_US
@@ -156,10 +156,10 @@ static sleep_config_t s_config = {
 #if SOC_PM_SUPPORT_RTC_PERIPH_PD
         ESP_PD_OPTION_AUTO,
 #endif
-#if SOC_RTC_SLOW_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
         ESP_PD_OPTION_AUTO,
 #endif
-#if SOC_RTC_FAST_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
         ESP_PD_OPTION_AUTO,
 #endif
         ESP_PD_OPTION_AUTO,
@@ -1157,6 +1157,26 @@ esp_err_t esp_sleep_disable_wifi_wakeup(void)
 #endif
 }
 
+esp_err_t esp_sleep_enable_bt_wakeup(void)
+{
+#if SOC_PM_SUPPORT_BT_WAKEUP
+    s_config.wakeup_triggers |= RTC_BT_TRIG_EN;
+    return ESP_OK;
+#else
+    return ESP_ERR_NOT_SUPPORTED;
+#endif
+}
+
+esp_err_t esp_sleep_disable_bt_wakeup(void)
+{
+#if SOC_PM_SUPPORT_BT_WAKEUP
+    s_config.wakeup_triggers &= (~RTC_BT_TRIG_EN);
+    return ESP_OK;
+#else
+    return ESP_ERR_NOT_SUPPORTED;
+#endif
+}
+
 esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
 {
     if (esp_rom_get_reset_reason(0) != RESET_REASON_CORE_DEEP_SLEEP && !s_light_sleep_wakeup) {
@@ -1227,7 +1247,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.
 
-#if SOC_RTC_SLOW_MEM_SUPPORTED && SOC_ULP_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD && SOC_ULP_SUPPORTED
     // Labels are defined in the linker script
     extern int _rtc_slow_length;
     /**
@@ -1242,7 +1262,7 @@ static uint32_t get_power_down_flags(void)
     }
 #endif
 
-#if SOC_RTC_FAST_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
 #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP
     /* 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.
@@ -1298,21 +1318,21 @@ static uint32_t get_power_down_flags(void)
 #if SOC_PM_SUPPORT_RTC_PERIPH_PD
     ESP_EARLY_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]]);
 #endif
-#if SOC_RTC_SLOW_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
     ESP_EARLY_LOGD(TAG, "RTC_SLOW_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]]);
 #endif
-#if SOC_RTC_FAST_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
     ESP_EARLY_LOGD(TAG, "RTC_FAST_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]);
 #endif
 
     // Prepare flags based on the selected options
     uint32_t pd_flags = 0;
-#if SOC_RTC_FAST_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD
     if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) {
         pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM;
     }
 #endif
-#if SOC_RTC_SLOW_MEM_SUPPORTED
+#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
     if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) {
         pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM;
     }

+ 2 - 0
components/esp_system/port/soc/esp32c2/clk.c

@@ -147,6 +147,8 @@ static void select_rtc_slow_clk(slow_clk_sel_t slow_clk)
              * will time out, returning 0.
              */
             ESP_EARLY_LOGD(TAG, "waiting for external clock by pin0 to start up");
+            rtc_clk_32k_enable_external();
+
             // When SLOW_CLK_CAL_CYCLES is set to 0, clock calibration will not be performed at startup.
             if (SLOW_CLK_CAL_CYCLES > 0) {
                 cal_val = rtc_clk_cal(RTC_CAL_EXT_CLK, SLOW_CLK_CAL_CYCLES);

+ 12 - 0
components/soc/esp32/include/soc/Kconfig.soc_caps.in

@@ -579,6 +579,10 @@ config SOC_SPIRAM_SUPPORTED
     bool
     default y
 
+config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
+    bool
+    default y
+
 config SOC_SHA_SUPPORT_PARALLEL_ENG
     bool
     default y
@@ -643,6 +647,14 @@ config SOC_PM_SUPPORT_RTC_PERIPH_PD
     bool
     default y
 
+config SOC_PM_SUPPORT_RTC_FAST_MEM_PD
+    bool
+    default y
+
+config SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
+    bool
+    default y
+
 config SOC_SDMMC_USE_IOMUX
     bool
     default y

+ 7 - 2
components/soc/esp32/include/soc/soc_caps.h

@@ -310,6 +310,9 @@
 /*-------------------------- SPIRAM CAPS -------------------------------------*/
 #define SOC_SPIRAM_SUPPORTED    1
 
+/*-------------------------- SPI MEM CAPS ---------------------------------------*/
+#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE         (1)
+
 /*--------------------------- SHA CAPS ---------------------------------------*/
 /* ESP32 style SHA engine, where multiple states can be stored in parallel */
 #define SOC_SHA_SUPPORT_PARALLEL_ENG    (1)
@@ -346,9 +349,11 @@
 #define SOC_PHY_DIG_REGS_MEM_SIZE       (21*4)
 
 /*-------------------------- Power Management CAPS ---------------------------*/
-#define SOC_PM_SUPPORT_EXT_WAKEUP       (1)
+#define SOC_PM_SUPPORT_EXT_WAKEUP                 (1)
 #define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP        (1)     /*!<Supports waking up from touch pad trigger */
-#define SOC_PM_SUPPORT_RTC_PERIPH_PD        (1)
+#define SOC_PM_SUPPORT_RTC_PERIPH_PD              (1)
+#define SOC_PM_SUPPORT_RTC_FAST_MEM_PD            (1)
+#define SOC_PM_SUPPORT_RTC_SLOW_MEM_PD            (1)
 
 /* ---------------------------- Compatibility ------------------------------- */
 #define SOC_CAN_SUPPORTED                   SOC_TWAI_SUPPORTED

+ 5 - 0
components/soc/esp32c2/include/soc/rtc.h

@@ -240,6 +240,11 @@ rtc_xtal_freq_t rtc_clk_xtal_freq_get(void);
  */
 void rtc_clk_xtal_freq_update(rtc_xtal_freq_t xtal_freq);
 
+/**
+ * @brief Enable 32KHz external oscillator
+ */
+void rtc_clk_32k_enable_external(void);
+
 /**
  * @brief Enable or disable 8 MHz internal oscillator
  *

+ 4 - 0
components/soc/esp32c3/include/soc/Kconfig.soc_caps.in

@@ -551,6 +551,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
     bool
     default y
 
+config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
+    bool
+    default y
+
 config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
     bool
     default y

+ 1 - 0
components/soc/esp32c3/include/soc/soc_caps.h

@@ -272,6 +272,7 @@
 #define SOC_SPI_MEM_SUPPORT_IDLE_INTR                     (1)
 #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND                    (1)
 #define SOC_SPI_MEM_SUPPORT_CHECK_SUS                     (1)
+#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE          (1)
 
 #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED         1
 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED         1

+ 4 - 0
components/soc/esp32h2/include/soc/Kconfig.soc_caps.in

@@ -539,6 +539,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS
     bool
     default y
 
+config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
+    bool
+    default y
+
 config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED
     bool
     default y

+ 1 - 0
components/soc/esp32h2/include/soc/soc_caps.h

@@ -280,6 +280,7 @@
 #define SOC_SPI_MEM_SUPPORT_IDLE_INTR                     (1)
 #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND                    (1)
 #define SOC_SPI_MEM_SUPPORT_CHECK_SUS                     (1)
+#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE          (1)
 
 #define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED         1
 #define SOC_MEMSPI_SRC_FREQ_24M_SUPPORTED         1

+ 12 - 0
components/soc/esp32s2/include/soc/Kconfig.soc_caps.in

@@ -803,6 +803,10 @@ config SOC_SPI_MEM_SUPPORT_SW_SUSPEND
     bool
     default y
 
+config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
+    bool
+    default y
+
 config SOC_PM_SUPPORT_EXT_WAKEUP
     bool
     default y
@@ -823,6 +827,14 @@ config SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP
     bool
     default y
 
+config SOC_PM_SUPPORT_RTC_FAST_MEM_PD
+    bool
+    default y
+
+config SOC_PM_SUPPORT_RTC_SLOW_MEM_PD
+    bool
+    default y
+
 config SOC_COEX_HW_PTI
     bool
     default y

+ 8 - 8
components/soc/esp32s2/include/soc/soc_caps.h

@@ -369,16 +369,16 @@
 #define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE                (1)
 #define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND                  (1)
 #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND                    (1)
-/*-------------------------- Power Management CAPS ---------------------------*/
-#define SOC_PM_SUPPORT_EXT_WAKEUP       (1)
-
-#define SOC_PM_SUPPORT_WIFI_WAKEUP      (1)
-
-#define SOC_PM_SUPPORT_WIFI_PD          (1)
-
-#define SOC_PM_SUPPORT_RTC_PERIPH_PD      (1)
+#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE          (1)
 
+/*-------------------------- Power Management CAPS ---------------------------*/
+#define SOC_PM_SUPPORT_EXT_WAKEUP                 (1)
+#define SOC_PM_SUPPORT_WIFI_WAKEUP                (1)
+#define SOC_PM_SUPPORT_WIFI_PD                    (1)
+#define SOC_PM_SUPPORT_RTC_PERIPH_PD              (1)
 #define SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP        (1)     /*!<Supports waking up from touch pad trigger */
+#define SOC_PM_SUPPORT_RTC_FAST_MEM_PD            (1)
+#define SOC_PM_SUPPORT_RTC_SLOW_MEM_PD            (1)
 
 /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/
 #define SOC_COEX_HW_PTI                 (1)

+ 4 - 0
components/soc/esp32s3/include/soc/Kconfig.soc_caps.in

@@ -943,6 +943,10 @@ config SOC_SPI_MEM_SUPPORT_TIME_TUNING
     bool
     default y
 
+config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE
+    bool
+    default y
+
 config SOC_COEX_HW_PTI
     bool
     default y

+ 1 - 0
components/soc/esp32s3/include/soc/soc_caps.h

@@ -400,6 +400,7 @@
 #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND                    (1)
 #define SOC_SPI_MEM_SUPPORT_OPI_MODE                      (1)
 #define SOC_SPI_MEM_SUPPORT_TIME_TUNING                   (1)
+#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE          (1)
 
 /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/
 #define SOC_COEX_HW_PTI                 (1)

+ 5 - 0
examples/wifi/power_save/main/Kconfig.projbuild

@@ -49,8 +49,12 @@ menu "Example Configuration"
 
         config EXAMPLE_MAX_CPU_FREQ_80
             bool "80 MHz"
+        config EXAMPLE_MAX_CPU_FREQ_120
+            bool "120 MHz"
+            depends on IDF_TARGET_ESP32C2
         config EXAMPLE_MAX_CPU_FREQ_160
             bool "160 MHz"
+            depends on !IDF_TARGET_ESP32C2
         config EXAMPLE_MAX_CPU_FREQ_240
             bool "240 MHz"
             depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
@@ -59,6 +63,7 @@ menu "Example Configuration"
     config EXAMPLE_MAX_CPU_FREQ_MHZ
         int
         default 80 if EXAMPLE_MAX_CPU_FREQ_80
+        default 120 if EXAMPLE_MAX_CPU_FREQ_120
         default 160 if EXAMPLE_MAX_CPU_FREQ_160
         default 240 if EXAMPLE_MAX_CPU_FREQ_240
 

+ 2 - 0
examples/wifi/power_save/main/power_save.c

@@ -103,6 +103,8 @@ void app_main(void)
     esp_pm_config_esp32c3_t pm_config = {
 #elif CONFIG_IDF_TARGET_ESP32S3
     esp_pm_config_esp32s3_t pm_config = {
+#elif CONFIG_IDF_TARGET_ESP32C2
+    esp_pm_config_esp32c2_t pm_config = {
 #endif
             .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ,
             .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ,