sleep: restore analog calibration registers after waking up from light sleep

Closes https://github.com/espressif/esp-idf/issues/8287
Closes https://github.com/espressif/esp-idf/issues/7921
This commit is contained in:
Armando
2022-01-25 14:23:53 +08:00
parent d7512d8b38
commit 494b996ecc
13 changed files with 156 additions and 51 deletions

View File

@@ -1,5 +1,5 @@
target_include_directories(${COMPONENT_LIB} PUBLIC .) target_include_directories(${COMPONENT_LIB} PUBLIC .)
target_include_directories(${COMPONENT_LIB} PRIVATE private_include) target_include_directories(${COMPONENT_LIB} PUBLIC private_include)
set(srcs set(srcs
"rtc_clk.c" "rtc_clk.c"

View File

@@ -77,3 +77,10 @@
#define I2C_SARADC_TSENS_DAC 0x6 #define I2C_SARADC_TSENS_DAC 0x6
#define I2C_SARADC_TSENS_DAC_MSB 3 #define I2C_SARADC_TSENS_DAC_MSB 3
#define I2C_SARADC_TSENS_DAC_LSB 0 #define I2C_SARADC_TSENS_DAC_LSB 0
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#define REGI2C_ANA_CALI_PD_WORKAROUND 1
#define REGI2C_ANA_CALI_BYTE_NUM 8

View File

@@ -83,6 +83,16 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add,
#define REGI2C_READ(block, reg_add) \ #define REGI2C_READ(block, reg_add) \
regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add)
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#if REGI2C_ANA_CALI_PD_WORKAROUND
void regi2c_analog_cali_reg_read(void);
void regi2c_analog_cali_reg_write(void);
#endif //#if ADC_CALI_PD_WORKAROUND
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -77,3 +77,10 @@
#define I2C_SARADC_TSENS_DAC 0x6 #define I2C_SARADC_TSENS_DAC 0x6
#define I2C_SARADC_TSENS_DAC_MSB 3 #define I2C_SARADC_TSENS_DAC_MSB 3
#define I2C_SARADC_TSENS_DAC_LSB 0 #define I2C_SARADC_TSENS_DAC_LSB 0
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#define REGI2C_ANA_CALI_PD_WORKAROUND 1
#define REGI2C_ANA_CALI_BYTE_NUM 8

View File

@@ -82,6 +82,16 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add,
#define REGI2C_READ(block, reg_add) \ #define REGI2C_READ(block, reg_add) \
regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add)
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#if REGI2C_ANA_CALI_PD_WORKAROUND
void regi2c_analog_cali_reg_read(void);
void regi2c_analog_cali_reg_write(void);
#endif //#if ADC_CALI_PD_WORKAROUND
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -73,3 +73,10 @@
#define I2C_SARADC_TSENS_DAC 0x6 #define I2C_SARADC_TSENS_DAC 0x6
#define I2C_SARADC_TSENS_DAC_MSB 3 #define I2C_SARADC_TSENS_DAC_MSB 3
#define I2C_SARADC_TSENS_DAC_LSB 0 #define I2C_SARADC_TSENS_DAC_LSB 0
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#define REGI2C_ANA_CALI_PD_WORKAROUND 1
#define REGI2C_ANA_CALI_BYTE_NUM 8

View File

