mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 20:24:32 +02:00
Merge branch 'bugfix/fix_x32k_startup_slow_bug_v4.2' into 'release/v4.2'
bugfix: Fix xtal 32k not oscillate or oscillate too slowly issue for esp32 (v4.2) See merge request espressif/esp-idf!17591
This commit is contained in:
@@ -289,6 +289,10 @@ esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold)
|
|||||||
|
|
||||||
esp_err_t touch_pad_init(void)
|
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) {
|
if (rtc_touch_mux == NULL) {
|
||||||
rtc_touch_mux = xSemaphoreCreateMutex();
|
rtc_touch_mux = xSemaphoreCreateMutex();
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ extern "C" {
|
|||||||
* @return
|
* @return
|
||||||
* - ESP_OK Success
|
* - ESP_OK Success
|
||||||
* - ESP_ERR_NO_MEM Touch pad init error
|
* - 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);
|
esp_err_t touch_pad_init(void);
|
||||||
|
|
||||||
|
@@ -564,18 +564,35 @@ menu "ESP32-specific"
|
|||||||
bool "Internal 8.5MHz oscillator, divided by 256 (~33kHz)"
|
bool "Internal 8.5MHz oscillator, divided by 256 (~33kHz)"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
choice ESP32_RTC_EXT_CRYST_ADDIT_CURRENT_METHOD
|
||||||
bool "Additional current for external 32kHz crystal"
|
prompt "Additional current for external 32kHz crystal"
|
||||||
depends on ESP32_RTC_CLK_SRC_EXT_CRYS
|
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
|
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
|
This problem is fixed in ESP32 ECO 3, so this workaround is not needed. Setting the
|
||||||
have enough drive strength to keep the crystal oscillating during deep sleep.
|
project configuration to minimum revision ECO3 will disable this option, , allow
|
||||||
If this option is enabled, additional current from touchpad 9 is provided
|
all wakeup sources, and save some code size.
|
||||||
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.
|
- "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
|
config ESP32_RTC_CLK_CAL_CYCLES
|
||||||
int "Number of cycles for RTC_SLOW_CLK calibration"
|
int "Number of cycles for RTC_SLOW_CLK calibration"
|
||||||
|
@@ -419,7 +419,8 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
|
|||||||
|
|
||||||
esp_err_t esp_sleep_enable_ulp_wakeup(void)
|
esp_err_t esp_sleep_enable_ulp_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;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ESP32_ULP_COPROC_ENABLED
|
#ifdef CONFIG_ESP32_ULP_COPROC_ENABLED
|
||||||
@@ -455,7 +456,8 @@ static void timer_wakeup_prepare(void)
|
|||||||
|
|
||||||
esp_err_t esp_sleep_enable_touchpad_wakeup(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;
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) {
|
if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN)) {
|
||||||
|
@@ -38,8 +38,14 @@ if(NOT BOOTLOADER_BUILD)
|
|||||||
list(APPEND srcs "src/regi2c_ctrl.c")
|
list(APPEND srcs "src/regi2c_ctrl.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(priv_requires ${target})
|
||||||
|
if(${target} STREQUAL "esp32")
|
||||||
|
# For RTC_EXT_CRYST_ADDIT_CURRENT to get chip revision in rtc_clk.c
|
||||||
|
list(APPEND priv_requires efuse)
|
||||||
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES ${target}
|
PRIV_REQUIRES ${priv_requires}
|
||||||
LDFRAGMENTS linker.lf)
|
LDFRAGMENTS linker.lf)
|
||||||
|
|
||||||
if(CONFIG_IDF_TARGET_ESP32)
|
if(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
@@ -237,6 +237,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)
|
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_en = 0;
|
||||||
SENS.sar_touch_ctrl2.touch_start_force = mode;
|
SENS.sar_touch_ctrl2.touch_start_force = mode;
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include "esp32/rom/rtc.h"
|
#include "esp32/rom/rtc.h"
|
||||||
#include "esp32/rom/uart.h"
|
#include "esp32/rom/uart.h"
|
||||||
#include "esp32/rom/gpio.h"
|
#include "esp32/rom/gpio.h"
|
||||||
|
#include "esp_efuse.h"
|
||||||
#include "soc/rtc.h"
|
#include "soc/rtc.h"
|
||||||
#include "soc/rtc_periph.h"
|
#include "soc/rtc_periph.h"
|
||||||
#include "soc/sens_periph.h"
|
#include "soc/sens_periph.h"
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
#define APLL_CAL_DELAY_2 0x3f
|
#define APLL_CAL_DELAY_2 0x3f
|
||||||
#define APLL_CAL_DELAY_3 0x1f
|
#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_DRES_VAL 3
|
||||||
#define XTAL_32K_DBIAS_VAL 0
|
#define XTAL_32K_DBIAS_VAL 0
|
||||||
|
|
||||||
@@ -126,20 +127,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);
|
REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DBIAS_XTAL_32K, dbias);
|
||||||
|
|
||||||
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||||
/* TOUCH sensor can provide additional current to external XTAL.
|
uint8_t chip_ver = esp_efuse_get_chip_ver();
|
||||||
In some case, X32N and X32P PAD don't have enough drive capability to start XTAL */
|
// version0 and version1 need provide additional current to external XTAL.
|
||||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS_M);
|
if(chip_ver == 0 || chip_ver == 1) {
|
||||||
/* Tie PAD Touch8 to VDD
|
/* TOUCH sensor can provide additional current to external XTAL.
|
||||||
NOTE: TOUCH8 and TOUCH9 register settings are reversed except for DAC, so we set RTC_IO_TOUCH_PAD9_REG here instead
|
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_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_TIE_OPT_M);
|
/* Tie PAD Touch8 to VDD
|
||||||
/* Set the current used to compensate TOUCH PAD8 */
|
NOTE: TOUCH8 and TOUCH9 register settings are reversed except for DAC, so we set RTC_IO_TOUCH_PAD9_REG here instead*/
|
||||||
SET_PERI_REG_BITS(RTC_IO_TOUCH_PAD8_REG, RTC_IO_TOUCH_PAD8_DAC, 4, RTC_IO_TOUCH_PAD8_DAC_S);
|
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_TIE_OPT_M);
|
||||||
/* Power up TOUCH8
|
/* Set the current used to compensate TOUCH PAD8 */
|
||||||
So the Touch DAC start to drive some current from VDD to TOUCH8(which is also XTAL-N)
|
SET_PERI_REG_BITS(RTC_IO_TOUCH_PAD8_REG, RTC_IO_TOUCH_PAD8_DAC, 4, RTC_IO_TOUCH_PAD8_DAC_S);
|
||||||
*/
|
/* Power up TOUCH8
|
||||||
SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
So the Touch DAC start to drive some current from VDD to TOUCH8(which is also XTAL-N)*/
|
||||||
#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
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 */
|
/* Power up external xtal */
|
||||||
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M);
|
SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M);
|
||||||
}
|
}
|
||||||
@@ -154,9 +177,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);
|
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
|
#ifdef CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||||
/* Power down TOUCH */
|
uint8_t chip_ver = esp_efuse_get_chip_ver();
|
||||||
CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M);
|
if(chip_ver == 0 || chip_ver == 1) {
|
||||||
#endif // 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);
|
||||||
|
}
|
||||||
|
#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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -151,7 +151,7 @@ void app_main(void)
|
|||||||
{
|
{
|
||||||
// Initialize touch pad peripheral, it will start a timer to run a filter
|
// Initialize touch pad peripheral, it will start a timer to run a filter
|
||||||
ESP_LOGI(TAG, "Initializing touch pad");
|
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'.
|
// 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);
|
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||||
// Set reference voltage for charging/discharging
|
// Set reference voltage for charging/discharging
|
||||||
|
@@ -57,7 +57,7 @@ void app_main(void)
|
|||||||
{
|
{
|
||||||
// Initialize touch pad peripheral.
|
// Initialize touch pad peripheral.
|
||||||
// The default fsm mode is software trigger mode.
|
// The default fsm mode is software trigger mode.
|
||||||
touch_pad_init();
|
ESP_ERROR_CHECK(touch_pad_init());
|
||||||
// Set reference voltage for charging/discharging
|
// Set reference voltage for charging/discharging
|
||||||
// In this case, the high reference valtage will be 2.7V - 1V = 1.7V
|
// In this case, the high reference valtage will be 2.7V - 1V = 1.7V
|
||||||
// The low reference voltage will be 0.5
|
// The low reference voltage will be 0.5
|
||||||
|
@@ -159,7 +159,7 @@ void app_main(void)
|
|||||||
#if CONFIG_IDF_TARGET_ESP32
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
// Initialize touch pad peripheral.
|
// Initialize touch pad peripheral.
|
||||||
// The default fsm mode is software trigger mode.
|
// 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'.
|
// 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);
|
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||||
// Set reference voltage for charging/discharging
|
// Set reference voltage for charging/discharging
|
||||||
|
Reference in New Issue
Block a user