mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-20 00:36:01 -04:00
Merge branch 'bugfix/fix_x32k_startup_slow_bug' into 'master'
bugfix: Fix xtal 32k not oscillate or oscillate too slowly issue for esp32 See merge request espressif/esp-idf!10519
This commit is contained in:
commit
af992c26bc
@ -287,6 +287,10 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
|
||||
|
||||
esp_err_t touch_pad_init(void)
|
||||
{
|
||||
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2
|
||||
ESP_LOGE(TOUCH_TAG, "Touch Pad can't work because it provides current to external XTAL");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2
|
||||
if (rtc_touch_mux == NULL) {
|
||||
rtc_touch_mux = xSemaphoreCreateMutex();
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ extern "C" {
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_NO_MEM Touch pad init error
|
||||
* - ESP_ERR_NOT_SUPPORTED Touch pad is providing current to external XTAL
|
||||
*/
|
||||
esp_err_t touch_pad_init(void);
|
||||
|
||||
|
@ -570,18 +570,35 @@ menu "ESP32-specific"
|
||||
bool "Internal 8.5MHz oscillator, divided by 256 (~33kHz)"
|
||||
endchoice
|
||||
|
||||
config ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
bool "Additional current for external 32kHz crystal"
|
||||
choice ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_METHOD
|
||||
prompt "Additional current for external 32kHz crystal"
|
||||
depends on ESP32_RTC_CLK_SRC_EXT_CRYS
|
||||
default "n"
|
||||
depends on ESP32_REV_MIN <= 1
|
||||
default ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_NONE
|
||||
help
|
||||
Choose which additional current is used for rtc external crystal.
|
||||
With some 32kHz crystal configurations, the X32N and X32P pins may not have enough
|
||||
drive strength to keep the crystal oscillating. Choose the method to provide
|
||||
additional current from touchpad 9 to the external 32kHz crystal. Note that
|
||||
the deep sleep current is slightly high (4-5uA) and the touchpad and the
|
||||
wakeup sources of both touchpad and ULP are not available in method 1 and method 2.
|
||||
|
||||
- With some 32kHz crystal configurations, the X32N and X32P pins may not
|
||||
have enough drive strength to keep the crystal oscillating during deep sleep.
|
||||
If this option is enabled, additional current from touchpad 9 is provided
|
||||
internally to drive the 32kHz crystal. If this option is enabled, deep sleep current
|
||||
is slightly higher (4-5uA) and the touchpad and ULP wakeup sources are not available.
|
||||
This problem is fixed in ESP32 ECO 3, so this workaround is not needed. Setting the
|
||||
project configuration to minimum revision ECO3 will disable this option, , allow
|
||||
all wakeup sources, and save some code size.
|
||||
|
||||
- "None" option will not provide additional current to external crystal
|
||||
- "Method 1" option can't ensure 100% to solve the external 32k crystal start failed
|
||||
issue, but the touchpad can work in this method.
|
||||
- "Method 2" option can solve the external 32k issue, but the touchpad can't work
|
||||
in this method.
|
||||
|
||||
config ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_NONE
|
||||
bool "None"
|
||||
config ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
bool "Method 1"
|
||||
config ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2
|
||||
bool "Method 2"
|
||||
endchoice
|
||||
|
||||
config ESP32_RTC_CLK_CAL_CYCLES
|
||||
int "Number of cycles for RTC_SLOW_CLK calibration"
|
||||
|
@ -1,7 +1,14 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
set(requires soc)
|
||||
if(${target} STREQUAL "esp32")
|
||||
list(APPEND requires efuse)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "compare_set.c"
|
||||
"cpu_util.c"
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES soc
|
||||
REQUIRES ${requires}
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "esp32/rom/ets_sys.h" // for ets_update_cpu_frequency
|
||||
#include "esp32/rom/rtc.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/sens_periph.h"
|
||||
@ -58,7 +59,7 @@
|
||||
#define APLL_CAL_DELAY_2 0x3f
|
||||
#define APLL_CAL_DELAY_3 0x1f
|
||||
|
||||
#define XTAL_32K_DAC_VAL 3
|
||||
#define XTAL_32K_DAC_VAL 1
|
||||
#define XTAL_32K_DRES_VAL 3
|
||||
#define XTAL_32K_DBIAS_VAL 0
|
||||
|
||||
@ -127,20 +128,42 @@ static void rtc_clk_32k_enable_common(int dac, int dres, int dbias)
|
||||
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DBIAS_XTAL_32K, dbias);
|
||||
|
||||
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
/* TOUCH sensor can provide additional current to external XTAL.
|
||||
In some case, X32N and X32P PAD don't have enough drive capability to start XTAL */
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS_M);
|
||||
/* Tie PAD Touch8 to VDD
|
||||
NOTE: TOUCH8 and TOUCH9 register settings are reversed except for DAC, so we set RTC_IO_TOUCH_PAD9_REG here instead
|
||||
*/
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_TIE_OPT_M);
|
||||
/* Set the current used to compensate TOUCH PAD8 */
|
||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_PAD8_REG, RTC_IO_TOUCH_PAD8_DAC, 4, RTC_IO_TOUCH_PAD8_DAC_S);
|
||||
/* Power up TOUCH8
|
||||
So the Touch DAC start to drive some current from VDD to TOUCH8(which is also XTAL-N)
|
||||
*/
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
||||
#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
uint8_t chip_ver = esp_efuse_get_chip_ver();
|
||||
// version0 and version1 need provide additional current to external XTAL.
|
||||
if(chip_ver == 0 || chip_ver == 1) {
|
||||
/* TOUCH sensor can provide additional current to external XTAL.
|
||||
In some case, X32N and X32P PAD don't have enough drive capability to start XTAL */
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS_M);
|
||||
/* Tie PAD Touch8 to VDD
|
||||
NOTE: TOUCH8 and TOUCH9 register settings are reversed except for DAC, so we set RTC_IO_TOUCH_PAD9_REG here instead*/
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_TIE_OPT_M);
|
||||
/* Set the current used to compensate TOUCH PAD8 */
|
||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_PAD8_REG, RTC_IO_TOUCH_PAD8_DAC, 4, RTC_IO_TOUCH_PAD8_DAC_S);
|
||||
/* Power up TOUCH8
|
||||
So the Touch DAC start to drive some current from VDD to TOUCH8(which is also XTAL-N)*/
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
||||
}
|
||||
#elif defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2
|
||||
uint8_t chip_ver = esp_efuse_get_chip_ver();
|
||||
if(chip_ver == 0 || chip_ver == 1) {
|
||||
/* TOUCH sensor can provide additional current to external XTAL.
|
||||
In some case, X32N and X32P PAD don't have enough drive capability to start XTAL */
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS_M);
|
||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_DCUR, 3, RTC_IO_TOUCH_DCUR_S);
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FSM_EN_M);
|
||||
/* Tie PAD Touch8 to VDD
|
||||
NOTE: TOUCH8 and TOUCH9 register settings are reversed except for DAC, so we set RTC_IO_TOUCH_PAD9_REG here instead
|
||||
*/
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_TIE_OPT_M);
|
||||
/* Set the current used to compensate TOUCH PAD8 */
|
||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_PAD8_REG, RTC_IO_TOUCH_PAD8_DAC, 1, RTC_IO_TOUCH_PAD8_DAC_S);
|
||||
/* Power up TOUCH8
|
||||
So the Touch DAC start to drive some current from VDD to TOUCH8(which is also XTAL-N)
|
||||
*/
|
||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_START_M);
|
||||
}
|
||||
#endif
|
||||
/* Power up external xtal */
|
||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M);
|
||||
}
|
||||
@ -155,9 +178,21 @@ void rtc_clk_32k_enable(bool enable)
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL);
|
||||
|
||||
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
/* Power down TOUCH */
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
||||
#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
uint8_t chip_ver = esp_efuse_get_chip_ver();
|
||||
if(chip_ver == 0 || chip_ver == 1) {
|
||||
/* Power down TOUCH */
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
||||
}
|
||||
#elif defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2
|
||||
uint8_t chip_ver = esp_efuse_get_chip_ver();
|
||||
if(chip_ver == 0 || chip_ver == 1) {
|
||||
/* Power down TOUCH */
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS_M);
|
||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_DCUR, 0, RTC_IO_TOUCH_DCUR_S);
|
||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
||||
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FSM_EN_M);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -542,9 +542,10 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
|
||||
esp_err_t esp_sleep_enable_ulp_wakeup(void)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
#if ((defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT) || (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2))
|
||||
ESP_LOGE(TAG, "Failed to enable wakeup when provide current to external 32kHz crystal");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
#endif
|
||||
#ifdef CONFIG_ESP32_ULP_COPROC_ENABLED
|
||||
if(s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
|
||||
ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
|
||||
@ -596,7 +597,8 @@ static void touch_wakeup_prepare(void)
|
||||
|
||||
esp_err_t esp_sleep_enable_touchpad_wakeup(void)
|
||||
{
|
||||
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
#if ((defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT) || (defined CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_V2))
|
||||
ESP_LOGE(TAG, "Failed to enable wakeup when provide current to external 32kHz crystal");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
#endif
|
||||
if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) {
|
||||
|
@ -233,6 +233,7 @@ static inline void touch_ll_get_tie_option(touch_pad_t touch_num, touch_tie_opt_
|
||||
*/
|
||||
static inline void touch_ll_set_fsm_mode(touch_fsm_mode_t mode)
|
||||
{
|
||||
SENS.sar_touch_ctrl2.touch_start_fsm_en = 1;
|
||||
SENS.sar_touch_ctrl2.touch_start_en = 0;
|
||||
SENS.sar_touch_ctrl2.touch_start_force = mode;
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ void app_main(void)
|
||||
{
|
||||
// Initialize touch pad peripheral, it will start a timer to run a filter
|
||||
ESP_LOGI(TAG, "Initializing touch pad");
|
||||
touch_pad_init();
|
||||
ESP_ERROR_CHECK(touch_pad_init());
|
||||
// If use interrupt trigger mode, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'.
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||
// Set reference voltage for charging/discharging
|
||||
|
@ -57,7 +57,7 @@ void app_main(void)
|
||||
{
|
||||
// Initialize touch pad peripheral.
|
||||
// The default fsm mode is software trigger mode.
|
||||
touch_pad_init();
|
||||
ESP_ERROR_CHECK(touch_pad_init());
|
||||
// Set reference voltage for charging/discharging
|
||||
// In this case, the high reference valtage will be 2.7V - 1V = 1.7V
|
||||
// The low reference voltage will be 0.5
|
||||
|
@ -159,7 +159,7 @@ void app_main(void)
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
// Initialize touch pad peripheral.
|
||||
// The default fsm mode is software trigger mode.
|
||||
touch_pad_init();
|
||||
ESP_ERROR_CHECK(touch_pad_init());
|
||||
// If use touch pad wake up, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'.
|
||||
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||
// Set reference voltage for charging/discharging
|
||||
|
Loading…
Reference in New Issue
Block a user