From 0a44d09f4f89adb9a3f1c72c2c2a285b99eab963 Mon Sep 17 00:00:00 2001 From: jingli Date: Sun, 9 Oct 2022 14:53:59 +0800 Subject: [PATCH 1/2] esp32/rtc: fix xtal unstable in some cases when sleep 1. add xtal buf wait to fix high temperature restart issue 2. add min sleep value to fix xtal stop due to too short sleep time issue --- components/esp_hw_support/include/esp_sleep.h | 10 +++++++++- components/esp_hw_support/sleep_modes.c | 20 +++++++++++++------ components/soc/esp32/include/soc/rtc.h | 3 ++- .../soc/esp32/include/soc/rtc_cntl_reg.h | 1 - components/soc/esp32c2/include/soc/rtc.h | 1 + .../soc/esp32c2/include/soc/rtc_cntl_reg.h | 1 - components/soc/esp32c3/include/soc/rtc.h | 1 + .../soc/esp32c3/include/soc/rtc_cntl_reg.h | 1 - components/soc/esp32c6/include/soc/rtc.h | 1 + .../esp32h2/include/rev1/soc/rtc_cntl_reg.h | 1 - .../esp32h2/include/rev2/soc/rtc_cntl_reg.h | 1 - components/soc/esp32h2/include/soc/rtc.h | 1 + components/soc/esp32s2/include/soc/rtc.h | 1 + .../soc/esp32s2/include/soc/rtc_cntl_reg.h | 19 +++++------------- components/soc/esp32s3/include/soc/rtc.h | 1 + .../soc/esp32s3/include/soc/rtc_cntl_reg.h | 1 - tools/ci/check_copyright_ignore.txt | 1 - 17 files changed, 36 insertions(+), 29 deletions(-) diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 3fd106cc673..896dc75d291 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -86,6 +86,11 @@ typedef enum { /* Leave this type define for compatibility */ typedef esp_sleep_source_t esp_sleep_wakeup_cause_t; +enum { + ESP_ERR_SLEEP_REJECT = ESP_ERR_INVALID_STATE, + ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION = ESP_ERR_INVALID_ARG, +}; + /** * @brief Disable wakeup source * @@ -372,7 +377,10 @@ void esp_deep_sleep_start(void) __attribute__((noreturn)); * * @return * - ESP_OK on success (returned after wakeup) - * - ESP_ERR_INVALID_STATE if WiFi or BT is not stopped + * - ESP_ERR_SLEEP_REJECT sleep request is rejected(wakeup source set before the sleep request) + * - ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION after deducting the sleep flow overhead, the final sleep duration + * is too short to cover the minimum sleep duration of the chip, when + * rtc timer wakeup source enabled */ esp_err_t esp_light_sleep_start(void); diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index a1f59dfb5b2..8e2294cdbe6 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -637,7 +637,7 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, rtc_vddsdio_config_t vddsdio_config) { // Enter sleep - esp_err_t err = esp_sleep_start(pd_flags); + uint32_t reject = esp_sleep_start(pd_flags); // If VDDSDIO regulator was controlled by RTC registers before sleep, // restore the configuration. @@ -650,7 +650,8 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, // Wait for the flash chip to start up esp_rom_delay_us(flash_enable_time_us); } - return err; + + return reject ? ESP_ERR_SLEEP_REJECT : ESP_OK; } /** @@ -811,11 +812,18 @@ esp_err_t esp_light_sleep_start(void) wdt_hal_write_protect_enable(&rtc_wdt_ctx); } - // Enter sleep, then wait for flash to be ready on wakeup - esp_err_t err = esp_light_sleep_inner(pd_flags, - flash_enable_time_us, vddsdio_config); + esp_err_t err = ESP_OK; + int64_t final_sleep_duration_us = (int64_t)s_config.sleep_duration - (int64_t)s_config.sleep_time_adjustment; + int64_t min_sleep_duration_us = rtc_time_slowclk_to_us(RTC_CNTL_MIN_SLP_VAL_MIN, s_config.rtc_clk_cal_period); - s_light_sleep_wakeup = true; + // if rtc timer wakeup source is enabled, need to compare final sleep duration and min sleep duration to avoid late wakeup + if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && (final_sleep_duration_us <= min_sleep_duration_us)) { + err = ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION; + } else { + // Enter sleep, then wait for flash to be ready on wakeup + err = esp_light_sleep_inner(pd_flags, flash_enable_time_us, vddsdio_config); + s_light_sleep_wakeup = true; + } // System timer has been stopped for the duration of the sleep, correct for that. uint64_t rtc_ticks_at_end = rtc_time_get(); diff --git a/components/soc/esp32/include/soc/rtc.h b/components/soc/esp32/include/soc/rtc.h index 9f927aee692..bec59669b1b 100644 --- a/components/soc/esp32/include/soc/rtc.h +++ b/components/soc/esp32/include/soc/rtc.h @@ -534,12 +534,13 @@ typedef struct rtc_sleep_config_s { void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_config); /* Various delays to be programmed into power control state machines */ -#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (500) +#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (1000) #define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES (1) #define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4) #define RTC_CNTL_WAKEUP_DELAY_CYCLES (7) #define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES (1) #define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1) +#define RTC_CNTL_MIN_SLP_VAL_MIN (128) #define RTC_CNTL_CK8M_WAIT_DEFAULT 20 #define RTC_CK8M_ENABLE_WAIT_DEFAULT 5 diff --git a/components/soc/esp32/include/soc/rtc_cntl_reg.h b/components/soc/esp32/include/soc/rtc_cntl_reg.h index aec51adf6a4..d609140b494 100644 --- a/components/soc/esp32/include/soc/rtc_cntl_reg.h +++ b/components/soc/esp32/include/soc/rtc_cntl_reg.h @@ -432,7 +432,6 @@ #define RTC_CNTL_MIN_SLP_VAL_M ((RTC_CNTL_MIN_SLP_VAL_V)<<(RTC_CNTL_MIN_SLP_VAL_S)) #define RTC_CNTL_MIN_SLP_VAL_V 0xFF #define RTC_CNTL_MIN_SLP_VAL_S 8 -#define RTC_CNTL_MIN_SLP_VAL_MIN 2 /* RTC_CNTL_ULP_CP_SUBTIMER_PREDIV : R/W ;bitpos:[7:0] ;default: 8'd1 ; */ /*description: */ #define RTC_CNTL_ULP_CP_SUBTIMER_PREDIV 0x000000FF diff --git a/components/soc/esp32c2/include/soc/rtc.h b/components/soc/esp32c2/include/soc/rtc.h index 0b63443d55d..1725ac3dcb8 100644 --- a/components/soc/esp32c2/include/soc/rtc.h +++ b/components/soc/esp32c2/include/soc/rtc.h @@ -96,6 +96,7 @@ extern "C" { #define RTC_CNTL_WAKEUP_DELAY_CYCLES (5) #define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES (1) #define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1) +#define RTC_CNTL_MIN_SLP_VAL_MIN (2) /* set sleep_init default param diff --git a/components/soc/esp32c2/include/soc/rtc_cntl_reg.h b/components/soc/esp32c2/include/soc/rtc_cntl_reg.h index d409108d410..2ae5143b01f 100644 --- a/components/soc/esp32c2/include/soc/rtc_cntl_reg.h +++ b/components/soc/esp32c2/include/soc/rtc_cntl_reg.h @@ -303,7 +303,6 @@ RO CPU.*/ #define RTC_CNTL_MIN_SLP_VAL_M ((RTC_CNTL_MIN_SLP_VAL_V)<<(RTC_CNTL_MIN_SLP_VAL_S)) #define RTC_CNTL_MIN_SLP_VAL_V 0xFF #define RTC_CNTL_MIN_SLP_VAL_S 8 -#define RTC_CNTL_MIN_SLP_VAL_MIN 2 #define RTC_CNTL_ANA_CONF_REG (DR_REG_RTCCNTL_BASE + 0x2C) /* RTC_CNTL_PLL_I2C_PU : ;bitpos:[31] ;default: 1'd0 ; */ diff --git a/components/soc/esp32c3/include/soc/rtc.h b/components/soc/esp32c3/include/soc/rtc.h index a52ee8b75df..0e10a3181ef 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -99,6 +99,7 @@ extern "C" { #define RTC_CNTL_WAKEUP_DELAY_CYCLES (5) #define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES (1) #define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1) +#define RTC_CNTL_MIN_SLP_VAL_MIN (2) /* set sleep_init default param diff --git a/components/soc/esp32c3/include/soc/rtc_cntl_reg.h b/components/soc/esp32c3/include/soc/rtc_cntl_reg.h index 51607ff89fd..ac7d7b03b47 100644 --- a/components/soc/esp32c3/include/soc/rtc_cntl_reg.h +++ b/components/soc/esp32c3/include/soc/rtc_cntl_reg.h @@ -380,7 +380,6 @@ extern "C" { #define RTC_CNTL_MIN_SLP_VAL_M ((RTC_CNTL_MIN_SLP_VAL_V)<<(RTC_CNTL_MIN_SLP_VAL_S)) #define RTC_CNTL_MIN_SLP_VAL_V 0xFF #define RTC_CNTL_MIN_SLP_VAL_S 8 -#define RTC_CNTL_MIN_SLP_VAL_MIN 2 #define RTC_CNTL_TIMER6_REG (DR_REG_RTCCNTL_BASE + 0x0030) /* RTC_CNTL_DG_PERI_POWERUP_TIMER : R/W ;bitpos:[31:25] ;default: 7'h5 ; */ diff --git a/components/soc/esp32c6/include/soc/rtc.h b/components/soc/esp32c6/include/soc/rtc.h index af4bd822de6..dd202268269 100644 --- a/components/soc/esp32c6/include/soc/rtc.h +++ b/components/soc/esp32c6/include/soc/rtc.h @@ -99,6 +99,7 @@ extern "C" { #define RTC_CNTL_WAKEUP_DELAY_CYCLES (5) #define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES (1) #define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1) +#define RTC_CNTL_MIN_SLP_VAL_MIN (2) /* set sleep_init default param diff --git a/components/soc/esp32h2/include/rev1/soc/rtc_cntl_reg.h b/components/soc/esp32h2/include/rev1/soc/rtc_cntl_reg.h index 3249b2c99aa..34d6c7c5d47 100644 --- a/components/soc/esp32h2/include/rev1/soc/rtc_cntl_reg.h +++ b/components/soc/esp32h2/include/rev1/soc/rtc_cntl_reg.h @@ -392,7 +392,6 @@ extern "C" { #define RTC_CNTL_MIN_SLP_VAL_M ((RTC_CNTL_MIN_SLP_VAL_V)<<(RTC_CNTL_MIN_SLP_VAL_S)) #define RTC_CNTL_MIN_SLP_VAL_V 0xFF #define RTC_CNTL_MIN_SLP_VAL_S 8 -#define RTC_CNTL_MIN_SLP_VAL_MIN 2 #define RTC_CNTL_TIMER6_REG (DR_REG_RTCCNTL_BASE + 0x0030) /* RTC_CNTL_DG_PERI_POWERUP_TIMER : R/W ;bitpos:[31:25] ;default: 7'h5 ; */ diff --git a/components/soc/esp32h2/include/rev2/soc/rtc_cntl_reg.h b/components/soc/esp32h2/include/rev2/soc/rtc_cntl_reg.h index 06e37b04ee5..8226d49e4f6 100644 --- a/components/soc/esp32h2/include/rev2/soc/rtc_cntl_reg.h +++ b/components/soc/esp32h2/include/rev2/soc/rtc_cntl_reg.h @@ -482,7 +482,6 @@ extern "C" { #define RTC_CNTL_MIN_SLP_VAL_M (RTC_CNTL_MIN_SLP_VAL_V << RTC_CNTL_MIN_SLP_VAL_S) #define RTC_CNTL_MIN_SLP_VAL_V 0x000000FFU #define RTC_CNTL_MIN_SLP_VAL_S 8 -#define RTC_CNTL_MIN_SLP_VAL_MIN 2 /** RTC_CNTL_TIMER6_REG register * register description diff --git a/components/soc/esp32h2/include/soc/rtc.h b/components/soc/esp32h2/include/soc/rtc.h index 5373e0a3713..4d8bd70287e 100644 --- a/components/soc/esp32h2/include/soc/rtc.h +++ b/components/soc/esp32h2/include/soc/rtc.h @@ -116,6 +116,7 @@ extern "C" { #define RTC_CNTL_WAKEUP_DELAY_CYCLES (5) #define RTC_CNTL_OTHER_BLOCKS_POWERUP_CYCLES (1) #define RTC_CNTL_OTHER_BLOCKS_WAIT_CYCLES (1) +#define RTC_CNTL_MIN_SLP_VAL_MIN (2) /* set sleep_init default param diff --git a/components/soc/esp32s2/include/soc/rtc.h b/components/soc/esp32s2/include/soc/rtc.h index 35b75e9ecbf..b3321905b83 100644 --- a/components/soc/esp32s2/include/soc/rtc.h +++ b/components/soc/esp32s2/include/soc/rtc.h @@ -97,6 +97,7 @@ extern "C" { #define RTC_CNTL_XTL_BUF_WAIT_SLP_US (1000) #define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4) #define RTC_CNTL_WAKEUP_DELAY_CYCLES (4) +#define RTC_CNTL_MIN_SLP_VAL_MIN (2) #define RTC_CNTL_CK8M_DFREQ_DEFAULT 172 #define RTC_CNTL_SCK_DCAP_DEFAULT 255 diff --git a/components/soc/esp32s2/include/soc/rtc_cntl_reg.h b/components/soc/esp32s2/include/soc/rtc_cntl_reg.h index bb769c935d1..bd747d13aa9 100644 --- a/components/soc/esp32s2/include/soc/rtc_cntl_reg.h +++ b/components/soc/esp32s2/include/soc/rtc_cntl_reg.h @@ -1,16 +1,8 @@ -// Copyright 2017-2018 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. +/* + * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _SOC_RTC_CNTL_REG_H_ #define _SOC_RTC_CNTL_REG_H_ @@ -396,7 +388,6 @@ extern "C" { #define RTC_CNTL_MIN_SLP_VAL_M ((RTC_CNTL_MIN_SLP_VAL_V)<<(RTC_CNTL_MIN_SLP_VAL_S)) #define RTC_CNTL_MIN_SLP_VAL_V 0xFF #define RTC_CNTL_MIN_SLP_VAL_S 8 -#define RTC_CNTL_MIN_SLP_VAL_MIN 2 #define RTC_CNTL_TIMER6_REG (DR_REG_RTCCNTL_BASE + 0x0030) /* RTC_CNTL_DG_DCDC_POWERUP_TIMER : R/W ;bitpos:[31:25] ;default: 7'h8 ; */ diff --git a/components/soc/esp32s3/include/soc/rtc.h b/components/soc/esp32s3/include/soc/rtc.h index fab75b04392..82518b83d7f 100644 --- a/components/soc/esp32s3/include/soc/rtc.h +++ b/components/soc/esp32s3/include/soc/rtc.h @@ -99,6 +99,7 @@ extern "C" { #define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES (1) #define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4) #define RTC_CNTL_WAKEUP_DELAY_CYCLES (4) +#define RTC_CNTL_MIN_SLP_VAL_MIN (2) #define RTC_CNTL_CK8M_DFREQ_DEFAULT 100 #define RTC_CNTL_SCK_DCAP_DEFAULT 255 diff --git a/components/soc/esp32s3/include/soc/rtc_cntl_reg.h b/components/soc/esp32s3/include/soc/rtc_cntl_reg.h index 48927f3d538..c7730ba41d8 100644 --- a/components/soc/esp32s3/include/soc/rtc_cntl_reg.h +++ b/components/soc/esp32s3/include/soc/rtc_cntl_reg.h @@ -369,7 +369,6 @@ ork.*/ #define RTC_CNTL_MIN_SLP_VAL_M ((RTC_CNTL_MIN_SLP_VAL_V)<<(RTC_CNTL_MIN_SLP_VAL_S)) #define RTC_CNTL_MIN_SLP_VAL_V 0xFF #define RTC_CNTL_MIN_SLP_VAL_S 8 -#define RTC_CNTL_MIN_SLP_VAL_MIN 2 #define RTC_CNTL_TIMER6_REG (DR_REG_RTCCNTL_BASE + 0x30) /* RTC_CNTL_DG_PERI_POWERUP_TIMER : R/W ;bitpos:[31:25] ;default: 7'h8 ; */ diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 6417146d578..2114b6a5b33 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1096,7 +1096,6 @@ components/soc/esp32s2/include/soc/interrupt_reg.h components/soc/esp32s2/include/soc/ledc_reg.h components/soc/esp32s2/include/soc/memprot_defs.h components/soc/esp32s2/include/soc/nrx_reg.h -components/soc/esp32s2/include/soc/rtc_cntl_reg.h components/soc/esp32s2/include/soc/rtc_cntl_struct.h components/soc/esp32s2/include/soc/rtc_i2c_reg.h components/soc/esp32s2/include/soc/rtc_io_channel.h From 101c2c6c3e28123f85c16e9b30edd3fbbc80a119 Mon Sep 17 00:00:00 2001 From: jingli Date: Sun, 9 Oct 2022 17:15:21 +0800 Subject: [PATCH 2/2] esp_hw_support/sleep: fix light sleep wakeup flag light sleep wakeup flag is true to indicate the most recent successful wakeup from light sleep, which means the most recent light sleep occurred successfully and then wakes up by wakeup source --- components/esp_hw_support/sleep_modes.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 8e2294cdbe6..f27e937a58f 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -816,15 +816,20 @@ esp_err_t esp_light_sleep_start(void) int64_t final_sleep_duration_us = (int64_t)s_config.sleep_duration - (int64_t)s_config.sleep_time_adjustment; int64_t min_sleep_duration_us = rtc_time_slowclk_to_us(RTC_CNTL_MIN_SLP_VAL_MIN, s_config.rtc_clk_cal_period); + // reset light sleep wakeup flag before a new light sleep + s_light_sleep_wakeup = false; + // if rtc timer wakeup source is enabled, need to compare final sleep duration and min sleep duration to avoid late wakeup if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) && (final_sleep_duration_us <= min_sleep_duration_us)) { err = ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION; } else { // Enter sleep, then wait for flash to be ready on wakeup err = esp_light_sleep_inner(pd_flags, flash_enable_time_us, vddsdio_config); - s_light_sleep_wakeup = true; } + // light sleep wakeup flag only makes sense after a successful light sleep + s_light_sleep_wakeup = (err == ESP_OK); + // System timer has been stopped for the duration of the sleep, correct for that. uint64_t rtc_ticks_at_end = rtc_time_get(); uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period);