Skip to content

Commit

Permalink
Merge branch 'feature/adc_calibration_on_c2' into 'master'
Browse files Browse the repository at this point in the history
esp_adc: support adc calibration on esp32c2

Closes IDF-5203 and IDF-5899

See merge request espressif/esp-idf!20044
  • Loading branch information
Icarus113 committed Oct 18, 2022
2 parents 0c41b9e + d592d98 commit 542bdea
Show file tree
Hide file tree
Showing 30 changed files with 532 additions and 148 deletions.
Expand Up @@ -47,11 +47,11 @@
#define ADC_TEST_HIGH_THRESH 0

#elif CONFIG_IDF_TARGET_ESP32C2
#define ADC_TEST_LOW_VAL 2147
#define ADC_TEST_LOW_THRESH 100
#define ADC_TEST_LOW_VAL 0
#define ADC_TEST_LOW_THRESH 15

#define ADC_TEST_HIGH_VAL 4095
#define ADC_TEST_HIGH_THRESH 0
#define ADC_TEST_HIGH_VAL 3400
#define ADC_TEST_HIGH_THRESH 200

#endif

Expand Down
Expand Up @@ -9,7 +9,6 @@
@pytest.mark.esp32s2
@pytest.mark.esp32s3
@pytest.mark.esp32c3
@pytest.mark.esp32c2
@pytest.mark.adc
@pytest.mark.parametrize(
'config',
Expand All @@ -22,3 +21,19 @@ def test_legacy_adc(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('*')
dut.expect_unity_test_output(timeout=240)


# All ESP32C2 ADC runners are 26m xtal
@pytest.mark.esp32c2
@pytest.mark.adc
@pytest.mark.parametrize(
'config, baud',
[
('esp32c2_xtal26m_release', '74880'),
],
indirect=True,
)
def test_legacy_adc_esp32c2_xtal_26mhz(dut: Dut) -> None:
dut.expect_exact('Press ENTER to see the list of tests')
dut.write('*')
dut.expect_unity_test_output(timeout=240)
@@ -0,0 +1,8 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_XTAL_FREQ_26=y

CONFIG_PM_ENABLE=y
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
94 changes: 91 additions & 3 deletions components/efuse/esp32c2/esp_efuse_rtc_calib.c
Expand Up @@ -5,14 +5,102 @@
*/

#include <esp_bit_defs.h>
#include "esp_log.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_rtc_calib.h"
#include "hal/adc_types.h"

int esp_efuse_rtc_calib_get_ver(void)
{
uint32_t result = 0;
esp_efuse_read_field_blob(ESP_EFUSE_BLK_VERSION_MINOR, &result, ESP_EFUSE_BLK_VERSION_MINOR[0]->bit_count); // IDF-5366
return result;
uint32_t blk_ver_major = 0;
esp_efuse_read_field_blob(ESP_EFUSE_BLK_VERSION_MAJOR, &blk_ver_major, ESP_EFUSE_BLK_VERSION_MAJOR[0]->bit_count); // IDF-5366

uint32_t cali_version = (blk_ver_major == 0) ? ESP_EFUSE_ADC_CALIB_VER : 0;
if (!cali_version) {
ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0");
}

return cali_version;
}

uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten)
{
assert(version == ESP_EFUSE_ADC_CALIB_VER);
assert(atten <= ADC_ATTEN_DB_11);
(void) adc_unit;

if (atten == ADC_ATTEN_DB_2_5 || atten == ADC_ATTEN_DB_6) {
/**
* - ESP32C2 only supports HW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11
* - For other attenuation, we just return default value, which is 0.
*/
return 0;
}

int32_t adc_icode_diff_atten0 = 0;
int32_t adc_icode_diff_atten3 = 0;
int efuse_icode_bits = 0;

efuse_icode_bits = esp_efuse_get_field_size(ESP_EFUSE_ADC1_INIT_CODE_ATTEN0);
ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_ADC1_INIT_CODE_ATTEN0, &adc_icode_diff_atten0, efuse_icode_bits));
adc_icode_diff_atten0 = ((adc_icode_diff_atten0 & BIT(7)) != 0) ? -(adc_icode_diff_atten0 & 0x7f): adc_icode_diff_atten0;

