Răsfoiți Sursa

esp_hw_support: merge C3 changes to master

Merge RTC related C3 changes to master
Marius Vikhammer 5 ani în urmă
părinte
comite
eb788deb03

+ 5 - 1
components/bootloader_support/src/esp32c3/bootloader_esp32c3.c

@@ -261,10 +261,14 @@ static inline void bootloader_hardware_init(void)
     REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12);
 }
 
+/* There happend clock glitch reset for some chip when testing wifi[BIT0] and brownout reset when chip startup[BIT1].
+ * But super_watch_dog_reset function is ok, so open it[BIT2].
+ * Whether this api will deleted or not depends on analog design & test result when ECO chip come back.
+ */
 static inline void bootloader_glitch_reset_disable(void)
 {
     // TODO ESP32-C3 IDF-2453
-    REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, 0);
+    REG_SET_FIELD(RTC_CNTL_FIB_SEL_REG, RTC_CNTL_FIB_SEL, BIT2);
 }
 
 esp_err_t bootloader_init(void)

+ 1 - 1
components/esp_hw_support/port/esp32c3/CMakeLists.txt

@@ -10,7 +10,7 @@ set(srcs "cpu_util_esp32c3.c"
 add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
 
 target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
-target_include_directories(${COMPONENT_LIB} PUBLIC . include)
+target_include_directories(${COMPONENT_LIB} PUBLIC . private_include)
 target_include_directories(${COMPONENT_LIB} PRIVATE ../hal)
 
 if(NOT CMAKE_BUILD_EARLY_EXPANSION)

+ 1 - 2
components/esp_hw_support/port/esp32c3/i2c_rtc_clk.h

@@ -15,8 +15,7 @@
 #pragma once
 
 #include <stdint.h>
-#include "i2c_apll.h"
-#include "i2c_bbpll.h"
+#include "regi2c_ctrl.h"
 
 /* Analog function control register */
 #define ANA_CONFIG_REG  0x6000E044

+ 1 - 1
components/esp_hw_support/port/esp32c3/private_include/regi2c_brownout.h

@@ -23,7 +23,7 @@
  */
 
 #define I2C_BOD            0x61
-#define I2C_BOD_HOSTID     1
+#define I2C_BOD_HOSTID     0
 
 #define I2C_BOD_THRESHOLD           0x5
 #define I2C_BOD_THRESHOLD_MSB       2

+ 8 - 0
components/esp_hw_support/port/esp32c3/private_include/regi2c_lp_bias.h

@@ -41,3 +41,11 @@
 #define I2C_ULP_IR_FORCE_XPD_IPH 0
 #define I2C_ULP_IR_FORCE_XPD_IPH_MSB 4
 #define I2C_ULP_IR_FORCE_XPD_IPH_LSB 4
+
+#define I2C_ULP_IR_FORCE_XPD_CK 0
+#define I2C_ULP_IR_FORCE_XPD_CK_MSB 2
+#define I2C_ULP_IR_FORCE_XPD_CK_LSB 2
+
+#define I2C_ULP_IR_DISABLE_WATCHDOG_CK 0
+#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_MSB 6
+#define I2C_ULP_IR_DISABLE_WATCHDOG_CK_LSB 6

+ 1 - 1
components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h

@@ -24,7 +24,7 @@
  */
 
 #define I2C_SAR_ADC            0X69
-#define I2C_SAR_ADC_HOSTID     1
+#define I2C_SAR_ADC_HOSTID     0
 
 #define ADC_SAR1_ENCAL_GND_ADDR 0x7
 #define ADC_SAR1_ENCAL_GND_ADDR_MSB 5

+ 0 - 6
components/esp_hw_support/port/esp32c3/regi2c_ctrl.h

@@ -48,12 +48,6 @@ extern "C" {
 /* Clear to enable BBPLL */
 #define I2C_BBPLL_M     (BIT(17))
 
-#define SAR_I2C_FORCE_PD BIT(18)
-#define SAR_I2C_FORCE_PU BIT(16)
-
-#define ANA_CONFIG2_REG  0x6000E048
-#define ANA_CONFIG2_M   (BIT(18))
-
 /* ROM functions which read/write internal control bus */
 uint8_t rom_i2c_readReg(uint8_t block, uint8_t host_id, uint8_t reg_add);
 uint8_t rom_i2c_readReg_Mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb);

+ 119 - 139
components/esp_hw_support/port/esp32c3/rtc_clk.c

@@ -28,7 +28,7 @@
 #include "soc/efuse_reg.h"
 #include "soc/syscon_reg.h"
 #include "soc/system_reg.h"
-#include "i2c_rtc_clk.h"
+#include "regi2c_ctrl.h"
 #include "soc_log.h"
 #include "rtc_clk_common.h"
 #include "esp_rom_sys.h"
@@ -55,17 +55,27 @@ void rtc_clk_32k_enable_internal(x32k_config_t cfg)
 
 void rtc_clk_32k_enable(bool enable)
 {
-    abort(); // TODO ESP32-C3  IDF-2408
+    if (enable) {
+        x32k_config_t cfg = X32K_CONFIG_DEFAULT();
+        rtc_clk_32k_enable_internal(cfg);
+    } else {
+        SET_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XTAL32K_XPD_FORCE);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K);
+    }
 }
 
 void rtc_clk_32k_enable_external(void)
 {
-    abort(); // TODO ESP32-C3  IDF-2408
+    /* TODO ESP32-C3 IDF-2408: external 32k source may need different settings */
+    x32k_config_t cfg = X32K_CONFIG_DEFAULT();
+    rtc_clk_32k_enable_internal(cfg);
 }
 
 void rtc_clk_32k_bootstrap(uint32_t cycle)
 {
-    /* No special bootstrapping needed. Just enable the XTAL here. */
+    /* No special bootstrapping needed for ESP32-C3, 'cycle' argument is to keep the signature
+     * same as for the ESP32. Just enable the XTAL here.
+     */
     (void) cycle;
     rtc_clk_32k_enable(true);
 }
