mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-08 07:04:32 +02:00
Merge branch 'bugfix/fix_adc_calibration_light_sleep_issue' into 'master'
adc: fix calibration error when waking up from light sleep Closes IDF-4406, IDF-4605, IDFGH-6252, and IDFGH-6651 See merge request espressif/esp-idf!16259
This commit is contained in:
@@ -9,19 +9,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "test_utils.h"
|
#include "test_utils.h"
|
||||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
|
|
||||||
// TODO: Support ADC IDF-3908
|
|
||||||
#include "esp_adc_cal.h"
|
#include "esp_adc_cal.h"
|
||||||
#include "driver/adc.h"
|
#include "driver/adc_common.h"
|
||||||
|
|
||||||
static const char *TAG = "ADC";
|
__attribute__((unused)) static const char *TAG = "ADC";
|
||||||
|
|
||||||
|
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2)
|
||||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3, ESP32C3) //TODO: IDF-3160
|
//TODO: IDF-3160
|
||||||
//API only supported for C3 now.
|
|
||||||
|
|
||||||
#include "esp_adc_cal.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
|
|
||||||
#define TEST_COUNT 4096
|
#define TEST_COUNT 4096
|
||||||
#define MAX_ARRAY_SIZE 4096
|
#define MAX_ARRAY_SIZE 4096
|
||||||
@@ -282,12 +276,10 @@ TEST_CASE("test_adc_single", "[adc][ignore][manual]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3)
|
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) //TODO IDF-3908
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* ADC Speed Related Tests
|
* ADC Speed Related Tests
|
||||||
@@ -400,4 +392,222 @@ TEST_CASE("test_adc_single_cali_time", "[adc][ignore][manual]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2)
|
|
||||||
|
/********************************************************************************
|
||||||
|
* ADC Single with Light Sleep
|
||||||
|
********************************************************************************/
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "esp_sleep.h"
|
||||||
|
#include "regi2c_ctrl.h"
|
||||||
|
|
||||||
|
//ADC Channels
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
#define ADC1_SLEEP_TEST_CHAN ADC1_CHANNEL_6
|
||||||
|
#define ADC2_SLEEP_TEST_CHAN ADC2_CHANNEL_0
|
||||||
|
static const char *TAG_CH[2][10] = {{"ADC1_CH6"}, {"ADC2_CH0"}};
|
||||||
|
#else
|
||||||
|
#define ADC1_SLEEP_TEST_CHAN ADC1_CHANNEL_2
|
||||||
|
#define ADC2_SLEEP_TEST_CHAN ADC2_CHANNEL_0
|
||||||
|
static const char *TAG_CH[2][10] = {{"ADC1_CH2"}, {"ADC2_CH0"}};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//ADC Attenuation
|
||||||
|
#define ADC_SLEEP_TEST_ATTEN ADC_ATTEN_DB_6
|
||||||
|
|
||||||
|
//ADC Calibration
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
#define ADC_SLEEP_TEST_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_VREF
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
#define ADC_SLEEP_TEST_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||||
|
#define ADC_SLEEP_TEST_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP
|
||||||
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#define ADC_SLEEP_TEST_CALI_SCHEME ESP_ADC_CAL_VAL_EFUSE_TP_FIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static esp_adc_cal_characteristics_t adc1_chars;
|
||||||
|
static esp_adc_cal_characteristics_t adc2_chars;
|
||||||
|
|
||||||
|
|
||||||
|
static bool adc_calibration_init(void)
|
||||||
|
{
|
||||||
|
esp_err_t ret;
|
||||||
|
bool cali_enable = false;
|
||||||
|
|
||||||
|
ret = esp_adc_cal_check_efuse(ADC_SLEEP_TEST_CALI_SCHEME);
|
||||||
|
if (ret == ESP_ERR_NOT_SUPPORTED) {
|
||||||
|
ESP_LOGW(TAG, "Calibration scheme not supported, skip software calibration");
|
||||||
|
} else if (ret == ESP_ERR_INVALID_VERSION) {
|
||||||
|
ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
|
||||||
|
} else if (ret == ESP_OK) {
|
||||||
|
cali_enable = true;
|
||||||
|
esp_adc_cal_characterize(ADC_UNIT_1, ADC_SLEEP_TEST_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars);
|
||||||
|
esp_adc_cal_characterize(ADC_UNIT_2, ADC_SLEEP_TEST_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc2_chars);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Invalid arg");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cali_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_REGI2C_ANA_CALI_BYTE_NUM 8
|
||||||
|
|
||||||
|
TEST_CASE("test ADC1 Single Read with Light Sleep", "[adc][manul][ignore]")
|
||||||
|
{
|
||||||
|
//ADC1 config
|
||||||
|
TEST_ESP_OK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT));
|
||||||
|
TEST_ESP_OK(adc1_config_channel_atten(ADC1_SLEEP_TEST_CHAN, ADC_SLEEP_TEST_ATTEN));
|
||||||
|
|
||||||
|
//ADC config calibration
|
||||||
|
bool cali_en = adc_calibration_init();
|
||||||
|
|
||||||
|
int raw_expected = 0;
|
||||||
|
uint32_t cali_expected = 0;
|
||||||
|
uint8_t regi2c_cali_val_before[TEST_REGI2C_ANA_CALI_BYTE_NUM] = {};
|
||||||
|
|
||||||
|
int raw_after_sleep = 0;
|
||||||
|
uint32_t cali_after_sleep = 0;
|
||||||
|
uint8_t regi2c_cali_val_after[TEST_REGI2C_ANA_CALI_BYTE_NUM] = {};
|
||||||
|
|
||||||
|
//---------------------------------Before Sleep-----------------------------------//
|
||||||
|
ESP_LOGI("Before", "Light Sleep");
|
||||||
|
|
||||||
|
//Read
|
||||||
|
raw_expected = adc1_get_raw(ADC1_SLEEP_TEST_CHAN);
|
||||||
|
if (cali_en) {
|
||||||
|
cali_expected = esp_adc_cal_raw_to_voltage(raw_expected, &adc1_chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if REGI2C_ANA_CALI_PD_WORKAROUND
|
||||||
|
//Print regi2c
|
||||||
|
for (int i = 0; i < TEST_REGI2C_ANA_CALI_BYTE_NUM; i++) {
|
||||||
|
regi2c_cali_val_before[i] = regi2c_ctrl_read_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i);
|
||||||
|
printf("regi2c cali val is 0x%x", regi2c_cali_val_before[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Print result
|
||||||
|
ESP_LOGI(TAG_CH[0][0], "ADC1 raw data: %d", raw_expected);
|
||||||
|
if (cali_en) {
|
||||||
|
ESP_LOGI(TAG_CH[0][0], "ADC1 cali data: %d", cali_expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------After Sleep-----------------------------------//
|
||||||
|
ESP_LOGI("After", "Light Sleep");
|
||||||
|
esp_sleep_enable_timer_wakeup(30 * 1000);
|
||||||
|
esp_light_sleep_start();
|
||||||
|
ESP_LOGI(TAG, "Wakeup from light sleep.");
|
||||||
|
|
||||||
|
#if REGI2C_ANA_CALI_PD_WORKAROUND
|
||||||
|
//Print regi2c
|
||||||
|
for (int i = 0; i < TEST_REGI2C_ANA_CALI_BYTE_NUM; i++) {
|
||||||
|
regi2c_cali_val_after[i] = regi2c_ctrl_read_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i);
|
||||||
|
printf("regi2c cali val is 0x%x", regi2c_cali_val_after[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Read
|
||||||
|
raw_after_sleep = adc1_get_raw(ADC1_SLEEP_TEST_CHAN);
|
||||||
|
if (cali_en) {
|
||||||
|
cali_after_sleep = esp_adc_cal_raw_to_voltage(raw_after_sleep, &adc1_chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Print result
|
||||||
|
ESP_LOGI(TAG_CH[0][0], "after light sleep, ADC1 cali data: %d", raw_after_sleep);
|
||||||
|
if (cali_en) {
|
||||||
|
ESP_LOGI(TAG_CH[0][0], "after light sleep, ADC1 cali data: %d", cali_after_sleep);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Compare
|
||||||
|
int32_t raw_diff = raw_expected - raw_after_sleep;
|
||||||
|
IDF_LOG_PERFORMANCE("ADC1 raw diff after sleep", "%d", raw_diff);
|
||||||
|
if (cali_en) {
|
||||||
|
int32_t cali_diff = cali_expected - cali_after_sleep;
|
||||||
|
IDF_LOG_PERFORMANCE("ADC1 cali diff after sleep", "%d mV", cali_diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < TEST_REGI2C_ANA_CALI_BYTE_NUM; i++) {
|
||||||
|
TEST_ASSERT_EQUAL(regi2c_cali_val_before[i], regi2c_cali_val_after[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("test ADC2 Single Read with Light Sleep", "[adc][manul][ignore]")
|
||||||
|
{
|
||||||
|
//ADC2 config
|
||||||
|
ESP_ERROR_CHECK(adc2_config_channel_atten(ADC2_SLEEP_TEST_CHAN, ADC_SLEEP_TEST_ATTEN));
|
||||||
|
//ADC config calibration
|
||||||
|
bool cali_en = adc_calibration_init();
|
||||||
|
|
||||||
|
int raw_expected = 0;
|
||||||
|
uint32_t cali_expected = 0;
|
||||||
|
uint8_t regi2c_cali_val_before[TEST_REGI2C_ANA_CALI_BYTE_NUM] = {};
|
||||||
|
|
||||||
|
int raw_after_sleep = 0;
|
||||||
|
uint32_t cali_after_sleep = 0;
|
||||||
|
uint8_t regi2c_cali_val_after[TEST_REGI2C_ANA_CALI_BYTE_NUM] = {};
|
||||||
|
|
||||||
|
//---------------------------------Before Sleep-----------------------------------//
|
||||||
|
ESP_LOGI("Before", "Light Sleep");
|
||||||
|
|
||||||
|
//Read
|
||||||
|
TEST_ESP_OK(adc2_get_raw(ADC2_SLEEP_TEST_CHAN, ADC_WIDTH_BIT_DEFAULT, &raw_expected));
|
||||||
|
if (cali_en) {
|
||||||
|
cali_expected = esp_adc_cal_raw_to_voltage(raw_expected, &adc2_chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if REGI2C_ANA_CALI_PD_WORKAROUND
|
||||||
|
//Print regi2c
|
||||||
|
for (int i = 0; i < TEST_REGI2C_ANA_CALI_BYTE_NUM; i++) {
|
||||||
|
regi2c_cali_val_before[i] = regi2c_ctrl_read_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i);
|
||||||
|
printf("regi2c cali val is 0x%x", regi2c_cali_val_before[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Print result
|
||||||
|
ESP_LOGI(TAG_CH[1][0], "ADC2 raw data: %d", raw_expected);
|
||||||
|
if (cali_en) {
|
||||||
|
ESP_LOGI(TAG_CH[1][0], "ADC2 cali data: %d", cali_expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------After Sleep-----------------------------------//
|
||||||
|
ESP_LOGI("After", "Light Sleep");
|
||||||
|
esp_sleep_enable_timer_wakeup(30 * 1000);
|
||||||
|
esp_light_sleep_start();
|
||||||
|
ESP_LOGI(TAG, "Wakeup from light sleep.");
|
||||||
|
|
||||||
|
#if REGI2C_ANA_CALI_PD_WORKAROUND
|
||||||
|
//Print regi2c
|
||||||
|
for (int i = 0; i < TEST_REGI2C_ANA_CALI_BYTE_NUM; i++) {
|
||||||
|
regi2c_cali_val_after[i] = regi2c_ctrl_read_reg(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, i);
|
||||||
|
printf("regi2c cali val is 0x%x", regi2c_cali_val_after[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Read
|
||||||
|
TEST_ESP_OK(adc2_get_raw(ADC2_SLEEP_TEST_CHAN, ADC_WIDTH_BIT_DEFAULT, &raw_after_sleep));
|
||||||
|
if (cali_en) {
|
||||||
|
cali_after_sleep += esp_adc_cal_raw_to_voltage(raw_after_sleep, &adc2_chars);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Print result
|
||||||
|
ESP_LOGI(TAG_CH[1][0], "after light sleep, ADC2 cali data: %d", raw_after_sleep);
|
||||||
|
if (cali_en) {
|
||||||
|
ESP_LOGI(TAG_CH[1][0], "after light sleep, ADC2 cali data: %d", cali_after_sleep);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Compare
|
||||||
|
int32_t raw_diff = raw_expected - raw_after_sleep;
|
||||||
|
IDF_LOG_PERFORMANCE("ADC2 raw diff after sleep", "%d", raw_diff);
|
||||||
|
if (cali_en) {
|
||||||
|
int32_t cali_diff = cali_expected - cali_after_sleep;
|
||||||
|
IDF_LOG_PERFORMANCE("ADC2 cali diff after sleep", "%d mV", cali_diff);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < TEST_REGI2C_ANA_CALI_BYTE_NUM; i++) {
|
||||||
|
TEST_ASSERT_EQUAL(regi2c_cali_val_before[i], regi2c_cali_val_after[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) //TODO IDF-3908
|
||||||
|
@@ -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"
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user