@@ -77,6 +77,16 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add,
#define REGI2C_READ(block, reg_add) \ #define REGI2C_READ(block, reg_add) \
regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add)
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#if REGI2C_ANA_CALI_PD_WORKAROUND
void regi2c_analog_cali_reg_read(void);
void regi2c_analog_cali_reg_write(void);
#endif //#if ADC_CALI_PD_WORKAROUND
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -235,50 +235,50 @@ static void set_ocode_by_efuse(int calib_version)
*/ */
static void calibrate_ocode(void) static void calibrate_ocode(void)
{ {
// /* /*
// Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL). Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL).
// Method: Method:
// 1. read current cpu config, save in old_config; 1. read current cpu config, save in old_config;
// 2. switch cpu to xtal because PLL will be closed when o-code calibration; 2. switch cpu to xtal because PLL will be closed when o-code calibration;
// 3. begin o-code calibration; 3. begin o-code calibration;
// 4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout; 4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout;
// 5. set cpu to old-config. 5. set cpu to old-config.
// */ */
// rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get(); rtc_slow_freq_t slow_clk_freq = rtc_clk_slow_freq_get();
// rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL; rtc_slow_freq_t rtc_slow_freq_x32k = RTC_SLOW_FREQ_32K_XTAL;
// rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256; rtc_slow_freq_t rtc_slow_freq_8MD256 = RTC_SLOW_FREQ_8MD256;
// rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX; rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX;
// if (slow_clk_freq == (rtc_slow_freq_x32k)) { if (slow_clk_freq == (rtc_slow_freq_x32k)) {
// cal_clk = RTC_CAL_32K_XTAL; cal_clk = RTC_CAL_32K_XTAL;
// } else if (slow_clk_freq == rtc_slow_freq_8MD256) { } else if (slow_clk_freq == rtc_slow_freq_8MD256) {
// cal_clk = RTC_CAL_8MD256; cal_clk = RTC_CAL_8MD256;
// } }
// uint64_t max_delay_time_us = 10000; uint64_t max_delay_time_us = 10000;
// uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100); uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100);
// uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period); uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period);
// uint64_t cycle0 = rtc_time_get(); uint64_t cycle0 = rtc_time_get();
// uint64_t timeout_cycle = cycle0 + max_delay_cycle; uint64_t timeout_cycle = cycle0 + max_delay_cycle;
// uint64_t cycle1 = 0; uint64_t cycle1 = 0;
// rtc_cpu_freq_config_t old_config; rtc_cpu_freq_config_t old_config;
// rtc_clk_cpu_freq_get_config(&old_config); rtc_clk_cpu_freq_get_config(&old_config);
// rtc_clk_cpu_freq_set_xtal(); rtc_clk_cpu_freq_set_xtal();
// REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0); REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0);
// REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1); REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1);
// bool odone_flag = 0; bool odone_flag = 0;
// bool bg_odone_flag = 0; bool bg_odone_flag = 0;
// while(1) { while(1) {
// odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG); odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG);
// bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG); bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG);
// cycle1 = rtc_time_get(); cycle1 = rtc_time_get();
// if (odone_flag && bg_odone_flag) if (odone_flag && bg_odone_flag)
// break; break;
// if (cycle1 >= timeout_cycle) { if (cycle1 >= timeout_cycle) {
// SOC_LOGW(TAG, "o_code calibration fail"); SOC_LOGW(TAG, "o_code calibration fail");
// break; break;
// } }
// } }
// rtc_clk_cpu_freq_set_config(&old_config); rtc_clk_cpu_freq_set_config(&old_config);
} }

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -73,3 +73,10 @@
#define I2C_SARADC_TSENS_DAC 0x6 #define I2C_SARADC_TSENS_DAC 0x6
#define I2C_SARADC_TSENS_DAC_MSB 3 #define I2C_SARADC_TSENS_DAC_MSB 3
#define I2C_SARADC_TSENS_DAC_LSB 0 #define I2C_SARADC_TSENS_DAC_LSB 0
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#define REGI2C_ANA_CALI_PD_WORKAROUND 1
#define REGI2C_ANA_CALI_BYTE_NUM 8

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -81,6 +81,15 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add,
regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add) regi2c_ctrl_read_reg(block, block##_HOSTID, reg_add)
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#if REGI2C_ANA_CALI_PD_WORKAROUND
void regi2c_analog_cali_reg_read(void);
void regi2c_analog_cali_reg_write(void);
#endif //#if ADC_CALI_PD_WORKAROUND
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -1,10 +1,11 @@
/* /*
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include "regi2c_ctrl.h" #include "regi2c_ctrl.h"
#include "esp_attr.h"
#include <stdint.h> #include <stdint.h>
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/semphr.h> #include <freertos/semphr.h>
@@ -40,3 +41,27 @@ void IRAM_ATTR regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_
i2c_write_reg_mask_raw(block, host_id, reg_add, msb, lsb, data); i2c_write_reg_mask_raw(block, host_id, reg_add, msb, lsb, data);
portEXIT_CRITICAL_ISR(&mux); portEXIT_CRITICAL_ISR(&mux);
} }
/**
* Restore regi2c analog calibration related configuration registers.
* This is a workaround, and is fixed on later chips
*/
#if REGI2C_ANA_CALI_PD_WORKAROUND
static DRAM_ATTR uint8_t reg_val[REGI2C_ANA_CALI_BYTE_NUM];
void IRAM_ATTR regi2c_analog_cali_reg_read(void)
{
for (int i = 0; i < REGI2C_ANA_CALI_PD_WORKAROUND; i++) {
reg_val[i] = regi2c_ctrl_read_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i);
}
}
void IRAM_ATTR regi2c_analog_cali_reg_write(void)
{
for (int i = 0; i < REGI2C_ANA_CALI_PD_WORKAROUND; i++) {
regi2c_ctrl_write_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i, reg_val[i]);
}
}
#endif //#if ADC_CALI_PD_WORKAROUND