@@ -112,32 +122,6 @@ bool rtc_clk_8md256_enabled(void)
     return GET_PERI_REG_MASK(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV) == 0;
 }
 
-void rtc_clk_apll_enable(bool enable, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2, uint32_t o_div)
-{
-    REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD, enable ? 0 : 1);
-    REG_SET_FIELD(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, enable ? 1 : 0);
-
-    if (enable) {
-        I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_DSDM2, sdm2);
-        I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_DSDM0, sdm0);
-        I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_DSDM1, sdm1);
-        I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_1);
-        I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_SDM_STOP, APLL_SDM_STOP_VAL_2_REV1);
-        I2C_WRITEREG_MASK_RTC(I2C_APLL, I2C_APLL_OR_OUTPUT_DIV, o_div);
-
-        /* calibration */
-        I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_1);
-        I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_2);
-        I2C_WRITEREG_RTC(I2C_APLL, I2C_APLL_IR_CAL_DELAY, APLL_CAL_DELAY_3);
-
-        /* wait for calibration end */
-        while (!(I2C_READREG_MASK_RTC(I2C_APLL, I2C_APLL_OR_CAL_END))) {
-            /* use esp_rom_delay_us so the RTC bus doesn't get flooded */
-            esp_rom_delay_us(1);
-        }
-    }
-}
-
 void rtc_clk_set_xtal_wait(void)
 {
     /*
@@ -145,12 +129,10 @@ void rtc_clk_set_xtal_wait(void)
      and `RTC_CNTL_XTL_BUF_WAIT` depend on it.
     */
     rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
-    rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
-    rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
     rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
-    if (slow_clk_freq == (rtc_slow_freq_x32k)) {
+    if (slow_clk_freq == RTC_SLOW_FREQ_32K_XTAL) {
         cal_clk = RTC_CAL_32K_XTAL;
-    } else if (slow_clk_freq == rtc_slow_freq_8MD256) {
+    } else if (slow_clk_freq == RTC_SLOW_FREQ_8MD256) {
         cal_clk  = RTC_CAL_8MD256;
     }
     uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 2000);
@@ -161,6 +143,18 @@ void rtc_clk_set_xtal_wait(void)
     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, xtal_wait_1ms);
 }
 
+static void wait_dig_dbias_valid(uint64_t rtc_cycles)
+{
+    rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
+    rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
+    if (slow_clk_freq == RTC_SLOW_FREQ_32K_XTAL) {
+        cal_clk = RTC_CAL_32K_XTAL;
+    } else if (slow_clk_freq == RTC_SLOW_FREQ_8MD256) {
+        cal_clk = RTC_CAL_8MD256;
+    }
+    rtc_clk_cal(cal_clk, rtc_cycles);
+}
+
 void rtc_clk_slow_freq_set(rtc_slow_freq_t slow_freq)
 {
     REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
@@ -226,55 +220,87 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
     uint8_t dr3;
     uint8_t dchgp;
     uint8_t dcur;
-
-    assert(xtal_freq == RTC_XTAL_FREQ_40M);
+    uint8_t dbias;
 
     if (pll_freq == RTC_PLL_FREQ_480M) {
-        /* Clear this register to let the digital part know 480M PLL is used */
+        /* Set this register to let the digital part know 480M PLL is used */
         SET_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
         /* Configure 480M PLL */
-        div_ref = 0;
-        div7_0 = 8;
-        dr1 = 0;
-        dr3 = 0;
-        dchgp = 5;
-        dcur = 4;
-        I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
+        switch (xtal_freq) {
+        case RTC_XTAL_FREQ_40M:
+            div_ref = 0;
+            div7_0 = 8;
+            dr1 = 0;
+            dr3 = 0;
+            dchgp = 5;
+            dcur = 3;
+            dbias = 2;
+            break;
+        case RTC_XTAL_FREQ_32M:
+            div_ref = 1;
+            div7_0 = 26;
+            dr1 = 1;
+            dr3 = 1;
+            dchgp = 4;
+            dcur = 0;
+            dbias = 2;
+            break;
+        default:
+            div_ref = 0;
+            div7_0 = 8;
+            dr1 = 0;
+            dr3 = 0;
+            dchgp = 5;
+            dcur = 3;
+            dbias = 2;
+            break;
+        }
+        REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6B);
     } else {
         /* Clear this register to let the digital part know 320M PLL is used */
         CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
         /* Configure 320M PLL */
-        div_ref = 0;
-        div7_0 = 4;
-        dr1 = 0;
-        dr3 = 0;
-        dchgp = 5;
-        dcur = 5;
-        I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
+        switch (xtal_freq) {
+        case RTC_XTAL_FREQ_40M:
+            div_ref = 0;
+            div7_0 = 4;
+            dr1 = 0;
+            dr3 = 0;
+            dchgp = 5;
+            dcur = 3;
+            dbias = 2;
+            break;
+        case RTC_XTAL_FREQ_32M:
+            div_ref = 1;
+            div7_0 = 6;
+            dr1 = 0;
+            dr3 = 0;
+            dchgp = 5;
+            dcur = 3;
+            dbias = 2;
+            break;
+        default:
+            div_ref = 0;
+            div7_0 = 4;
+            dr1 = 0;
+            dr3 = 0;
+            dchgp = 5;
+            dcur = 3;
+            dbias = 2;
+            break;
+        }
+        REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
     }
     uint8_t i2c_bbpll_lref  = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
     uint8_t i2c_bbpll_div_7_0 = div7_0;
     uint8_t i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB ) | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
