mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
ESP32: Fix xtal 32k not oscillate or oscillate too slowly issue
ESP32 in revision0 and revision1 uses touchpad to provide current to oscillate xtal 32k. But revision2 and revision3 do not need to do that. Note: touchpad can not work and toupad/ULP wakeup sources are not available when toupad provides current to xtal 32k
This commit is contained in:
parent
23e8233506
commit
9100cd558e
@ -276,6 +276,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();
|
||||
}
|
||||
|
@ -30,6 +30,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);
|
||||
|
||||
|
@ -590,18 +590,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"
|
||||
|
@ -407,7 +407,8 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
|
||||
|
||||
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;
|
||||
#endif
|
||||
#ifdef CONFIG_ESP32_ULP_COPROC_ENABLED
|
||||
@ -443,7 +444,8 @@ static void timer_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)) {
|
||||
|
@ -53,7 +53,13 @@ if(IDF_TARGET STREQUAL "esp32s2beta")
|
||||
list(APPEND srcs "src/hal/spi_flash_hal_gpspi.c")
|
||||
endif()
|
||||
|
||||
set(priv_requires ${soc_name})
|
||||
if(${soc_name} STREQUAL "esp32")
|
||||
# For rtc_clk.c
|
||||
list(APPEND priv_requires efuse)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
PRIV_REQUIRES ${soc_name}
|
||||
PRIV_REQUIRES ${priv_requires}
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
@ -228,6 +228,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;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "esp32/rom/rtc.h"
|
||||
#include "esp32/rom/uart.h"
|
||||
#include "esp32/rom/gpio.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/sens_periph.h"
|
||||
@ -57,7 +58,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
|
||||
|
||||
@ -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);
|
||||
|
||||
#ifdef 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, 4, RTC_IO_TOUCH_PAD8_DAC_S);
|
||||
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);
|
||||
#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
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);
|
||||
}
|
||||
@ -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);
|
||||
|
||||
#ifdef 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);
|
||||
#endif // CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT
|
||||
}
|
||||
#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
|
||||
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
|
||||
|
@ -155,7 +155,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