From 5ba87240b5e4e7294077a7c714243656477b208b Mon Sep 17 00:00:00 2001 From: Zhang Jun Yi Date: Wed, 23 May 2018 15:24:09 +0800 Subject: [PATCH] soc/rtc: Bypass touchpad current to external 32k crystal oscillator --- components/soc/esp32/rtc_clk.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/components/soc/esp32/rtc_clk.c b/components/soc/esp32/rtc_clk.c index 43964448c..9a7278bce 100644 --- a/components/soc/esp32/rtc_clk.c +++ b/components/soc/esp32/rtc_clk.c @@ -58,7 +58,7 @@ #define APLL_CAL_DELAY_2 0x3f #define APLL_CAL_DELAY_3 0x1f -#define XTAL_32K_DAC_VAL 1 +#define XTAL_32K_DAC_VAL 3 #define XTAL_32K_DRES_VAL 3 #define XTAL_32K_DBIAS_VAL 0 @@ -114,14 +114,34 @@ static const char* TAG = "rtc_clk"; static void rtc_clk_32k_enable_common(int dac, int dres, int dbias) { - SET_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_X32P_RDE | RTC_IO_X32P_RUE | RTC_IO_X32N_RUE | - RTC_IO_X32N_RDE | RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL); + RTC_IO_X32P_RDE | RTC_IO_X32P_RUE | RTC_IO_X32N_RUE | + RTC_IO_X32N_RDE | RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL); + SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL | RTC_IO_X32P_MUX_SEL); + /* Set the parameters of xtal + dac --> current + dres --> resistance + dbias --> bais voltage + */ REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DAC_XTAL_32K, dac); REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DRES_XTAL_32K, dres); REG_SET_FIELD(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_DBIAS_XTAL_32K, dbias); - SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K); + + /* 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); + /* Power up external xtal */ + SET_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K_M); } void rtc_clk_32k_enable(bool enable) @@ -129,7 +149,10 @@ void rtc_clk_32k_enable(bool enable) if (enable) { rtc_clk_32k_enable_common(XTAL_32K_DAC_VAL, XTAL_32K_DRES_VAL, XTAL_32K_DBIAS_VAL); } else { + /* Disable X32N and X32P pad drive external xtal */ CLEAR_PERI_REG_MASK(RTC_IO_XTAL_32K_PAD_REG, RTC_IO_XPD_XTAL_32K); + /* Power down TOUCH */ + CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD9_REG, RTC_IO_TOUCH_PAD9_XPD_M); } }