-    I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
-    I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
-    I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
-    I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
-    I2C_WRITEREG_RTC(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
-
-    // Enable calibration by software
-    I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_IR_CAL_ENX_CAP, 1);
-    for (int ext_cap = 0; ext_cap < 16; ext_cap++) {
-        uint8_t cal_result;
-        I2C_WRITEREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_IR_CAL_EXT_CAP, ext_cap);
-        cal_result = I2C_READREG_MASK_RTC(I2C_BBPLL, I2C_BBPLL_OR_CAL_CAP);
-        if (cal_result == 0) {
-            break;
-        }
-        if (ext_cap == 15) {
-            SOC_LOGE(TAG, "BBPLL SOFTWARE CAL FAIL");
-            abort();
-        }
-    }
+    REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
+    REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
+    REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
+    REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
+    REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
+    REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
+
     s_cur_pll_freq = pll_freq;
 }
 
@@ -285,7 +311,7 @@ void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
  */
 static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
 {
-    //int dbias = DIG_DBIAS_80M_160M;
+    int dbias = DIG_DBIAS_80M_160M;
     int per_conf = DPORT_CPUPERIOD_SEL_80;
     if (cpu_freq_mhz == 80) {
         /* nothing to do */
@@ -295,9 +321,10 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
         SOC_LOGE(TAG, "invalid frequency");
         abort();
     }
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias);
+    wait_dig_dbias_valid(2);
     REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
     REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
-    //REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
     REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_PLL);
     rtc_clk_apb_freq_update(80 * MHZ);
     ets_update_cpu_frequency(cpu_freq_mhz);
@@ -346,24 +373,23 @@ bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t *ou
 
 void rtc_clk_cpu_freq_set_config(const rtc_cpu_freq_config_t *config)
 {
-    rtc_xtal_freq_t xtal_freq = rtc_clk_xtal_freq_get();
     uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL);
-    if (soc_clk_sel != DPORT_SOC_CLK_SEL_XTAL) {
-        rtc_clk_cpu_freq_to_xtal(xtal_freq, 1);
-    }
-    if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
-        rtc_clk_bbpll_disable();
-    }
     if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
-        if (config->div > 1) {
-            rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
+        rtc_clk_cpu_freq_to_xtal(config->freq_mhz, config->div);
+        if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
+            rtc_clk_bbpll_disable();
         }
     } else if (config->source == RTC_CPU_FREQ_SRC_PLL) {
-        rtc_clk_bbpll_enable();
-        rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
+        if (soc_clk_sel != DPORT_SOC_CLK_SEL_PLL) {
+            rtc_clk_bbpll_enable();
+            rtc_clk_bbpll_configure(rtc_clk_xtal_freq_get(), config->source_freq_mhz);
+        }
         rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
     } else if (config->source == RTC_CPU_FREQ_SRC_8M) {
         rtc_clk_cpu_freq_to_8m();
+        if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL) {
+            rtc_clk_bbpll_disable();
+        }
     }
 }
 
@@ -406,7 +432,6 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
         div = 1;
         freq_mhz = source_freq_mhz;
         break;
-    case DPORT_SOC_CLK_SEL_APLL:
     default:
         SOC_LOGE(TAG, "unsupported frequency configuration");
         abort();
@@ -419,53 +444,6 @@ void rtc_clk_cpu_freq_get_config(rtc_cpu_freq_config_t *out_config)
     };
 }
 