View File

@@ -27,6 +27,7 @@
#include "soc/rtc.h" #include "soc/rtc.h"
#include "soc/soc_caps.h" #include "soc/soc_caps.h"
#include "regi2c_ctrl.h" //For `REGI2C_ANA_CALI_PD_WORKAROUND`, temp
#include "hal/wdt_hal.h" #include "hal/wdt_hal.h"
#include "hal/rtc_hal.h" #include "hal/rtc_hal.h"
@@ -319,6 +320,9 @@ static void IRAM_ATTR resume_uarts(void)
} }
} }
/**
* These save-restore workaround should be moved to lower layer
*/
inline static void IRAM_ATTR misc_modules_sleep_prepare(void) inline static void IRAM_ATTR misc_modules_sleep_prepare(void)
{ {
#if CONFIG_MAC_BB_PD #if CONFIG_MAC_BB_PD
@@ -330,8 +334,14 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(void)
#if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD #if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD
sleep_enable_memory_retention(); sleep_enable_memory_retention();
#endif #endif
#if REGI2C_ANA_CALI_PD_WORKAROUND
regi2c_analog_cali_reg_read();
#endif
} }
/**
* These save-restore workaround should be moved to lower layer
*/
inline static void IRAM_ATTR misc_modules_wake_prepare(void) inline static void IRAM_ATTR misc_modules_wake_prepare(void)
{ {
#if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD #if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD
@@ -343,6 +353,9 @@ inline static void IRAM_ATTR misc_modules_wake_prepare(void)
#if CONFIG_MAC_BB_PD #if CONFIG_MAC_BB_PD
mac_bb_power_up_cb_execute(); mac_bb_power_up_cb_execute();
#endif #endif
#if REGI2C_ANA_CALI_PD_WORKAROUND
regi2c_analog_cali_reg_write();
#endif
} }
inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu); inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu);

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -566,8 +566,8 @@ static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
return (uint32_t)adc_ll_rtc_get_convert_value(adc_n); return (uint32_t)adc_ll_rtc_get_convert_value(adc_n);
} }
#elif SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
//For those RTC controller not supported chips, they use digital controller to do the single read. e.g.: esp32c3 //For those RTC controller not supported chips, they use digital controller to do the single read. e.g.: esp32c3
#elif SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd) static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
{ {
adc_ll_onetime_sample_enable(ADC_NUM_1, false); adc_ll_onetime_sample_enable(ADC_NUM_1, false);