efuse_icode_bits = esp_efuse_get_field_size(ESP_EFUSE_ADC1_INIT_CODE_ATTEN3);
ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_ADC1_INIT_CODE_ATTEN3, &adc_icode_diff_atten3, efuse_icode_bits));

ESP_EARLY_LOGV("eFuse", "adc_icode_diff_atten0: 0d%"PRId32", adc_icode_diff_atten3: 0d%"PRId32, adc_icode_diff_atten0, adc_icode_diff_atten3);

uint32_t init_code = 0;
if (atten == ADC_ATTEN_DB_0) {
init_code = adc_icode_diff_atten0 + 2160;
} else {
//ADC_ATTEN_DB_11
init_code = adc_icode_diff_atten3 + adc_icode_diff_atten0 + 2160;
}

return init_code;
}

esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t *out_digi, uint32_t *out_vol_mv)
{
assert(version == ESP_EFUSE_ADC_CALIB_VER);
assert(atten <= ADC_ATTEN_DB_11);
(void) adc_unit;

if (atten == ADC_ATTEN_DB_2_5 || atten == ADC_ATTEN_DB_6) {
/**
* - ESP32C2 only supports SW calibration on ADC_ATTEN_DB_0 and ADC_ATTEN_DB_11
* - For other attenuation, we need to return an error, informing upper layer SW calibration driver
* to deal with the error.
*/
return ESP_ERR_INVALID_ARG;
}

int32_t adc_vol_diff_atten0 = 0;
int32_t adc_vol_diff_atten3 = 0;
int efuse_vol_bits = 0;

efuse_vol_bits = esp_efuse_get_field_size(ESP_EFUSE_ADC1_CAL_VOL_ATTEN0);
ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_ADC1_CAL_VOL_ATTEN0, &adc_vol_diff_atten0, efuse_vol_bits));
adc_vol_diff_atten0 = ((adc_vol_diff_atten0 & BIT(7)) != 0) ? -(adc_vol_diff_atten0 & 0x7f): adc_vol_diff_atten0;

efuse_vol_bits = esp_efuse_get_field_size(ESP_EFUSE_ADC1_CAL_VOL_ATTEN3);
ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_ADC1_CAL_VOL_ATTEN3, &adc_vol_diff_atten3, efuse_vol_bits));
adc_vol_diff_atten3 = ((adc_vol_diff_atten3 & BIT(5)) != 0) ? -(adc_vol_diff_atten3 & 0x1f): adc_vol_diff_atten3;

ESP_EARLY_LOGV("eFuse", "adc_vol_diff_atten0: 0d%"PRId32", adc_vol_diff_atten3: 0d%"PRId32, adc_vol_diff_atten0, adc_vol_diff_atten3);

if (atten == ADC_ATTEN_DB_0) {
*out_digi = adc_vol_diff_atten0 + 1540;
*out_vol_mv = 400;
} else {
//ADC_ATTEN_DB_11
*out_digi = adc_vol_diff_atten0 + 1540 - adc_vol_diff_atten3 - 123;
*out_vol_mv = 1370;
}

return ESP_OK;
}

esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
Expand Down
56 changes: 46 additions & 10 deletions components/efuse/esp32c2/esp_efuse_table.c
Expand Up @@ -9,7 +9,7 @@
#include <assert.h>
#include "esp_efuse_table.h"

// md5_digest_table 5bc3d3149d5d4c75461337fa415d6533
// md5_digest_table ceedae45d1a885ced865a05eeca7d7ee
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
Expand Down Expand Up @@ -176,10 +176,6 @@ static const esp_efuse_desc_t BLK_VERSION_MAJOR[] = {
{EFUSE_BLK2, 60, 2}, // BLK_VERSION_MAJOR,
};

static const esp_efuse_desc_t PVT_LOW[] = {
{EFUSE_BLK2, 91, 5}, // EFUSE_PVT_LOW,
};