-void rtc_clk_cpu_freq_set(rtc_cpu_freq_t cpu_freq)
-{
-    rtc_xtal_freq_t xtal_freq = RTC_XTAL_FREQ_40M;
-    /* Switch CPU to XTAL frequency first */
-    //REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
-    //REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, APB_CTRL_SOC_CLK_SEL_XTL);
-    //REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 1);
-    //ets_update_cpu_frequency(xtal_freq);
-    /* Frequency switch is synchronized to SLOW_CLK cycle. Wait until the switch
-     * is complete before disabling the PLL.
-     */
-    rtc_clk_wait_for_slow_cycle();
-    REG_SET_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
-    //REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 0);
-    // SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG,
-    //         RTC_CNTL_BB_I2C_FORCE_PD | RTC_CNTL_BBPLL_FORCE_PD |
-    //         RTC_CNTL_BBPLL_I2C_FORCE_PD);
-    s_cur_pll_freq = 0;
-    rtc_clk_apb_freq_update(xtal_freq * MHZ);
-    if (cpu_freq == RTC_CPU_FREQ_XTAL) {
-        /* already at XTAL, nothing to do */
-    } else if (cpu_freq == RTC_CPU_FREQ_2M) {
-        /* set up divider to produce 2MHz from XTAL */
-        REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, (xtal_freq / 2) - 1);
-        ets_update_cpu_frequency(2);
-        rtc_clk_apb_freq_update(2 * MHZ);
-    } else {
-        /* use PLL as clock source */
-        if (cpu_freq == RTC_CPU_FREQ_80M) {
-
-            REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 0);
-            ets_update_cpu_frequency(80);
-            s_cur_pll_freq = RTC_PLL_FREQ_480M;
-        } else if (cpu_freq == RTC_CPU_FREQ_160M) {
-            //REG_CLR_BIT(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL);
-            REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, 1);
-            ets_update_cpu_frequency(160);
-            s_cur_pll_freq = RTC_PLL_FREQ_480M;
-        }
-#define APB_CTRL_SOC_CLK_SEL_PLL 1
-        REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, APB_CTRL_SOC_CLK_SEL_PLL);
-        rtc_clk_wait_for_slow_cycle();
-        rtc_clk_apb_freq_update(80 * MHZ);
-    }
-    s_cur_pll_freq = cpu_freq;
-}
-
 void rtc_clk_cpu_freq_set_config_fast(const rtc_cpu_freq_config_t *config)
 {
     if (config->source == RTC_CPU_FREQ_SRC_XTAL) {
@@ -493,6 +471,13 @@ void rtc_clk_cpu_freq_set_xtal(void)
 void rtc_clk_cpu_freq_to_xtal(int freq, int div)
 {
     ets_update_cpu_frequency(freq);
+    /* lower the voltage */
+    if (freq <= 2) {
+        REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_2M);
+    } else {
+        REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
+    }
+    wait_dig_dbias_valid(2);
     /* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
     REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
     REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
@@ -500,18 +485,13 @@ void rtc_clk_cpu_freq_to_xtal(int freq, int div)
     /* switch clock source */
     REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
     rtc_clk_apb_freq_update(freq * MHZ);
-    /* lower the voltage */
-    if (freq <= 2) {
-        //REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_2M);
-    } else {
-        //REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
-    }
 }
 
 static void rtc_clk_cpu_freq_to_8m(void)
 {
     ets_update_cpu_frequency(8);
-    //REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
+    wait_dig_dbias_valid(2);
     REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
     REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_8M);
     rtc_clk_apb_freq_update(RTC_FAST_CLK_FREQ_8M);

+ 0 - 2
components/esp_hw_support/port/esp32c3/rtc_clk_common.h

@@ -18,12 +18,10 @@
 
 #define DPORT_CPUPERIOD_SEL_80      0
 #define DPORT_CPUPERIOD_SEL_160     1
-#define DPORT_CPUPERIOD_SEL_240     2
 
 #define DPORT_SOC_CLK_SEL_XTAL    0
 #define DPORT_SOC_CLK_SEL_PLL    1
 #define DPORT_SOC_CLK_SEL_8M     2
-#define DPORT_SOC_CLK_SEL_APLL   3
 
 #define RTC_FAST_CLK_FREQ_8M        8500000
 

+ 2 - 2
components/esp_hw_support/port/esp32c3/rtc_clk_init.c

@@ -24,13 +24,13 @@
 #include "soc/sens_periph.h"
 #include "soc/efuse_periph.h"
 #include "soc/apb_ctrl_reg.h"
-#include "i2c_rtc_clk.h"
+#include "regi2c_ctrl.h"
 #include "soc_log.h"
 #include "sdkconfig.h"
 #include "rtc_clk_common.h"
 #include "esp_rom_uart.h"
 
-static const char* TAG = "rtc_clk_init";
+static const char *TAG = "rtc_clk_init";
 
 void rtc_clk_init(rtc_clk_config_t cfg)
 {

+ 85 - 47
components/esp_hw_support/port/esp32c3/rtc_init.c

@@ -22,52 +22,42 @@
 #include "soc/spi_mem_reg.h"
 #include "soc/extmem_reg.h"
 #include "soc/system_reg.h"
-#include "i2c_rtc_clk.h"
+#include "regi2c_ctrl.h"
+#include "soc_log.h"
+
+static const char *TAG = "rtc_init";
 
 void rtc_init(rtc_config_t cfg)
 {
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
+
     CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU);
     rtc_clk_set_xtal_wait();
     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait);
     REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, cfg.ck8m_wait);
+    REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
 
-    /* Moved from rtc sleep to rtc init to save sleep function running time */
-    // set shortest possible sleep time limit
-    //REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL, RTC_CNTL_MIN_SLP_VAL_MIN);
-
-    /* This power domian removed
-    * set rom&ram timer
-    * REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_ROM_RAM_POWERUP_TIMER, ROM_RAM_POWERUP_CYCLES);
-    * REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_ROM_RAM_WAIT_TIMER, ROM_RAM_WAIT_CYCLES);
-    */
-    // set wifi timer
+    // set default powerup & wait time
     rtc_init_config_t rtc_init_cfg = RTC_INIT_CONFIG_DEFAULT();
     REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_POWERUP_TIMER, rtc_init_cfg.wifi_powerup_cycles);
     REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_WAIT_TIMER, rtc_init_cfg.wifi_wait_cycles);
-    // set rtc peri timer
-    //REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_POWERUP_TIMER, rtc_init_cfg.rtc_powerup_cycles);
-    //REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_WAIT_TIMER, rtc_init_cfg.rtc_wait_cycles);
-    // set digital wrap timer
+    REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_POWERUP_TIMER, rtc_init_cfg.bt_powerup_cycles);
+    REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_WAIT_TIMER, rtc_init_cfg.bt_wait_cycles);
+    REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_POWERUP_TIMER, rtc_init_cfg.cpu_top_powerup_cycles);
+    REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_WAIT_TIMER, rtc_init_cfg.cpu_top_wait_cycles);
     REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_POWERUP_TIMER, rtc_init_cfg.dg_wrap_powerup_cycles);
     REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_WAIT_TIMER, rtc_init_cfg.dg_wrap_wait_cycles);
-    // set rtc memory timer
-    //REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_RTCMEM_POWERUP_TIMER, rtc_init_cfg.rtc_mem_powerup_cycles);
-    //REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_RTCMEM_WAIT_TIMER, rtc_init_cfg.rtc_mem_wait_cycles);
-
-    //SET_PERI_REG_MASK(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_INC_HEARTBEAT_PERIOD);
+    REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_POWERUP_TIMER, rtc_init_cfg.dg_peri_powerup_cycles);
+    REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_WAIT_TIMER, rtc_init_cfg.dg_peri_wait_cycles);
 
     /* Reset RTC bias to default value (needed if waking up from deep sleep) */
