Merge branch 'bugfix/update_esp32c6eco1_sleep_fosc_cal_cycles' into 'master'

bugfix: update esp32c6eco1 / esp32h2eco2 fosc calibration cycles during sleep and support calibrate OSC clock every N times lightsleep

Closes IDF-7287

See merge request espressif/esp-idf!23489
This commit is contained in:
Wu Zheng Hui
2023-05-09 18:44:20 +08:00
9 changed files with 84 additions and 6 deletions

View File

@@ -3,6 +3,15 @@ menu "Hardware Settings"
menu "Chip revision"
# Insert chip-specific HW config
orsource "./port/$IDF_TARGET/Kconfig.hw_support"
config ESP_REV_NEW_CHIP_TEST
bool "Internal test mode"
depends on IDF_CI_BUILD
default n
help
For internal chip testing, a small number of new versions chips didn't
update the version field in eFuse, you can enable this option to force the
software recognize the chip version based on the rev selected in menuconfig.
endmenu
orsource "./port/$IDF_TARGET/Kconfig.spiram"

View File

@@ -11,11 +11,14 @@ choice ESP32C6_REV_MIN
config ESP32C6_REV_MIN_0
bool "Rev v0.0"
config ESP32C6_REV_MIN_1
bool "Rev v0.1 (ECO1)"
endchoice
config ESP32C6_REV_MIN_FULL
int
default 0 if ESP32C6_REV_MIN_0
default 1 if ESP32C6_REV_MIN_1
config ESP_REV_MIN_FULL
int

View File

@@ -103,6 +103,15 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
&& !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
}
/*The Fosc CLK of calibration circuit is divided by 32 for ECO1.
So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
avoid excessive calibration time.*/
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
if (cal_clk == RTC_CAL_RC_FAST) {
slowclk_cycles = slowclk_cycles >> 5;
}
}
/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);

View File

@@ -11,11 +11,17 @@ choice ESP32H2_REV_MIN
config ESP32H2_REV_MIN_0
bool "Rev v0.0"
config ESP32H2_REV_MIN_1
bool "Rev v0.1 (ECO1)"
config ESP32H2_REV_MIN_2
bool "Rev v0.2 (ECO2)"
endchoice
config ESP32H2_REV_MIN_FULL
int
default 0 if ESP32H2_REV_MIN_0
default 1 if ESP32H2_REV_MIN_1
default 2 if ESP32H2_REV_MIN_2
config ESP_REV_MIN_FULL
int

View File

@@ -102,6 +102,15 @@ uint32_t rtc_clk_cal_internal(rtc_cal_sel_t cal_clk, uint32_t slowclk_cycles)
&& !GET_PERI_REG_MASK(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT));
}
/*The Fosc CLK of calibration circuit is divided by 32 for ECO2.
So we need to divide the calibrate cycles of the FOSC for ECO1 and above chips by 32 to
avoid excessive calibration time.*/
if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) {
if (cal_clk == RTC_CAL_RC_FAST) {
slowclk_cycles = slowclk_cycles >> 5;
}
}
/* Prepare calibration */
REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cali_clk_sel);
CLEAR_PERI_REG_MASK(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING);

View File

@@ -99,7 +99,7 @@
// Cycles for RTC Timer clock source (internal oscillator) calibrate
#define RTC_CLK_SRC_CAL_CYCLES (10)
#define FAST_CLK_SRC_CAL_CYCLES (2000) /* ~ 127.4 us */
#define FAST_CLK_SRC_CAL_CYCLES (2048) /* ~ 127.4 us */
#ifdef CONFIG_IDF_TARGET_ESP32
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (212)
@@ -150,7 +150,7 @@
static esp_deep_sleep_cb_t s_dslp_cb[MAX_DSLP_HOOKS]={0};
/**
* Internal structure which holds all requested deep sleep parameters
* Internal structure which holds all requested sleep parameters
*/
typedef struct {
struct {
@@ -180,6 +180,8 @@ typedef struct {
} sleep_config_t;
static uint32_t s_lightsleep_cnt = 0;
_Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should increase ext1_rtc_gpio_mask field size");
static sleep_config_t s_config = {
@@ -689,7 +691,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t mo
// re-enable UART output
resume_uarts();
s_lightsleep_cnt++;
return result;
}
@@ -889,8 +891,13 @@ esp_err_t esp_light_sleep_start(void)
s_config.rtc_clk_cal_period = rtc_clk_cal_cycling(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
#else
s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
#if CONFIG_PM_ENABLE
if (s_lightsleep_cnt % CONFIG_PM_LIGHTSLEEP_RTC_OSC_CAL_INTERVAL == 0)
#endif
{
s_config.rtc_clk_cal_period = rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
esp_clk_slowclk_cal_set(s_config.rtc_clk_cal_period);
}
#endif
/*
@@ -902,7 +909,12 @@ esp_err_t esp_light_sleep_start(void)
*/
#if SOC_PMU_SUPPORTED
s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES);
#if CONFIG_PM_ENABLE
if (s_lightsleep_cnt % CONFIG_PM_LIGHTSLEEP_RTC_OSC_CAL_INTERVAL == 0)
#endif
{
s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES);
}
int sleep_time_sw_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out;
int sleep_time_hw_adjustment = pmu_sleep_calculate_hw_wait_time(pd_flags, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period);
s_config.sleep_time_adjustment = sleep_time_sw_adjustment + sleep_time_hw_adjustment;

View File

@@ -93,6 +93,20 @@ menu "Power Management"
This option is invisible to users, and it is only used for ci testing,
enabling it in the application will increase the sleep and wake-up time overhead
config PM_LIGHTSLEEP_RTC_OSC_CAL_INTERVAL
int "Calibrate the RTC_FAST/SLOW clock every N times of light sleep"
default 1
depends on PM_ENABLE
range 1 128
help
The value of this option determines the calibration interval of the RTC_FAST/SLOW clock during sleep when
power management is enabled. When it is configured as N, the RTC_FAST/SLOW clock will be calibrated
every N times of lightsleep.
Decreasing this value will increase the time the chip is in the active state, thereby increasing the
average power consumption of the chip.
Increasing this value can reduce the average power consumption, but when the external environment changes
drastically and the chip RTC_FAST/SLOW oscillator frequency drifts, it may cause system instability.
config PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP
bool "Power down CPU in light sleep"
depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6

View File

@@ -16,12 +16,20 @@
uint32_t efuse_hal_get_major_chip_version(void)
{
#ifdef CONFIG_ESP_REV_NEW_CHIP_TEST
return CONFIG_ESP_REV_MIN_FULL / 100;
#else
return efuse_ll_get_chip_wafer_version_major();
#endif
}
uint32_t efuse_hal_get_minor_chip_version(void)
{
#ifdef CONFIG_ESP_REV_NEW_CHIP_TEST
return CONFIG_ESP_REV_MIN_FULL % 100;
#else
return efuse_ll_get_chip_wafer_version_minor();
#endif
}
/******************* eFuse control functions *************************/

View File

@@ -16,12 +16,20 @@
uint32_t efuse_hal_get_major_chip_version(void)
{
#ifdef CONFIG_ESP_REV_NEW_CHIP_TEST
return CONFIG_ESP_REV_MIN_FULL / 100;
#else
return efuse_ll_get_chip_wafer_version_major();
#endif
}
uint32_t efuse_hal_get_minor_chip_version(void)
{
#ifdef CONFIG_ESP_REV_NEW_CHIP_TEST
return CONFIG_ESP_REV_MIN_FULL % 100;
#else
return efuse_ll_get_chip_wafer_version_minor();
#endif
}
/******************* eFuse control functions *************************/