static const esp_efuse_desc_t KEY0[] = {
{EFUSE_BLK3, 0, 256}, // [256bit FE key] or [128bit FE key and 128key SB key] or [user data],
};
Expand All @@ -200,6 +196,26 @@ static const esp_efuse_desc_t OCODE[] = {
{EFUSE_BLK2, 62, 7}, // OCode,
};

static const esp_efuse_desc_t TEMP_CALIB[] = {
{EFUSE_BLK2, 69, 9}, // Temperature calibration data,
};

static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0[] = {
{EFUSE_BLK2, 78, 8}, // ADC1 init code at atten0,
};

static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN3[] = {
{EFUSE_BLK2, 86, 5}, // ADC1 init code at atten3,
};

static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN0[] = {
{EFUSE_BLK2, 91, 8}, // ADC1 calibration voltage at atten0,
};

static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN3[] = {
{EFUSE_BLK2, 99, 6}, // ADC1 calibration voltage at atten3,
};

static const esp_efuse_desc_t DIG_DBIAS_HVT[] = {
{EFUSE_BLK2, 105, 5}, // BLOCK2 digital dbias when hvt,
};
Expand Down Expand Up @@ -444,11 +460,6 @@ const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[] = {
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_PVT_LOW[] = {
&PVT_LOW[0], // EFUSE_PVT_LOW
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_KEY0[] = {
&KEY0[0], // [256bit FE key] or [128bit FE key and 128key SB key] or [user data]
NULL
Expand All @@ -474,6 +485,31 @@ const esp_efuse_desc_t* ESP_EFUSE_OCODE[] = {
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[] = {
&TEMP_CALIB[0], // Temperature calibration data
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[] = {
&ADC1_INIT_CODE_ATTEN0[0], // ADC1 init code at atten0
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[] = {
&ADC1_INIT_CODE_ATTEN3[0], // ADC1 init code at atten3
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[] = {
&ADC1_CAL_VOL_ATTEN0[0], // ADC1 calibration voltage at atten0
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[] = {
&ADC1_CAL_VOL_ATTEN3[0], // ADC1 calibration voltage at atten3
NULL
};

const esp_efuse_desc_t* ESP_EFUSE_DIG_DBIAS_HVT[] = {
&DIG_DBIAS_HVT[0], // BLOCK2 digital dbias when hvt
NULL
Expand Down
6 changes: 5 additions & 1 deletion components/efuse/esp32c2/esp_efuse_table.csv
Expand Up @@ -71,7 +71,6 @@
BLK_VERSION_MAJOR, EFUSE_BLK2, 60, 2, BLK_VERSION_MAJOR

# EFUSE_RD_BLK2_DATA2_REG
PVT_LOW, EFUSE_BLK2, 91, 5, EFUSE_PVT_LOW


################
Expand All @@ -83,6 +82,11 @@ KEY0.SB_128BIT, EFUSE_BLK3, 128, 128, [128bit SB
# AUTO CONFIG DIG&RTC DBIAS#
################
OCODE, EFUSE_BLK2, 62, 7, OCode
TEMP_CALIB, EFUSE_BLK2, 69, 9, Temperature calibration data
ADC1_INIT_CODE_ATTEN0, EFUSE_BLK2, 78, 8, ADC1 init code at atten0
ADC1_INIT_CODE_ATTEN3, EFUSE_BLK2, 86, 5, ADC1 init code at atten3
ADC1_CAL_VOL_ATTEN0, EFUSE_BLK2, 91, 8, ADC1 calibration voltage at atten0
ADC1_CAL_VOL_ATTEN3, EFUSE_BLK2, 99, 6, ADC1 calibration voltage at atten3
DIG_DBIAS_HVT, EFUSE_BLK2, 105, 5, BLOCK2 digital dbias when hvt
DIG_LDO_SLP_DBIAS2, EFUSE_BLK2, 110, 7, BLOCK2 DIG_LDO_DBG0_DBIAS2
DIG_LDO_SLP_DBIAS26, EFUSE_BLK2, 117, 8, BLOCK2 DIG_LDO_DBG0_DBIAS26
Expand Down
34 changes: 34 additions & 0 deletions components/efuse/esp32c2/include/esp_efuse_rtc_calib.h
Expand Up @@ -11,6 +11,40 @@
extern "C" {
#endif

//This is the ADC calibration value version burnt in efuse
#define ESP_EFUSE_ADC_CALIB_VER 1

/**
* @brief Get the RTC calibration efuse version
*
* @return Version of the stored efuse
*/
int esp_efuse_rtc_calib_get_ver(void);

/**
* @brief Get the init code in the efuse, for the corresponding attenuation.
*
* @param version Version of the stored efuse
* @param adc_unit ADC unit
* @param atten Attenuation of the init code
* @return The init code stored in efuse
*/
uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten);

/**
* @brief Get the calibration digits stored in the efuse, and the corresponding voltage.
*
* @param version Version of the stored efuse
* @param adc_unit ADC unit
* @param atten Attenuation to use
* @param out_digi Output buffer of the digits
* @param out_vol_mv Output of the voltage, in mV
* @return
* - ESP_ERR_INVALID_ARG: If `ADC_ATTEN_DB_2_5` or `ADC_ATTEN_DB_6` is used
* - ESP_OK: if success
*/
esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t *out_digi, uint32_t *out_vol_mv);

/**
* @brief Get the temperature sensor calibration number delta_T stored in the efuse.
*
Expand Down
8 changes: 6 additions & 2 deletions components/efuse/esp32c2/include/esp_efuse_table.h
Expand Up @@ -10,7 +10,7 @@ extern "C" {

#include "esp_efuse.h"

// md5_digest_table 5bc3d3149d5d4c75461337fa415d6533
// md5_digest_table ceedae45d1a885ced865a05eeca7d7ee
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
// If you want to change some fields, you need to change esp_efuse_table.csv file
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
Expand Down Expand Up @@ -56,12 +56,16 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WAFER_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_PKG_VERSION[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MINOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_BLK_VERSION_MAJOR[];
extern const esp_efuse_desc_t* ESP_EFUSE_PVT_LOW[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0_FE_256BIT[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0_FE_128BIT[];
extern const esp_efuse_desc_t* ESP_EFUSE_KEY0_SB_128BIT[];
extern const esp_efuse_desc_t* ESP_EFUSE_OCODE[];
extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN3[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN0[];
extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIG_DBIAS_HVT[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIG_LDO_SLP_DBIAS2[];
extern const esp_efuse_desc_t* ESP_EFUSE_DIG_LDO_SLP_DBIAS26[];
Expand Down
17 changes: 12 additions & 5 deletions components/efuse/esp32c3/esp_efuse_rtc_calib.c
Expand Up @@ -7,17 +7,24 @@
#include <esp_bit_defs.h>
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_efuse_rtc_calib.h"

int esp_efuse_rtc_calib_get_ver(void)
{
uint32_t result = 0;
esp_efuse_read_field_blob(ESP_EFUSE_BLK_VERSION_MAJOR, &result, ESP_EFUSE_BLK_VERSION_MAJOR[0]->bit_count); // IDF-5366
return result;
uint32_t blk_ver_major = 0;
esp_efuse_read_field_blob(ESP_EFUSE_BLK_VERSION_MAJOR, &blk_ver_major, ESP_EFUSE_BLK_VERSION_MAJOR[0]->bit_count); // IDF-5366

uint32_t cali_version = (blk_ver_major == 1) ? ESP_EFUSE_ADC_CALIB_VER : 0;
if (!cali_version) {
ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0");
}

return cali_version;
}

uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten)
{
assert(version == 1);
assert(version == ESP_EFUSE_ADC_CALIB_VER);
(void) adc_unit;
const esp_efuse_desc_t** init_code_efuse;
assert(atten < 4);
Expand All @@ -44,7 +51,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
(void)adc_unit; //On esp32c3, V1 we don't have calibration data for ADC2, using the efuse data of ADC1
const esp_efuse_desc_t** cal_vol_efuse;
uint32_t calib_vol_expected_mv;
if (version != 1) {
if (version != ESP_EFUSE_ADC_CALIB_VER) {
return ESP_ERR_INVALID_ARG;
}
if (atten >= 4) {
Expand Down

0 comments on commit 542bdea

Please sign in to comment.