-    //REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_CNTL_DBIAS_1V10);
-    //REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_SLP, RTC_CNTL_DBIAS_1V10);
-
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, RTC_CNTL_DBIAS_1V10);
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, RTC_CNTL_DBIAS_1V10);
 
     if (cfg.clkctl_init) {
         //clear CMMU clock force on
         CLEAR_PERI_REG_MASK(EXTMEM_CACHE_MMU_POWER_CTRL_REG, EXTMEM_CACHE_MMU_MEM_FORCE_ON);
-        //clear rom clock force on
-        //REG_SET_FIELD(SYSTEM_ROM_CTRL_0_REG, SYSTEM_ROM_IRAM0_CLKGATE_FORCE_ON, 0);
-        //clear sram clock force on
-        //REG_SET_FIELD(SYSTEM_SRAM_CTRL_0_REG, SYSTEM_SRAM_CLKGATE_FORCE_ON, 0);
         //clear tag clock force on
         CLEAR_PERI_REG_MASK(EXTMEM_ICACHE_TAG_POWER_CTRL_REG, EXTMEM_ICACHE_TAG_MEM_FORCE_ON);
         //clear register clock force on
@@ -84,10 +74,13 @@ void rtc_init(rtc_config_t cfg)
         } else {
             SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU);
         }
-        // CLEAR APLL close
+        // force pd APLL
         CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU);
         SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PD);
 
+        //open sar_i2c protect function to avoid sar_i2c reset when rtc_ldo is low.
+        CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_I2C_RESET_POR_FORCE_PD);
+
         //cancel bbpll force pu if setting no force power up
         if (!cfg.bbpll_fpu) {
             CLEAR_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_FORCE_PU);
@@ -98,44 +91,39 @@ void rtc_init(rtc_config_t cfg)
             SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_I2C_FORCE_PU);
             SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PU);
         }
-        //cancel RTC REG force PU
-        //CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FORCE_PU);
+
         CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
         CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PU);
 
-        //combine two rtc memory options
-        //CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_PU);
-        //CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_NOISO);
-
         if (cfg.rtc_dboost_fpd) {
             SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PD);
         } else {
             CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PD);
         }
 
-        //cancel sar i2c pd force
-        //CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD);
-        //cancel digital pu force
-        //CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_MEM_FORCE_PU);
-        //cannel i2c_reset_protect pd force
+        //clear i2c_reset_protect pd force, need tested in low temperature.
         //CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,RTC_CNTL_I2C_RESET_POR_FORCE_PD);
 
         /* If this mask is enabled, all soc memories cannot enter power down mode */
         /* We should control soc memory power down mode from RTC, so we will not touch this register any more */
-        //CLEAR_PERI_REG_MASK(SYSTEM_MEM_PD_MASK_REG, SYSTEM_LSLP_MEM_PD_MASK);
+        CLEAR_PERI_REG_MASK(SYSTEM_MEM_PD_MASK_REG, SYSTEM_LSLP_MEM_PD_MASK);
+
         /* If this pd_cfg is set to 1, all memory won't enter low power mode during light sleep */
         /* If this pd_cfg is set to 0, all memory will enter low power mode during light sleep */
-        rtc_sleep_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(0);
-        rtc_sleep_pd(pd_cfg);
+        rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(0);
+        rtc_sleep_pu(pu_cfg);
 
         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_FORCE_PU);
         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_FORCE_PU);
-        // ROM_RAM power domain is removed
-        // CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_ROM_RAM_FORCE_PU);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PU);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_FORCE_PU);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_FORCE_PU);
+
         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_WRAP_FORCE_NOISO);
         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_WIFI_FORCE_NOISO);
-        // CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CPU_ROM_RAM_FORCE_NOISO);
-        //CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FORCE_NOISO);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_NOISO);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CPU_TOP_FORCE_NOISO);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PERI_FORCE_NOISO);
         //cancel digital PADS force no iso
         if (cfg.cpu_waiti_clk_gate) {
             CLEAR_PERI_REG_MASK(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPU_WAIT_MODE_FORCE_ON);
@@ -146,9 +134,59 @@ void rtc_init(rtc_config_t cfg)
         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
         CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_NOISO);
     }
+    if (cfg.cali_ocode) {
+        /*
+        Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration(must close PLL).
+        Method:
+        1. read current cpu config, save in old_config;
+        2. switch cpu to xtal because PLL will be closed when o-code calibration;
+        3. begin o-code calibration;
+        4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
+        5. set cpu to old-config.
+        */
+        rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
+        rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
+        rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
+        rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
+        if (slow_clk_freq == (rtc_slow_freq_x32k)) {
+            cal_clk = RTC_CAL_32K_XTAL;
+        } else if (slow_clk_freq == rtc_slow_freq_8MD256) {
+            cal_clk  = RTC_CAL_8MD256;
+        }
+
+        uint64_t max_delay_time_us = 10000;
+        uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
+        uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
+        uint64_t cycle0 = rtc_time_get();
+        uint64_t timeout_cycle = cycle0 + max_delay_cycle;
+        uint64_t cycle1 = 0;
+
+        rtc_cpu_freq_config_t old_config;
+        rtc_clk_cpu_freq_get_config(&old_config);
+        rtc_clk_cpu_freq_set_xtal();
+
+
+        REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
+        REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
+        bool odone_flag = 0;
+        bool bg_odone_flag = 0;
+        while (1) {
+            odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
+            bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
+            cycle1 = rtc_time_get();
+            if (odone_flag && bg_odone_flag) {
+                break;
+            }
+            if (cycle1 >= timeout_cycle) {
+                SOC_LOGW(TAG, "o_code calibration fail\n");
+                break;
+            }
+        }
+        rtc_clk_cpu_freq_set_config(&old_config);
+    }
 }
 
