diff --git a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c b/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c index 0219da916b..e3129c84e8 100644 --- a/components/bootloader_support/src/esp32c3/bootloader_esp32c3.c +++ b/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) diff --git a/components/esp_hw_support/port/esp32c3/CMakeLists.txt b/components/esp_hw_support/port/esp32c3/CMakeLists.txt index a0220bef87..f8dc50fed7 100644 --- a/components/esp_hw_support/port/esp32c3/CMakeLists.txt +++ b/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) diff --git a/components/esp_hw_support/port/esp32c3/i2c_rtc_clk.h b/components/esp_hw_support/port/esp32c3/i2c_rtc_clk.h index 7042b8d1c7..0bbe0ee1a1 100644 --- a/components/esp_hw_support/port/esp32c3/i2c_rtc_clk.h +++ b/components/esp_hw_support/port/esp32c3/i2c_rtc_clk.h @@ -15,8 +15,7 @@ #pragma once #include -#include "i2c_apll.h" -#include "i2c_bbpll.h" +#include "regi2c_ctrl.h" /* Analog function control register */ #define ANA_CONFIG_REG 0x6000E044 diff --git a/components/esp_hw_support/port/esp32c3/private_include/regi2c_brownout.h b/components/esp_hw_support/port/esp32c3/private_include/regi2c_brownout.h index 0b8b618bba..d81751347c 100644 --- a/components/esp_hw_support/port/esp32c3/private_include/regi2c_brownout.h +++ b/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 diff --git a/components/esp_hw_support/port/esp32c3/private_include/regi2c_lp_bias.h b/components/esp_hw_support/port/esp32c3/private_include/regi2c_lp_bias.h index a735e0a42e..7cf3b457ce 100644 --- a/components/esp_hw_support/port/esp32c3/private_include/regi2c_lp_bias.h +++ b/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 diff --git a/components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h b/components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h index 2345e0a5aa..bb024245c9 100644 --- a/components/esp_hw_support/port/esp32c3/private_include/regi2c_saradc.h +++ b/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 diff --git a/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h b/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h index a197b3c83b..a8a07a8c1b 100644 --- a/components/esp_hw_support/port/esp32c3/regi2c_ctrl.h +++ b/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); diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk.c b/components/esp_hw_support/port/esp32c3/rtc_clk.c index 6c82c2103b..5cd7259bb7 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk.c +++ b/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); + 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); - // 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(); - } - } s_cur_pll_freq = pll_freq; } @@ -285,19 +311,26 @@ 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 origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL); + int origin_cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL); + int dbias = DIG_DBIAS_80M; int per_conf = DPORT_CPUPERIOD_SEL_80; if (cpu_freq_mhz == 80) { /* nothing to do */ } else if (cpu_freq_mhz == 160) { + dbias = DIG_DBIAS_160M; per_conf = DPORT_CPUPERIOD_SEL_160; } else { SOC_LOGE(TAG, "invalid frequency"); abort(); } + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias); + if ((origin_soc_clk == DPORT_SOC_CLK_SEL_XTAL) || (origin_soc_clk == DPORT_SOC_CLK_SEL_8M) + || (((origin_soc_clk == DPORT_SOC_CLK_SEL_PLL) && (0 == origin_cpuperiod_sel)))) { + 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 +379,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 +438,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 +450,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) { @@ -492,7 +476,18 @@ void rtc_clk_cpu_freq_set_xtal(void) */ void rtc_clk_cpu_freq_to_xtal(int freq, int div) { + int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL); + int origin_div_cnt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT); 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); + } + if ((DPORT_SOC_CLK_SEL_XTAL == origin_soc_clk) && (origin_div_cnt > 0)) { + 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 +495,17 @@ 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) { + int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL); + int origin_div_cnt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT); 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); + if ((DPORT_SOC_CLK_SEL_XTAL == origin_soc_clk) && (origin_div_cnt > 4)) { + 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); diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk_common.h b/components/esp_hw_support/port/esp32c3/rtc_clk_common.h index 787e36d08d..c3e8a86e09 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk_common.h +++ b/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 diff --git a/components/esp_hw_support/port/esp32c3/rtc_clk_init.c b/components/esp_hw_support/port/esp32c3/rtc_clk_init.c index 19708e91dd..7a5d42c58e 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_clk_init.c +++ b/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) { diff --git a/components/esp_hw_support/port/esp32c3/rtc_init.c b/components/esp_hw_support/port/esp32c3/rtc_init.c index 9361cf6c73..2f09d06c02 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_init.c +++ b/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); diff --git a/components/esp_hw_support/port/esp32c3/rtc_sleep.c b/components/esp_hw_support/port/esp32c3/rtc_sleep.c index d2775fdcda..5d3c6eed1f 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_sleep.c +++ b/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; } diff --git a/components/esp_hw_support/port/esp32c3/rtc_time.c b/components/esp_hw_support/port/esp32c3/rtc_time.c index 12c0961a43..53681232a5 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_time.c +++ b/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; diff --git a/components/esp_hw_support/test/test_rtc_clk.c b/components/esp_hw_support/test/test_rtc_clk.c index b763d51943..8d8acc04b8 100644 --- a/components/esp_hw_support/test/test_rtc_clk.c +++ b/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" diff --git a/components/esp_system/sleep_modes.c b/components/esp_system/sleep_modes.c index 7c477d975c..c01bec714f 100644 --- a/components/esp_system/sleep_modes.c +++ b/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) { diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 9f37a65d81..c8a00414d9 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -210,6 +210,7 @@ #define SOC_TOUCH_PAD_MEASURE_WAIT_MAX (0xFF) /*!