-rtc_vddsdio_config_t rtc_vddsdio_get_config()
+rtc_vddsdio_config_t rtc_vddsdio_get_config(void)
 {
     rtc_vddsdio_config_t result;
     uint32_t sdio_conf_reg = REG_READ(RTC_CNTL_SDIO_CONF_REG);

+ 102 - 6
components/esp_hw_support/port/esp32c3/rtc_sleep.c

@@ -19,22 +19,118 @@
 #include "soc/apb_ctrl_reg.h"
 #include "soc/rtc.h"
 #include "soc/i2s_reg.h"
+#include "soc/bb_reg.h"
+#include "soc/nrx_reg.h"
+#include "soc/fe_reg.h"
 #include "soc/timer_group_reg.h"
 #include "soc/rtc.h"
 #include "esp32c3/rom/ets_sys.h"
+#include "regi2c_ctrl.h"
 
 /**
  * Configure whether certain peripherals are powered down in deep sleep
- * @param cfg power down flags as rtc_sleep_pd_config_t structure
+ * @param cfg power down flags as rtc_sleep_pu_config_t structure
  */
-void rtc_sleep_pd(rtc_sleep_pd_config_t cfg)
+void rtc_sleep_pu(rtc_sleep_pu_config_t cfg)
 {
-    abort(); // TODO ESP32-C3 IDF-2106
+    REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
+    REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
+    REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_DC_MEM_FORCE_PU, cfg.fe_fpu);
+    REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
+    REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG, APB_CTRL_AGC_MEM_FORCE_PU, cfg.fe_fpu);
+    REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
+    REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
+    REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
+    REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
+    REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
+    REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
+    REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
+    if (cfg.sram_fpu) {
+        REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_SRAM_POWER_UP, APB_CTRL_SRAM_POWER_UP);
+    } else {
+        REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_SRAM_POWER_UP, 0);
+    }
+    if (cfg.rom_ram_fpu) {
+        REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_ROM_POWER_UP, APB_CTRL_ROM_POWER_UP);
+    } else {
+        REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG, APB_CTRL_ROM_POWER_UP, 0);
+    }
 }
 
 void rtc_sleep_init(rtc_sleep_config_t cfg)
 {
-    abort(); // TODO ESP32-C3 IDF-2106
+    if (cfg.lslp_mem_inf_fpu) {
+        rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
+        rtc_sleep_pu(pu_cfg);
+    }
+    if (cfg.wifi_pd_en) {
+        SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
+    } else {
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN);
+    }
+    if (cfg.bt_pd_en) {
+        SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
+    } else {
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN);
+    }
+    if (cfg.cpu_pd_en) {
+        SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
+    } else {
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN);
+    }
+    if (cfg.dig_peri_pd_en) {
+        SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
+    } else {
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN);
+    }
+
+    REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR, RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
+    REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR, RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
+    REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP, RTC_CNTL_BIASSLP_SLEEP_DEFAULT);
+    REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR, RTC_CNTL_PD_CUR_MONITOR_DEFAULT);
+    REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP, RTC_CNTL_PD_CUR_SLEEP_DEFAULT);
+    if (cfg.deep_slp) {
+        REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
+        /* It's only a temporary configuration to set dbg 0 to make deepsleep run successfully when in high temperature.
+           we will restore it to RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT when ECO chip come back.
+           TODO ESP32-C3 IDF-2568
+         */
+        REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, 0);
+        SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
+                            RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
+                            RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
+    } else {
+        SET_PERI_REG_MASK(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP_EN);
+        REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP, RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
+        SET_PERI_REG_MASK(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU);
+        CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN);
+        REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT);
+    }
+
+    /* enable VDDSDIO control by state machine */
+    REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
+    REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN, cfg.vddsdio_pd_en);
+
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP, cfg.rtc_dbias_slp);
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, cfg.rtc_dbias_wak);
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP, cfg.dig_dbias_slp);
+    REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, cfg.dig_dbias_wak);
+
+    REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
+    REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
+
+    /* gating XTAL clock */
+    REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING);
+}
+
+void rtc_sleep_low_init(uint32_t slowclk_period)
+{
+    // set 5 PWC state machine times to fit in main state machine time
+    REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
+    REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
+    REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
 }
 
 void rtc_sleep_set_wakeup_time(uint64_t t)
@@ -62,8 +158,8 @@ uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
 
     /* restore config if it is a light sleep */
     if (lslp_mem_inf_fpu) {
-        rtc_sleep_pd_config_t pd_cfg = RTC_SLEEP_PD_CONFIG_ALL(0);
-        rtc_sleep_pd(pd_cfg);
+        rtc_sleep_pu_config_t pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
+        rtc_sleep_pu(pu_cfg);
     }
     return reject;
 }

+ 6 - 0
components/esp_hw_support/port/esp32c3/rtc_time.c

@@ -150,6 +150,12 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
 uint64_t rtc_time_get(void)
 {
     SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
+#if 0 // TODO ESP32-C3 IDF-2569:  Re-enable it in the future
+    while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
+        esp_rom_delay_us(1); // might take 1 RTC slowclk period, don't flood RTC bus
+    }
+    SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
+#endif
     uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
     t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
     return t;

+ 1 - 1
components/esp_hw_support/test/test_rtc_clk.c

@@ -17,7 +17,7 @@
 
 extern void rtc_clk_select_rtc_slow_clk(void);
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3)
+#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
 
 #include "esp32/clk.h"
 

+ 8 - 0
components/esp_system/sleep_modes.c

@@ -893,6 +893,7 @@ static uint32_t get_power_down_flags(void)
     // 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 SOC_TOUCH_PAD_WAKE_SUPPORTED
         uint32_t wakeup_source = RTC_TOUCH_TRIG_EN;
 #if SOC_ULP_SUPPORTED
         wakeup_source |= RTC_ULP_TRIG_EN;
@@ -904,6 +905,13 @@ static uint32_t get_power_down_flags(void)
             // prevents ULP timer and touch FSMs from working correctly.
             s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF;
         }
+#else
+        if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN) {
+            s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON;
+        } else {
+            s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF;
+        }
+#endif // SOC_TOUCH_PAD_WAKE_SUPPORTED
     }
 
     if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] == ESP_PD_OPTION_AUTO) {

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

@@ -210,6 +210,7 @@
 
 #define SOC_TOUCH_PAD_MEASURE_WAIT_MAX      (0xFF)  /*!<The timer frequency is 8Mhz, the max value is 0xff */
 #define SOC_TOUCH_PAD_THRESHOLD_MAX         (0)     /*!<If set touch threshold max value, The touch sensor can't be in touched status */
+#define SOC_TOUCH_PAD_WAKE_SUPPORTED        (1)     /*!<Supports waking up from touch pad trigger */
 
 /*-------------------------- TWAI CAPS ---------------------------------------*/
 #define SOC_TWAI_BRP_MIN                        2

+ 0 - 135
components/soc/esp32c3/i2c_apll.h

@@ -1,135 +0,0 @@
-// 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
-
-/**
- * @file i2c_apll.h
- * @brief Register definitions for audio PLL (APLL)
- *
- * This file lists register fields of APLL, located on an internal configuration
- * bus. These definitions are used via macros defined in i2c_rtc_clk.h, by
- * rtc_clk_apll_enable function in rtc_clk.c.
- */
-
-#define I2C_APLL            0X6D
-#define I2C_APLL_HOSTID     3
-
-#define I2C_APLL_IR_CAL_DELAY        0
-#define I2C_APLL_IR_CAL_DELAY_MSB    3
-#define I2C_APLL_IR_CAL_DELAY_LSB    0
-
-#define I2C_APLL_IR_CAL_RSTB        0
-#define I2C_APLL_IR_CAL_RSTB_MSB    4
-#define I2C_APLL_IR_CAL_RSTB_LSB    4
-
-#define I2C_APLL_IR_CAL_START        0
-#define I2C_APLL_IR_CAL_START_MSB    5
-#define I2C_APLL_IR_CAL_START_LSB    5
-
-#define I2C_APLL_IR_CAL_UNSTOP        0
-#define I2C_APLL_IR_CAL_UNSTOP_MSB    6
-#define I2C_APLL_IR_CAL_UNSTOP_LSB    6
-
-#define I2C_APLL_OC_ENB_FCAL        0
-#define I2C_APLL_OC_ENB_FCAL_MSB    7
-#define I2C_APLL_OC_ENB_FCAL_LSB    7
-
-#define I2C_APLL_IR_CAL_EXT_CAP        1
-#define I2C_APLL_IR_CAL_EXT_CAP_MSB    4
-#define I2C_APLL_IR_CAL_EXT_CAP_LSB    0
-
-#define I2C_APLL_IR_CAL_ENX_CAP        1
-#define I2C_APLL_IR_CAL_ENX_CAP_MSB    5
-#define I2C_APLL_IR_CAL_ENX_CAP_LSB    5
-
-#define I2C_APLL_OC_LBW        1
-#define I2C_APLL_OC_LBW_MSB    6
-#define I2C_APLL_OC_LBW_LSB    6
-
-#define I2C_APLL_IR_CAL_CK_DIV        2
-#define I2C_APLL_IR_CAL_CK_DIV_MSB    3
-#define I2C_APLL_IR_CAL_CK_DIV_LSB    0
-
-#define I2C_APLL_OC_DCHGP        2
-#define I2C_APLL_OC_DCHGP_MSB    6
-#define I2C_APLL_OC_DCHGP_LSB    4
-
-#define I2C_APLL_OC_ENB_VCON        2
-#define I2C_APLL_OC_ENB_VCON_MSB    7
-#define I2C_APLL_OC_ENB_VCON_LSB    7
-
-#define I2C_APLL_OR_CAL_CAP        3
-#define I2C_APLL_OR_CAL_CAP_MSB    4
-#define I2C_APLL_OR_CAL_CAP_LSB    0
-
-#define I2C_APLL_OR_CAL_UDF        3
-#define I2C_APLL_OR_CAL_UDF_MSB    5
-#define I2C_APLL_OR_CAL_UDF_LSB    5
-
-#define I2C_APLL_OR_CAL_OVF        3
-#define I2C_APLL_OR_CAL_OVF_MSB    6
-#define I2C_APLL_OR_CAL_OVF_LSB    6
-
-#define I2C_APLL_OR_CAL_END        3
-#define I2C_APLL_OR_CAL_END_MSB    7
-#define I2C_APLL_OR_CAL_END_LSB    7
-
-#define I2C_APLL_OR_OUTPUT_DIV        4
-#define I2C_APLL_OR_OUTPUT_DIV_MSB    4
-#define I2C_APLL_OR_OUTPUT_DIV_LSB    0
-
-#define I2C_APLL_OC_TSCHGP        4
-#define I2C_APLL_OC_TSCHGP_MSB    6
-#define I2C_APLL_OC_TSCHGP_LSB    6
-
-#define I2C_APLL_EN_FAST_CAL        4
-#define I2C_APLL_EN_FAST_CAL_MSB    7
-#define I2C_APLL_EN_FAST_CAL_LSB    7
-
-#define I2C_APLL_OC_DHREF_SEL        5
-#define I2C_APLL_OC_DHREF_SEL_MSB    1
-#define I2C_APLL_OC_DHREF_SEL_LSB    0
-
-#define I2C_APLL_OC_DLREF_SEL        5
-#define I2C_APLL_OC_DLREF_SEL_MSB    3
-#define I2C_APLL_OC_DLREF_SEL_LSB    2
-
-#define I2C_APLL_SDM_DITHER        5
-#define I2C_APLL_SDM_DITHER_MSB    4
-#define I2C_APLL_SDM_DITHER_LSB    4
-
-#define I2C_APLL_SDM_STOP        5
-#define I2C_APLL_SDM_STOP_MSB    5
-#define I2C_APLL_SDM_STOP_LSB    5
-
-#define I2C_APLL_SDM_RSTB        5
-#define I2C_APLL_SDM_RSTB_MSB    6
-#define I2C_APLL_SDM_RSTB_LSB    6
-
-#define I2C_APLL_OC_DVDD        6
-#define I2C_APLL_OC_DVDD_MSB    4
-#define I2C_APLL_OC_DVDD_LSB    0
-
-#define I2C_APLL_DSDM2        7
-#define I2C_APLL_DSDM2_MSB    5
-#define I2C_APLL_DSDM2_LSB    0
-
-#define I2C_APLL_DSDM1        8
-#define I2C_APLL_DSDM1_MSB    7
-#define I2C_APLL_DSDM1_LSB    0
-
-#define I2C_APLL_DSDM0        9
-#define I2C_APLL_DSDM0_MSB    7
-#define I2C_APLL_DSDM0_LSB    0

+ 15 - 19
components/soc/esp32c3/include/soc/rtc.h

@@ -101,11 +101,11 @@ extern "C" {
 #define RTC_CNTL_SCK_DCAP_DEFAULT   255
 
 /* Various delays to be programmed into power control state machines */
-#define RTC_CNTL_XTL_BUF_WAIT_SLP_US        (1000)
-#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES    (2)
-#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES       (4)
-#define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES         (1)
-#define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES            (1)
+#define RTC_CNTL_XTL_BUF_WAIT_SLP_US            (1000)
+#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES        (2)
+#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES           (4)
+#define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES    (1)
+#define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES       (1)
 
 /*
 set sleep_init default param
@@ -117,6 +117,7 @@ set sleep_init default param
 #define RTC_CNTL_BIASSLP_SLEEP_DEFAULT  1
 #define RTC_CNTL_PD_CUR_MONITOR_DEFAULT  0
 #define RTC_CNTL_PD_CUR_SLEEP_DEFAULT  1
+#define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254
 
 /**
  * @brief Possible main XTAL frequency values.
@@ -232,9 +233,9 @@ typedef struct {
 } x32k_config_t;
 
 #define X32K_CONFIG_DEFAULT() { \
-    .dac = 1, \
+    .dac = 3, \
     .dres = 3, \
-    .dgm = 0, \
+    .dgm = 3, \
     .dbuf = 1, \
 }
 
@@ -717,20 +718,15 @@ void rtc_sleep_low_init(uint32_t slowclk_period);
  */
 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)
-#define RTC_TIMER_TRIG_EN   BIT(3)  //!< Timer wakeup
-#define RTC_SDIO_TRIG_EN    BIT(4)  //!< SDIO wakeup (light sleep only)
-#define RTC_MAC_TRIG_EN     BIT(5)  //!< MAC wakeup (light sleep only)
-#define RTC_UART0_TRIG_EN   BIT(6)  //!< UART0 wakeup (light sleep only)
-#define RTC_UART1_TRIG_EN   BIT(7)  //!< UART1 wakeup (light sleep only)
-#define RTC_BT_TRIG_EN      BIT(10) //!< BT wakeup (light sleep only)
-#define RTC_COCPU_TRIG_EN   BIT(11)
+#define RTC_GPIO_TRIG_EN            BIT(2)  //!< GPIO wakeup
+#define RTC_TIMER_TRIG_EN           BIT(3)  //!< Timer wakeup
+#define RTC_MAC_TRIG_EN             BIT(5)  //!< MAC wakeup (light sleep only)
+#define RTC_UART0_TRIG_EN           BIT(6)  //!< UART0 wakeup (light sleep only)
+#define RTC_UART1_TRIG_EN           BIT(7)  //!< UART1 wakeup (light sleep only)
+#define RTC_BT_TRIG_EN              BIT(10) //!< BT wakeup (light sleep only)
 #define RTC_XTAL32K_DEAD_TRIG_EN    BIT(12)
-#define RTC_COCPU_TRAP_TRIG_EN      BIT(13)
 #define RTC_USB_TRIG_EN             BIT(14)
+#define RTC_BROWNOUT_DET_TRIG_EN    BIT(16)
 
 /**
  * @brief Enter deep or light sleep mode

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

@@ -222,6 +222,7 @@
 
 #define SOC_TOUCH_PAD_THRESHOLD_MAX         (0x1FFFFF)  /*!<If set touch threshold max value, The touch sensor can't be in touched status */
 #define SOC_TOUCH_PAD_MEASURE_WAIT_MAX      (0xFF)  /*!<The timer frequency is 8Mhz, the max value is 0xff */
+#define SOC_TOUCH_PAD_WAKE_SUPPORTED        (1)     /*!<Supports waking up from touch pad trigger */
 
 /*-------------------------- TWAI CAPS ---------------------------------------*/
 #define SOC_TWAI_BRP_MIN                2

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

@@ -26,6 +26,7 @@ extern "C" {
 #define SOC_TOUCH_SHIELD_CHANNEL            (14)
 #define SOC_TOUCH_DENOISE_CHANNEL           (0)
 #define SOC_TOUCH_PROXIMITY_CHANNEL_NUM     (3)
+#define SOC_TOUCH_PAD_WAKE_SUPPORTED        (1)     /*!<Supports waking up from touch pad trigger */
 
 #ifdef __cplusplus
 }