diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index 7b1f135d208..57556f4627b 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -605,6 +605,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void) * update this when bringing up the calibration on that chip */ adc_calc_hw_calibration_code(i, j); +#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + /* Load the channel compensation from efuse */ + for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { + adc_load_hw_calibration_chan_compens(i, k, j); + } +#endif } } } diff --git a/components/driver/deprecated/adc_legacy.c b/components/driver/deprecated/adc_legacy.c index 7abab4734e2..9b5c4d7f005 100644 --- a/components/driver/deprecated/adc_legacy.c +++ b/components/driver/deprecated/adc_legacy.c @@ -947,6 +947,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void) * update this when bringing up the calibration on that chip */ adc_calc_hw_calibration_code(i, j); +#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + /* Load the channel compensation from efuse */ + for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { + adc_load_hw_calibration_chan_compens(i, k, j); + } +#endif } } } diff --git a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c index f68991fdaba..c1ff8d66f74 100644 --- a/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c +++ b/components/driver/test_apps/legacy_adc_driver/main/test_legacy_adc.c @@ -53,11 +53,11 @@ #define ADC_TEST_HIGH_VAL 3400 #define ADC_TEST_HIGH_THRESH 200 -#elif CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5312 -#define ADC_TEST_LOW_VAL 2144 -#define ADC_TEST_LOW_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32C6 +#define ADC_TEST_LOW_VAL 0 +#define ADC_TEST_LOW_THRESH 15 -#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_VAL 3350 #define ADC_TEST_HIGH_THRESH 200 #elif CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6216 diff --git a/components/efuse/esp32c2/esp_efuse_rtc_calib.c b/components/efuse/esp32c2/esp_efuse_rtc_calib.c index 79c3409ddfc..0e360709597 100644 --- a/components/efuse/esp32c2/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32c2/esp_efuse_rtc_calib.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,8 @@ int esp_efuse_rtc_calib_get_ver(void) 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((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)); assert(atten <= ADC_ATTEN_DB_11); (void) adc_unit; @@ -64,7 +65,8 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a 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((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)); assert(atten <= ADC_ATTEN_DB_11); (void) adc_unit; diff --git a/components/efuse/esp32c2/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c2/include/esp_efuse_rtc_calib.h index f4e42f29967..a012fc872d1 100644 --- a/components/efuse/esp32c2/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32c2/include/esp_efuse_rtc_calib.h @@ -12,7 +12,9 @@ extern "C" { #endif //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER /** * @brief Get the RTC calibration efuse version diff --git a/components/efuse/esp32c3/esp_efuse_rtc_calib.c b/components/efuse/esp32c3/esp_efuse_rtc_calib.c index 5977b432912..be61b54f89c 100644 --- a/components/efuse/esp32c3/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32c3/esp_efuse_rtc_calib.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,8 @@ int esp_efuse_rtc_calib_get_ver(void) 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((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)); (void) adc_unit; const esp_efuse_desc_t** init_code_efuse; assert(atten < 4); @@ -51,7 +52,8 @@ 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 != ESP_EFUSE_ADC_CALIB_VER) { + if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) || + (version > ESP_EFUSE_ADC_CALIB_VER_MAX)) { return ESP_ERR_INVALID_ARG; } if (atten >= 4) { diff --git a/components/efuse/esp32c3/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c3/include/esp_efuse_rtc_calib.h index 1f6e4748bd7..b5c9912d20c 100644 --- a/components/efuse/esp32c3/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32c3/include/esp_efuse_rtc_calib.h @@ -12,7 +12,9 @@ extern "C" { #endif //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER /** * @brief Get the RTC calibration efuse version diff --git a/components/efuse/esp32c6/esp_efuse_rtc_calib.c b/components/efuse/esp32c6/esp_efuse_rtc_calib.c index 8083339c212..5477b095a49 100644 --- a/components/efuse/esp32c6/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32c6/esp_efuse_rtc_calib.c @@ -7,30 +7,126 @@ #include #include "esp_efuse.h" #include "esp_efuse_table.h" +#include "esp_efuse_rtc_calib.h" +#include "hal/efuse_hal.h" + +/** + * @brief Get the signed value by the raw data that read from eFuse + * @param data The raw data that read from eFuse + * @param sign_bit The index of the sign bit, start from 0 + */ +#define RTC_CALIB_GET_SIGNED_VAL(data, sign_bit) ((data & BIT##sign_bit) ? -(int)(data & ~BIT##sign_bit) : (int)data) 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 cali_version = 0; + uint32_t blk_ver = efuse_hal_blk_version(); + if (blk_ver == 1) { + cali_version = ESP_EFUSE_ADC_CALIB_VER1; + } else if (blk_ver >= 2) { + cali_version = ESP_EFUSE_ADC_CALIB_VER2; + } else { + 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) { - // Currently calibration is not supported on ESP32-C6, IDF-5236 - (void) version; + /* Version validation should be guaranteed in the caller */ + assert(atten >=0 && atten < 4); (void) adc_unit; - (void) atten; - return 0; + + const esp_efuse_desc_t** init_code_efuse; + if (atten == 0) { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0; + } else if (atten == 1) { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN1; + } else if (atten == 2) { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN2; + } else { + init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN3; + } + + int init_code_size = esp_efuse_get_field_size(init_code_efuse); + assert(init_code_size == 10); + + uint32_t init_code = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size)); + return init_code + 1600; // version 1 logic } -esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t* out_digi, uint32_t* out_vol_mv) +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten) { - // Currently calibration is not supported on ESP32-C6, IDF-5236 - (void) version; - (void) atten; - (void) out_digi; - (void) out_vol_mv; + /* Version validation should be guaranteed in the caller */ + assert(atten < 4); + assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit)); + + const esp_efuse_desc_t** chan_diff_efuse = NULL; + switch (adc_channel) { + case 0: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH0; + break; + case 1: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1; + break; + case 2: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2; + break; + case 3: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3; + break; + case 4: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4; + break; + case 5: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5; + break; + default: + chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6; + break; + } + + int chan_diff_size = esp_efuse_get_field_size(chan_diff_efuse); + assert(chan_diff_size == 4); + uint32_t chan_diff = 0; + ESP_ERROR_CHECK(esp_efuse_read_field_blob(chan_diff_efuse, &chan_diff, chan_diff_size)); + return RTC_CALIB_GET_SIGNED_VAL(chan_diff, 3) * (4 - atten); +} + +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) +{ + (void) adc_unit; + const esp_efuse_desc_t** cal_vol_efuse[4] = { + ESP_EFUSE_ADC1_CAL_VOL_ATTEN0, + ESP_EFUSE_ADC1_CAL_VOL_ATTEN1, + ESP_EFUSE_ADC1_CAL_VOL_ATTEN2, + ESP_EFUSE_ADC1_CAL_VOL_ATTEN3, + }; + const uint32_t input_vout_mv[2][4] = { + {400, 550, 750, 1370}, // Calibration V1 coefficients + {750, 1000, 1500, 2800}, // Calibration V2 coefficients + }; + + if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) || + (version > ESP_EFUSE_ADC_CALIB_VER_MAX)) { + return ESP_ERR_INVALID_ARG; + } + if (atten >= 4 || atten < 0) { + return ESP_ERR_INVALID_ARG; + } + + assert(cal_vol_efuse[atten][0]->bit_count == 10); + + uint32_t cal_vol = 0; + esp_err_t ret = esp_efuse_read_field_blob(cal_vol_efuse[atten], &cal_vol, cal_vol_efuse[atten][0]->bit_count); + if (ret != ESP_OK) { + return ret; + } + uint32_t chk_offset = (version == ESP_EFUSE_ADC_CALIB_VER1) ? 1500 : (atten == 2) ? 2900 : 2850; + *out_digi = chk_offset + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9); + *out_vol_mv = input_vout_mv[VER2IDX(version)][atten]; return ESP_OK; } diff --git a/components/efuse/esp32c6/esp_efuse_table.c b/components/efuse/esp32c6/esp_efuse_table.c index a1dcabf9d74..e6bf085e8a6 100644 --- a/components/efuse/esp32c6/esp_efuse_table.c +++ b/components/efuse/esp32c6/esp_efuse_table.c @@ -9,7 +9,7 @@ #include #include "esp_efuse_table.h" -// md5_digest_table 344c54cf227f74643e4d13dce1b1d30f +// md5_digest_table fd5a35cea89bfad954e834bc92bed385 // 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. @@ -227,6 +227,74 @@ static const esp_efuse_desc_t WR_DIS_OPTIONAL_UNIQUE_ID[] = { {EFUSE_BLK0, 21, 1}, // [] wr_dis of OPTIONAL_UNIQUE_ID, }; +static const esp_efuse_desc_t WR_DIS_TEMP_CALIB[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of TEMP_CALIB, +}; + +static const esp_efuse_desc_t WR_DIS_OCODE[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of OCODE, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_CAL_VOL_ATTEN3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_CAL_VOL_ATTEN3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH0, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH1, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH2, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH3, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH4, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH5, +}; + +static const esp_efuse_desc_t WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[] = { + {EFUSE_BLK0, 21, 1}, // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH6, +}; + static const esp_efuse_desc_t WR_DIS_BLOCK_USR_DATA[] = { {EFUSE_BLK0, 22, 1}, // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA, }; @@ -521,6 +589,74 @@ static const esp_efuse_desc_t OPTIONAL_UNIQUE_ID[] = { {EFUSE_BLK2, 0, 128}, // [] Optional unique 128-bit ID, }; +static const esp_efuse_desc_t TEMP_CALIB[] = { + {EFUSE_BLK2, 128, 9}, // [] Temperature calibration data, +}; + +static const esp_efuse_desc_t OCODE[] = { + {EFUSE_BLK2, 137, 8}, // [] ADC OCode, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0[] = { + {EFUSE_BLK2, 145, 10}, // [] ADC1 init code at atten0, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN1[] = { + {EFUSE_BLK2, 155, 10}, // [] ADC1 init code at atten1, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN2[] = { + {EFUSE_BLK2, 165, 10}, // [] ADC1 init code at atten2, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN3[] = { + {EFUSE_BLK2, 175, 10}, // [] ADC1 init code at atten3, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN0[] = { + {EFUSE_BLK2, 185, 10}, // [] ADC1 calibration voltage at atten0, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN1[] = { + {EFUSE_BLK2, 195, 10}, // [] ADC1 calibration voltage at atten1, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN2[] = { + {EFUSE_BLK2, 205, 10}, // [] ADC1 calibration voltage at atten2, +}; + +static const esp_efuse_desc_t ADC1_CAL_VOL_ATTEN3[] = { + {EFUSE_BLK2, 215, 10}, // [] ADC1 calibration voltage at atten3, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH0[] = { + {EFUSE_BLK2, 225, 4}, // [] ADC1 init code at atten0 ch0, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH1[] = { + {EFUSE_BLK2, 229, 4}, // [] ADC1 init code at atten0 ch1, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH2[] = { + {EFUSE_BLK2, 233, 4}, // [] ADC1 init code at atten0 ch2, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH3[] = { + {EFUSE_BLK2, 237, 4}, // [] ADC1 init code at atten0 ch3, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH4[] = { + {EFUSE_BLK2, 241, 4}, // [] ADC1 init code at atten0 ch4, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH5[] = { + {EFUSE_BLK2, 245, 4}, // [] ADC1 init code at atten0 ch5, +}; + +static const esp_efuse_desc_t ADC1_INIT_CODE_ATTEN0_CH6[] = { + {EFUSE_BLK2, 249, 4}, // [] ADC1 init code at atten0 ch6, +}; + static const esp_efuse_desc_t USER_DATA[] = { {EFUSE_BLK3, 0, 256}, // [BLOCK_USR_DATA] User data, }; @@ -826,6 +962,91 @@ const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[] = { + &WR_DIS_TEMP_CALIB[0], // [] wr_dis of TEMP_CALIB + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OCODE[] = { + &WR_DIS_OCODE[0], // [] wr_dis of OCODE + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN1[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN1[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN2[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN2[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN3[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN3[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN0[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN0[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN1[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN1[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN2[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN2[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN3[] = { + &WR_DIS_ADC1_CAL_VOL_ATTEN3[0], // [] wr_dis of ADC1_CAL_VOL_ATTEN3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[] = { + &WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[0], // [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH6 + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[] = { &WR_DIS_BLOCK_USR_DATA[0], // [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA NULL @@ -1192,6 +1413,91 @@ const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[] = { NULL }; +const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[] = { + &TEMP_CALIB[0], // [] Temperature calibration data + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_OCODE[] = { + &OCODE[0], // [] ADC OCode + 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_ATTEN1[] = { + &ADC1_INIT_CODE_ATTEN1[0], // [] ADC1 init code at atten1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[] = { + &ADC1_INIT_CODE_ATTEN2[0], // [] ADC1 init code at atten2 + 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_ATTEN1[] = { + &ADC1_CAL_VOL_ATTEN1[0], // [] ADC1 calibration voltage at atten1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[] = { + &ADC1_CAL_VOL_ATTEN2[0], // [] ADC1 calibration voltage at atten2 + 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_ADC1_INIT_CODE_ATTEN0_CH0[] = { + &ADC1_INIT_CODE_ATTEN0_CH0[0], // [] ADC1 init code at atten0 ch0 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1[] = { + &ADC1_INIT_CODE_ATTEN0_CH1[0], // [] ADC1 init code at atten0 ch1 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2[] = { + &ADC1_INIT_CODE_ATTEN0_CH2[0], // [] ADC1 init code at atten0 ch2 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3[] = { + &ADC1_INIT_CODE_ATTEN0_CH3[0], // [] ADC1 init code at atten0 ch3 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4[] = { + &ADC1_INIT_CODE_ATTEN0_CH4[0], // [] ADC1 init code at atten0 ch4 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5[] = { + &ADC1_INIT_CODE_ATTEN0_CH5[0], // [] ADC1 init code at atten0 ch5 + NULL +}; + +const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6[] = { + &ADC1_INIT_CODE_ATTEN0_CH6[0], // [] ADC1 init code at atten0 ch6 + NULL +}; + const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[] = { &USER_DATA[0], // [BLOCK_USR_DATA] User data NULL diff --git a/components/efuse/esp32c6/esp_efuse_table.csv b/components/efuse/esp32c6/esp_efuse_table.csv index 78304fe59d9..9cfbb6fb6d2 100644 --- a/components/efuse/esp32c6/esp_efuse_table.csv +++ b/components/efuse/esp32c6/esp_efuse_table.csv @@ -9,7 +9,7 @@ # this will generate new source files, next rebuild all the sources. # !!!!!!!!!!! # -# This file was generated by regtools.py based on the efuses.yaml file with the version: 0a6c6206f42d0f0b7aeaceb8cecf1fc2 +# This file was generated by regtools.py based on the efuses.yaml file with the version: 709e8ea096e8a03a10006d40d5451a49 WR_DIS, EFUSE_BLK0, 0, 32, [] Disable programming of individual eFuses WR_DIS.RD_DIS, EFUSE_BLK0, 0, 1, [] wr_dis of RD_DIS @@ -64,6 +64,23 @@ WR_DIS.FLASH_TEMP, EFUSE_BLK0, 20, 1, [] wr_dis WR_DIS.FLASH_VENDOR, EFUSE_BLK0, 20, 1, [] wr_dis of FLASH_VENDOR WR_DIS.SYS_DATA_PART1, EFUSE_BLK0, 21, 1, [] wr_dis of BLOCK2 WR_DIS.OPTIONAL_UNIQUE_ID, EFUSE_BLK0, 21, 1, [] wr_dis of OPTIONAL_UNIQUE_ID +WR_DIS.TEMP_CALIB, EFUSE_BLK0, 21, 1, [] wr_dis of TEMP_CALIB +WR_DIS.OCODE, EFUSE_BLK0, 21, 1, [] wr_dis of OCODE +WR_DIS.ADC1_INIT_CODE_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0 +WR_DIS.ADC1_INIT_CODE_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN1 +WR_DIS.ADC1_INIT_CODE_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN2 +WR_DIS.ADC1_INIT_CODE_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN3 +WR_DIS.ADC1_CAL_VOL_ATTEN0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN0 +WR_DIS.ADC1_CAL_VOL_ATTEN1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN1 +WR_DIS.ADC1_CAL_VOL_ATTEN2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN2 +WR_DIS.ADC1_CAL_VOL_ATTEN3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_CAL_VOL_ATTEN3 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH0, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH0 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH1, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH1 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH2, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH2 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH3, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH3 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH4, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH4 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH5, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH5 +WR_DIS.ADC1_INIT_CODE_ATTEN0_CH6, EFUSE_BLK0, 21, 1, [] wr_dis of ADC1_INIT_CODE_ATTEN0_CH6 WR_DIS.BLOCK_USR_DATA, EFUSE_BLK0, 22, 1, [WR_DIS.USER_DATA] wr_dis of BLOCK_USR_DATA WR_DIS.CUSTOM_MAC, EFUSE_BLK0, 22, 1, [WR_DIS.MAC_CUSTOM WR_DIS.USER_DATA_MAC_CUSTOM] wr_dis of CUSTOM_MAC WR_DIS.BLOCK_KEY0, EFUSE_BLK0, 23, 1, [WR_DIS.KEY0] wr_dis of BLOCK_KEY0 @@ -142,6 +159,23 @@ FLASH_CAP, EFUSE_BLK1, 128, 3, [] FLASH_TEMP, EFUSE_BLK1, 131, 2, [] FLASH_VENDOR, EFUSE_BLK1, 133, 3, [] OPTIONAL_UNIQUE_ID, EFUSE_BLK2, 0, 128, [] Optional unique 128-bit ID +TEMP_CALIB, EFUSE_BLK2, 128, 9, [] Temperature calibration data +OCODE, EFUSE_BLK2, 137, 8, [] ADC OCode +ADC1_INIT_CODE_ATTEN0, EFUSE_BLK2, 145, 10, [] ADC1 init code at atten0 +ADC1_INIT_CODE_ATTEN1, EFUSE_BLK2, 155, 10, [] ADC1 init code at atten1 +ADC1_INIT_CODE_ATTEN2, EFUSE_BLK2, 165, 10, [] ADC1 init code at atten2 +ADC1_INIT_CODE_ATTEN3, EFUSE_BLK2, 175, 10, [] ADC1 init code at atten3 +ADC1_CAL_VOL_ATTEN0, EFUSE_BLK2, 185, 10, [] ADC1 calibration voltage at atten0 +ADC1_CAL_VOL_ATTEN1, EFUSE_BLK2, 195, 10, [] ADC1 calibration voltage at atten1 +ADC1_CAL_VOL_ATTEN2, EFUSE_BLK2, 205, 10, [] ADC1 calibration voltage at atten2 +ADC1_CAL_VOL_ATTEN3, EFUSE_BLK2, 215, 10, [] ADC1 calibration voltage at atten3 +ADC1_INIT_CODE_ATTEN0_CH0, EFUSE_BLK2, 225, 4, [] ADC1 init code at atten0 ch0 +ADC1_INIT_CODE_ATTEN0_CH1, EFUSE_BLK2, 229, 4, [] ADC1 init code at atten0 ch1 +ADC1_INIT_CODE_ATTEN0_CH2, EFUSE_BLK2, 233, 4, [] ADC1 init code at atten0 ch2 +ADC1_INIT_CODE_ATTEN0_CH3, EFUSE_BLK2, 237, 4, [] ADC1 init code at atten0 ch3 +ADC1_INIT_CODE_ATTEN0_CH4, EFUSE_BLK2, 241, 4, [] ADC1 init code at atten0 ch4 +ADC1_INIT_CODE_ATTEN0_CH5, EFUSE_BLK2, 245, 4, [] ADC1 init code at atten0 ch5 +ADC1_INIT_CODE_ATTEN0_CH6, EFUSE_BLK2, 249, 4, [] ADC1 init code at atten0 ch6 USER_DATA, EFUSE_BLK3, 0, 256, [BLOCK_USR_DATA] User data USER_DATA.MAC_CUSTOM, EFUSE_BLK3, 200, 48, [MAC_CUSTOM CUSTOM_MAC] Custom MAC KEY0, EFUSE_BLK4, 0, 256, [BLOCK_KEY0] Key0 or user data diff --git a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h index c8029ffc639..e2cb7610fd1 100644 --- a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,8 +12,11 @@ extern "C" { #endif //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 1 - +#define ESP_EFUSE_ADC_CALIB_VER1 1 +#define ESP_EFUSE_ADC_CALIB_VER2 2 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1 +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER2 +#define VER2IDX(ver) (ver - 1) // Version number to index number of the array /** * @brief Get the RTC calibration efuse version * @@ -31,10 +34,22 @@ int esp_efuse_rtc_calib_get_ver(void); */ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten); +/** + * @brief Get the channel specific calibration compensation + * + * @param version Version of the stored efuse + * @param adc_unit ADC unit. Not used, for compatibility. On esp32c6, for calibration v1, both ADC units use the same init code (calibrated by ADC1) + * @param adc_channel ADC channel number + * @param atten Attenuation of the init code + * @return The channel calibration compensation value + */ +int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, 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 (not used on ESP32C6, for compatibility) * @param atten Attenuation to use * @param out_digi Output buffer of the digits * @param out_vol_mv Output of the voltage, in mV @@ -42,7 +57,7 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a * - ESP_ERR_INVALID_ARG: If efuse version or attenuation is invalid * - ESP_OK: if success */ -esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t* out_digi, uint32_t* out_vol_mv); +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. diff --git a/components/efuse/esp32c6/include/esp_efuse_table.h b/components/efuse/esp32c6/include/esp_efuse_table.h index b9837019281..28379f96725 100644 --- a/components/efuse/esp32c6/include/esp_efuse_table.h +++ b/components/efuse/esp32c6/include/esp_efuse_table.h @@ -10,7 +10,7 @@ extern "C" { #include "esp_efuse.h" -// md5_digest_table 344c54cf227f74643e4d13dce1b1d30f +// md5_digest_table fd5a35cea89bfad954e834bc92bed385 // 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. @@ -80,6 +80,23 @@ extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_TEMP[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_VENDOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_SYS_DATA_PART1[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OPTIONAL_UNIQUE_ID[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_OCODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_CAL_VOL_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH4[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH5[]; +extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_ADC1_INIT_CODE_ATTEN0_CH6[]; extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLOCK_USR_DATA[]; #define ESP_EFUSE_WR_DIS_USER_DATA ESP_EFUSE_WR_DIS_BLOCK_USR_DATA extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_CUSTOM_MAC[]; @@ -179,6 +196,23 @@ extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CAP[]; extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_TEMP[]; extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_VENDOR[]; extern const esp_efuse_desc_t* ESP_EFUSE_OPTIONAL_UNIQUE_ID[]; +extern const esp_efuse_desc_t* ESP_EFUSE_TEMP_CALIB[]; +extern const esp_efuse_desc_t* ESP_EFUSE_OCODE[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN2[]; +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_ATTEN1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_CAL_VOL_ATTEN3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH0[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5[]; +extern const esp_efuse_desc_t* ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6[]; extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA[]; #define ESP_EFUSE_BLOCK_USR_DATA ESP_EFUSE_USER_DATA extern const esp_efuse_desc_t* ESP_EFUSE_USER_DATA_MAC_CUSTOM[]; diff --git a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h index f2dcc89d2d8..a71ed137842 100644 --- a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,9 @@ extern "C" { #endif //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER /** * @brief Get the RTC calibration efuse version diff --git a/components/efuse/esp32s2/include/esp_efuse_rtc_table.h b/components/efuse/esp32s2/include/esp_efuse_rtc_table.h index f6f5d168459..e9b86794855 100644 --- a/components/efuse/esp32s2/include/esp_efuse_rtc_table.h +++ b/components/efuse/esp32s2/include/esp_efuse_rtc_table.h @@ -16,7 +16,9 @@ extern "C" { #include "sdkconfig.h" //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 2 +#define ESP_EFUSE_ADC_CALIB_VER 2 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER #define RTCCALIB_ESP32S2_ADCCOUNT 2 #define RTCCALIB_ESP32S2_ATTENCOUNT 4 diff --git a/components/efuse/esp32s3/esp_efuse_rtc_calib.c b/components/efuse/esp32s3/esp_efuse_rtc_calib.c index 800a2abeaf1..540fd9afc09 100644 --- a/components/efuse/esp32s3/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32s3/esp_efuse_rtc_calib.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,7 +27,8 @@ int esp_efuse_rtc_calib_get_ver(void) 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((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)); assert(atten < 4); assert(adc_unit <= ADC_UNIT_2); @@ -62,7 +63,8 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a 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((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)); assert(atten < 4); assert(adc_unit <= ADC_UNIT_2); diff --git a/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h b/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h index 0f0f37938df..49712040a03 100644 --- a/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32s3/include/esp_efuse_rtc_calib.h @@ -12,7 +12,9 @@ extern "C" { #endif //This is the ADC calibration value version burnt in efuse -#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER 1 +#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER +#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER /** * @brief Get the RTC calibration efuse version diff --git a/components/esp_adc/adc_cali_curve_fitting.c b/components/esp_adc/adc_cali_curve_fitting.c index 43474481759..38db70f5251 100644 --- a/components/esp_adc/adc_cali_curve_fitting.c +++ b/components/esp_adc/adc_cali_curve_fitting.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,10 +15,11 @@ #include "soc/soc_caps.h" #include "esp_adc/adc_cali_scheme.h" #include "adc_cali_interface.h" -#include "curve_fitting_coefficients.h" +#include "esp_private/adc_share_hw_ctrl.h" #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED #include "esp_efuse_rtc_calib.h" +#include "curve_fitting_coefficients.h" const __attribute__((unused)) static char *TAG = "adc_cali"; @@ -47,14 +48,9 @@ typedef struct { uint32_t coeff_b; ///< Offset of ADC-Voltage curve } cali_chars_first_step_t; -typedef struct { - uint8_t term_num; ///< Term number of the algorithm formula - const uint64_t (*coeff)[COEFF_GROUP_NUM][TERM_MAX][2]; ///< Coeff of each term. See `adc_error_coef_atten` for details (and the magic number 2) - const int32_t (*sign)[COEFF_GROUP_NUM][TERM_MAX]; ///< Sign of each term -} cali_chars_second_step_t; - typedef struct { adc_unit_t unit_id; ///< ADC unit + adc_channel_t chan; ///< ADC channel adc_atten_t atten; ///< ADC attenuation cali_chars_first_step_t chars_first_step; ///< Calibration first step characteristics cali_chars_second_step_t chars_second_step; ///< Calibration second step characteristics @@ -63,7 +59,6 @@ typedef struct { /* ----------------------- Characterization Functions ----------------------- */ static void get_first_step_reference_point(int version_num, adc_unit_t unit_id, adc_atten_t atten, adc_calib_info_t *calib_info); static void calc_first_step_coefficients(const adc_calib_info_t *parsed_data, cali_chars_curve_fitting_t *chars); -static void calc_second_step_coefficients(const adc_cali_curve_fitting_config_t *config, cali_chars_curve_fitting_t *ctx); static int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step_t *param, adc_atten_t atten); static esp_err_t check_valid(const adc_cali_curve_fitting_config_t *config); @@ -79,9 +74,10 @@ esp_err_t adc_cali_create_scheme_curve_fitting(const adc_cali_curve_fitting_conf if (ret != ESP_OK) { return ret; } - // current version only accepts encoding version: `ESP_EFUSE_ADC_CALIB_VER`. - uint8_t adc_encoding_version = esp_efuse_rtc_calib_get_ver(); - ESP_RETURN_ON_FALSE(adc_encoding_version == ESP_EFUSE_ADC_CALIB_VER, ESP_ERR_NOT_SUPPORTED, TAG, "Calibration required eFuse bits not burnt"); + // current version only accepts encoding version: ESP_EFUSE_ADC_CALIB_VER_MIN <= adc_encoding_version <= ESP_EFUSE_ADC_CALIB_VER_MAX. + uint32_t adc_encoding_version = esp_efuse_rtc_calib_get_ver(); + ESP_RETURN_ON_FALSE((adc_encoding_version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (adc_encoding_version <= ESP_EFUSE_ADC_CALIB_VER_MAX), ESP_ERR_NOT_SUPPORTED, TAG, "Calibration required eFuse bits not burnt"); adc_cali_scheme_t *scheme = (adc_cali_scheme_t *)heap_caps_calloc(1, sizeof(adc_cali_scheme_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_RETURN_ON_FALSE(scheme, ESP_ERR_NO_MEM, TAG, "no mem for adc calibration scheme"); @@ -98,8 +94,9 @@ esp_err_t adc_cali_create_scheme_curve_fitting(const adc_cali_curve_fitting_conf get_first_step_reference_point(adc_encoding_version, config->unit_id, config->atten, &calib_info); calc_first_step_coefficients(&calib_info, chars); //Set second step calibration context - calc_second_step_coefficients(config, chars); + curve_fitting_get_second_step_coeff(config, &(chars->chars_second_step)); chars->unit_id = config->unit_id; + chars->chan = config->chan; chars->atten = config->atten; *ret_handle = scheme; @@ -132,6 +129,16 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) //pointers are checked in the upper layer cali_chars_curve_fitting_t *ctx = arg; + +#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + int chan_compensation = adc_get_hw_calibration_chan_compens(ctx->unit_id, ctx->chan, ctx->atten); + raw -= chan_compensation; + /* Limit the range */ + int max_val = (1L << SOC_ADC_RTC_MAX_BITWIDTH) - 1; + raw = raw <= 0 ? 0 : + raw > max_val ? max_val : raw; +#endif // SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + uint64_t v_cali_1 = (uint64_t)raw * ctx->chars_first_step.coeff_a / coeff_a_scaling + ctx->chars_first_step.coeff_b; int32_t error = get_reading_error(v_cali_1, &(ctx->chars_second_step), ctx->atten); @@ -144,7 +151,8 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) //To get the reference point (Dout, Vin) static void get_first_step_reference_point(int version_num, adc_unit_t unit_id, adc_atten_t atten, adc_calib_info_t *calib_info) { - assert(version_num == ESP_EFUSE_ADC_CALIB_VER); + assert((version_num >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version_num <= ESP_EFUSE_ADC_CALIB_VER_MAX)); esp_err_t ret; calib_info->version_num = version_num; @@ -153,7 +161,7 @@ static void get_first_step_reference_point(int version_num, adc_unit_t unit_id, uint32_t voltage = 0; uint32_t digi = 0; - ret = esp_efuse_rtc_calib_get_cal_voltage(version_num, unit_id, atten, &digi, &voltage); + ret = esp_efuse_rtc_calib_get_cal_voltage(version_num, unit_id, (int)atten, &digi, &voltage); assert(ret == ESP_OK); calib_info->ref_data.ver1.voltage = voltage; calib_info->ref_data.ver1.digi = digi; @@ -170,18 +178,6 @@ static void calc_first_step_coefficients(const adc_calib_info_t *parsed_data, ca ESP_LOGV(TAG, "Calib V1, Cal Voltage = %"PRId32", Digi out = %"PRId32", Coef_a = %"PRId32"\n", parsed_data->ref_data.ver1.voltage, parsed_data->ref_data.ver1.digi, ctx->chars_first_step.coeff_a); } -static void calc_second_step_coefficients(const adc_cali_curve_fitting_config_t *config, cali_chars_curve_fitting_t *ctx) -{ - ctx->chars_second_step.term_num = (config->atten == 3) ? 5 : 3; -#if CONFIG_IDF_TARGET_ESP32C3 - //On esp32c3, ADC1 and ADC2 share the second step coefficients - ctx->chars_second_step.coeff = &adc1_error_coef_atten; - ctx->chars_second_step.sign = &adc1_error_sign; -#else - ctx->chars_second_step.coeff = (config->unit_id == ADC_UNIT_1) ? &adc1_error_coef_atten : &adc2_error_coef_atten; - ctx->chars_second_step.sign = (config->unit_id == ADC_UNIT_1) ? &adc1_error_sign : &adc2_error_sign; -#endif -} static int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step_t *param, adc_atten_t atten) { @@ -197,13 +193,6 @@ static int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step memset(variable, 0, term_num * sizeof(uint64_t)); memset(term, 0, term_num * sizeof(uint64_t)); - /** - * For atten0 ~ 2: - * error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); - * - * For atten3: - * error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); - */ variable[0] = 1; coeff = (*param->coeff)[atten][0][0]; term[0] = variable[0] * coeff / (*param->coeff)[atten][0][1]; diff --git a/components/esp_adc/adc_common.c b/components/esp_adc/adc_common.c index 1a473c52166..19087aeab51 100644 --- a/components/esp_adc/adc_common.c +++ b/components/esp_adc/adc_common.c @@ -102,6 +102,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void) * update this when bringing up the calibration on that chip */ adc_calc_hw_calibration_code(i, j); +#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + /* Load the channel compensation from efuse */ + for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { + adc_load_hw_calibration_chan_compens(i, k, j); + } +#endif } } } diff --git a/components/esp_adc/adc_oneshot.c b/components/esp_adc/adc_oneshot.c index 7b8b61ea68e..cbdb1bc4dd5 100644 --- a/components/esp_adc/adc_oneshot.c +++ b/components/esp_adc/adc_oneshot.c @@ -122,6 +122,10 @@ esp_err_t adc_oneshot_new_unit(const adc_oneshot_unit_init_cfg_t *init_config, a _lock_release(&s_ctx.mutex); #endif + if (init_config->ulp_mode == ADC_ULP_MODE_DISABLE) { + sar_periph_ctrl_adc_oneshot_power_acquire(); + } + ESP_LOGD(TAG, "new adc unit%"PRId32" is created", unit->unit_id); *ret_unit = unit; return ESP_OK; @@ -167,16 +171,14 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, } portENTER_CRITICAL(&rtc_spinlock); - sar_periph_ctrl_adc_oneshot_power_acquire(); adc_oneshot_hal_setup(&(handle->hal), chan); #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); adc_hal_calibration_init(handle->unit_id); adc_set_hw_calibration_code(handle->unit_id, atten); -#endif +#endif // SOC_ADC_CALIBRATION_V1_SUPPORTED bool valid = false; valid = adc_oneshot_hal_convert(&(handle->hal), out_raw); - sar_periph_ctrl_adc_oneshot_power_release(); portEXIT_CRITICAL(&rtc_spinlock); adc_lock_release(handle->unit_id); @@ -192,7 +194,6 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c portENTER_CRITICAL_SAFE(&rtc_spinlock); - sar_periph_ctrl_adc_oneshot_power_acquire(); adc_oneshot_hal_setup(&(handle->hal), chan); #if SOC_ADC_CALIBRATION_V1_SUPPORTED adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); @@ -200,7 +201,6 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c adc_set_hw_calibration_code(handle->unit_id, atten); #endif adc_oneshot_hal_convert(&(handle->hal), out_raw); - sar_periph_ctrl_adc_oneshot_power_release(); portEXIT_CRITICAL_SAFE(&rtc_spinlock); @@ -210,6 +210,7 @@ esp_err_t adc_oneshot_read_isr(adc_oneshot_unit_handle_t handle, adc_channel_t c esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) { ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + adc_ulp_mode_t ulp_mode = handle->ulp_mode; bool success_free = s_adc_unit_free(handle->unit_id); ESP_RETURN_ON_FALSE(success_free, ESP_ERR_NOT_FOUND, TAG, "adc%"PRId32" isn't in use", handle->unit_id + 1); @@ -220,6 +221,10 @@ esp_err_t adc_oneshot_del_unit(adc_oneshot_unit_handle_t handle) ESP_LOGD(TAG, "adc unit%"PRId32" is deleted", handle->unit_id); free(handle); + if (ulp_mode == ADC_ULP_MODE_DISABLE) { + sar_periph_ctrl_adc_oneshot_power_release(); + } + #if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED //To free the APB_SARADC periph if needed _lock_acquire(&s_ctx.mutex); diff --git a/components/esp_adc/curve_fitting_coefficients.h b/components/esp_adc/curve_fitting_coefficients.h index 1a77ac6b765..79f08dc7bf6 100644 --- a/components/esp_adc/curve_fitting_coefficients.h +++ b/components/esp_adc/curve_fitting_coefficients.h @@ -1,33 +1,34 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include +#include "esp_adc/adc_cali_scheme.h" + +#ifdef __cplusplus +extern "C" { +#endif #define COEFF_GROUP_NUM 4 #define TERM_MAX 5 +typedef struct { + uint8_t term_num; ///< Term number of the algorithm formula + const uint64_t (*coeff)[COEFF_GROUP_NUM][TERM_MAX][2]; ///< Coeff of each term. See `adc_error_coef_atten` for details (and the magic number 2) + const int32_t (*sign)[COEFF_GROUP_NUM][TERM_MAX]; ///< Sign of each term +} cali_chars_second_step_t; + /** - * @note Error Calculation - * Coefficients for calculating the reading voltage error. - * Four sets of coefficients for atten0 ~ atten3 respectively. - * - * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. + * @brief Assign the second step coefficients for curve calibration * - * @note {0,0} stands for unused item - * @note In case of the overflow, these coeffcients are recorded as Absolute Value - * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); - * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. - * @note ADC1 and ADC2 use same coeffients + * @param config the curve fitting configuration + * @param ctx the context pointer of the second step configuration structure */ -extern const uint64_t adc1_error_coef_atten[COEFF_GROUP_NUM][TERM_MAX][2]; -extern const uint64_t adc2_error_coef_atten[COEFF_GROUP_NUM][TERM_MAX][2]; +void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx); -/** - * Term sign - */ -extern const int32_t adc1_error_sign[COEFF_GROUP_NUM][TERM_MAX]; -extern const int32_t adc2_error_sign[COEFF_GROUP_NUM][TERM_MAX]; +#ifdef __cplusplus +} +#endif diff --git a/components/esp_adc/esp32c2/adc_cali_line_fitting.c b/components/esp_adc/esp32c2/adc_cali_line_fitting.c index dde0ebe40f6..6eae21f7a55 100644 --- a/components/esp_adc/esp32c2/adc_cali_line_fitting.c +++ b/components/esp_adc/esp32c2/adc_cali_line_fitting.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -58,9 +58,10 @@ esp_err_t adc_cali_create_scheme_line_fitting(const adc_cali_line_fitting_config return ret; } - //current version only accepts encoding version: `ESP_EFUSE_ADC_CALIB_VER`. + //current version only accepts encoding version: ESP_EFUSE_ADC_CALIB_VER_MIN <= adc_encoding_version <= ESP_EFUSE_ADC_CALIB_VER_MAX. uint8_t adc_cali_version = esp_efuse_rtc_calib_get_ver(); - ESP_RETURN_ON_FALSE(adc_cali_version == ESP_EFUSE_ADC_CALIB_VER, ESP_ERR_NOT_SUPPORTED, TAG, "Calibration required eFuse bits not burnt"); + ESP_RETURN_ON_FALSE((adc_cali_version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (adc_cali_version <= ESP_EFUSE_ADC_CALIB_VER_MAX), ESP_ERR_NOT_SUPPORTED, TAG, "Calibration required eFuse bits not burnt"); adc_cali_scheme_t *scheme = (adc_cali_scheme_t *)heap_caps_calloc(1, sizeof(adc_cali_scheme_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); ESP_RETURN_ON_FALSE(scheme, ESP_ERR_NO_MEM, TAG, "no mem for adc calibration scheme"); @@ -76,7 +77,7 @@ esp_err_t adc_cali_create_scheme_line_fitting(const adc_cali_line_fitting_config uint32_t voltage_mv = 0; uint32_t digi_val = 0; - esp_efuse_rtc_calib_get_cal_voltage(adc_cali_version, chars->unit_id, chars->atten, &digi_val, &voltage_mv); + ret = esp_efuse_rtc_calib_get_cal_voltage(adc_cali_version, chars->unit_id, chars->atten, &digi_val, &voltage_mv); assert(ret == ESP_OK); chars->coeff_a = coeff_a_scaling * voltage_mv / digi_val; chars->coeff_b = 0; diff --git a/components/esp_adc/esp32c3/curve_fitting_coefficients.c b/components/esp_adc/esp32c3/curve_fitting_coefficients.c index c8f8d5776eb..47a4b4eec73 100644 --- a/components/esp_adc/esp32c3/curve_fitting_coefficients.c +++ b/components/esp_adc/esp32c3/curve_fitting_coefficients.c @@ -1,10 +1,11 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "../curve_fitting_coefficients.h" /** * @note Error Calculation @@ -14,12 +15,12 @@ * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. * * @note {0,0} stands for unused item - * @note In case of the overflow, these coeffcients are recorded as Absolute Value + * @note In case of the overflow, these coefficients are recorded as Absolute Value * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. - * @note ADC1 and ADC2 use same coeffients + * @note ADC1 and ADC2 use same coefficients */ -const uint64_t adc1_error_coef_atten[4][5][2] = { +const static uint64_t adc1_error_coef_atten[COEFF_GROUP_NUM][TERM_MAX][2] = { {{225966470500043, 1e15}, {7265418501948, 1e16}, {109410402681, 1e16}, {0, 0}, {0, 0}}, //atten0 {{4229623392600516, 1e16}, {731527490903, 1e16}, {88166562521, 1e16}, {0, 0}, {0, 0}}, //atten1 {{1017859239236435, 1e15}, {97159265299153, 1e16}, {149794028038, 1e16}, {0, 0}, {0, 0}}, //atten2 @@ -28,9 +29,18 @@ const uint64_t adc1_error_coef_atten[4][5][2] = { /** * Term sign */ -const int32_t adc1_error_sign[4][5] = { +const static int32_t adc1_error_sign[COEFF_GROUP_NUM][TERM_MAX] = { {-1, -1, 1, 0, 0}, //atten0 { 1, -1, 1, 0, 0}, //atten1 {-1, -1, 1, 0, 0}, //atten2 {-1, -1, 1, -1, 1} //atten3 }; + +void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx) +{ + ctx->term_num = (config->atten == 3) ? 5 : 3; + // On esp32c3, ADC1 and ADC2 share the second step coefficients + // And if the target only has 1 ADC peripheral, just use the ADC1 directly + ctx->coeff = &adc1_error_coef_atten; + ctx->sign = &adc1_error_sign; +} diff --git a/components/esp_adc/esp32c6/curve_fitting_coefficients.c b/components/esp_adc/esp32c6/curve_fitting_coefficients.c new file mode 100644 index 00000000000..39d0f7d3246 --- /dev/null +++ b/components/esp_adc/esp32c6/curve_fitting_coefficients.c @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "esp_efuse_rtc_calib.h" +#include "../curve_fitting_coefficients.h" + +#define COEFF_VERSION_NUM 2 // Currently C6 has two versions of curve calibration schemes + +/** + * @note Error Calculation + * Coefficients for calculating the reading voltage error. + * Four sets of coefficients for atten0 ~ atten3 respectively. + * + * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. + * + * @note {0,0} stands for unused item + * @note In case of the overflow, these coefficients are recorded as Absolute Value + * @note For atten0 ~ 3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. + */ +const static uint64_t adc1_error_coef_atten[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX][2] = { + /* Coefficients of calibration version 1 */ + { + {{487166399931449, 1e15}, {6436483033201, 1e16}, {30410131806, 1e16}, {0, 0}, {0, 0}}, //atten0 + {{8665498165817785, 1e16}, {15239070452946, 1e16}, {13818878844, 1e16}, {0, 0}, {0, 0}}, //atten1 + {{12277821756674387, 1e16}, {22275554717885, 1e16}, {5924302667, 1e16}, {0, 0}, {0, 0}}, //atten2 + {{3801417550380255, 1e16}, {6020352420772, 1e16}, {12442478488, 1e16}, {0, 0}, {0, 0}}, //atten3 + }, + /* Coefficients of calibration version 2 */ + { + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, //atten0 + {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, //atten1 + {{12217864764388775, 1e16}, {1954123107752, 1e16}, {6409679727, 1e16}, {0, 0}, {0, 0}}, //atten2 + {{3915910437042445 , 1e16}, {31536470857564, 1e16}, {12493873014, 1e16}, {0, 0}, {0, 0}}, //atten3 + }, +}; + +/** + * Term sign + */ +const static int32_t adc1_error_sign[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX] = { + /* Coefficient sign of calibration version 1 */ + { + {-1, 1, 1, 0, 0}, //atten0 + {-1, 1, 1, 0, 0}, //atten1 + {-1, 1, 1, 0, 0}, //atten2 + {-1, -1, 1, 0, 0}, //atten3 + }, + /* Coefficient sign of calibration version 2 */ + { + { 0, 0, 0, 0, 0}, //atten0 + { 0, 0, 0, 0, 0}, //atten1 + {-1, -1, 1, 0, 0}, //atten2 + {-1, -1, 1, 0, 0}, //atten3 + }, +}; + + +void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx) +{ + uint32_t adc_calib_ver = esp_efuse_rtc_calib_get_ver(); + assert((adc_calib_ver >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (adc_calib_ver <= ESP_EFUSE_ADC_CALIB_VER_MAX)); + ctx->term_num = 3; + ctx->coeff = &adc1_error_coef_atten[VER2IDX(adc_calib_ver)]; + ctx->sign = &adc1_error_sign[VER2IDX(adc_calib_ver)]; +} diff --git a/components/esp_adc/esp32c6/include/adc_cali_schemes.h b/components/esp_adc/esp32c6/include/adc_cali_schemes.h index cfdd5ad0d54..0fe33833b99 100644 --- a/components/esp_adc/esp32c6/include/adc_cali_schemes.h +++ b/components/esp_adc/esp32c6/include/adc_cali_schemes.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,4 +12,4 @@ * @brief Supported calibration schemes */ -//Now no scheme supported +#define ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED 1 diff --git a/components/esp_adc/esp32s3/curve_fitting_coefficients.c b/components/esp_adc/esp32s3/curve_fitting_coefficients.c index b81ad58c632..6020130f306 100644 --- a/components/esp_adc/esp32s3/curve_fitting_coefficients.c +++ b/components/esp_adc/esp32s3/curve_fitting_coefficients.c @@ -1,11 +1,11 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include - +#include "../curve_fitting_coefficients.h" /** * @note Error Calculation @@ -15,17 +15,17 @@ * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. * * @note {0,0} stands for unused item - * @note In case of the overflow, these coeffcients are recorded as Absolute Value + * @note In case of the overflow, these coefficients are recorded as Absolute Value * @note For atten0 ~ 2, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2); For atten3, error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + (K4 * X^4); * @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. */ -const uint64_t adc1_error_coef_atten[4][5][2] = { +const static uint64_t adc1_error_coef_atten[COEFF_GROUP_NUM][TERM_MAX][2] = { {{27856531419538344, 1e16}, {50871540569528, 1e16}, {9798249589, 1e15}, {0, 0}, {0, 0}}, //ADC1 atten0 {{29831022915028695, 1e16}, {49393185868806, 1e16}, {101379430548, 1e16}, {0, 0}, {0, 0}}, //ADC1 atten1 {{23285545746296417, 1e16}, {147640181047414, 1e16}, {208385525314, 1e16}, {0, 0}, {0, 0}}, //ADC1 atten2 {{644403418269478, 1e15}, {644334888647536, 1e16}, {1297891447611, 1e16}, {70769718, 1e15}, {13515, 1e15}} //ADC1 atten3 }; -const uint64_t adc2_error_coef_atten[4][5][2] = { +const static uint64_t adc2_error_coef_atten[COEFF_GROUP_NUM][TERM_MAX][2] = { {{25668651654328927, 1e16}, {1353548869615, 1e16}, {36615265189, 1e16}, {0, 0}, {0, 0}}, //ADC2 atten0 {{23690184690298404, 1e16}, {66319894226185, 1e16}, {118964995959, 1e16}, {0, 0}, {0, 0}}, //ADC2 atten1 {{9452499397020617, 1e16}, {200996773954387, 1e16}, {259011467956, 1e16}, {0, 0}, {0, 0}}, //ADC2 atten2 @@ -34,15 +34,22 @@ const uint64_t adc2_error_coef_atten[4][5][2] = { /** * Term sign */ -const int32_t adc1_error_sign[4][5] = { +const static int32_t adc1_error_sign[COEFF_GROUP_NUM][TERM_MAX] = { {-1, -1, 1, 0, 0}, //ADC1 atten0 {-1, -1, 1, 0, 0}, //ADC1 atten1 {-1, -1, 1, 0, 0}, //ADC1 atten2 {-1, -1, 1, -1, 1} //ADC1 atten3 }; -const int32_t adc2_error_sign[4][5] = { +const static int32_t adc2_error_sign[COEFF_GROUP_NUM][TERM_MAX] = { {-1, 1, 1, 0, 0}, //ADC2 atten0 {-1, -1, 1, 0, 0}, //ADC2 atten1 {-1, -1, 1, 0, 0}, //ADC2 atten2 { 1, -1, 1, -1, 1} //ADC2 atten3 }; + +void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx) +{ + ctx->term_num = (config->atten == 3) ? 5 : 3; + ctx->coeff = (config->unit_id == ADC_UNIT_1) ? &adc1_error_coef_atten : &adc2_error_coef_atten; + ctx->sign = (config->unit_id == ADC_UNIT_1) ? &adc1_error_sign : &adc2_error_sign; +} diff --git a/components/esp_adc/include/esp_adc/adc_cali_scheme.h b/components/esp_adc/include/esp_adc/adc_cali_scheme.h index 8f148c4c88b..8894c66c1f0 100644 --- a/components/esp_adc/include/esp_adc/adc_cali_scheme.h +++ b/components/esp_adc/include/esp_adc/adc_cali_scheme.h @@ -22,6 +22,7 @@ extern "C" { ---------------------------------------------------------------*/ typedef struct { adc_unit_t unit_id; ///< ADC unit + adc_channel_t chan; ///< ADC channel, for chips with SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED, calibration can be per channel adc_atten_t atten; ///< ADC attenuation adc_bitwidth_t bitwidth; ///< ADC raw output bitwidth } adc_cali_curve_fitting_config_t; diff --git a/components/esp_adc/test_apps/adc/main/test_adc.c b/components/esp_adc/test_apps/adc/main/test_adc.c index d4fc8409db8..6e1055acd3c 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_adc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -149,7 +149,7 @@ static void s_adc_oneshot_with_sleep(adc_unit_t unit_id, adc_channel_t channel) bool do_calibration = false; adc_cali_handle_t cali_handle[TEST_ATTEN_NUMS] = {}; for (int i = 0; i < TEST_ATTEN_NUMS; i++) { - do_calibration = test_adc_calibration_init(unit_id, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); + do_calibration = test_adc_calibration_init(unit_id, channel, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); } if (!do_calibration) { ESP_LOGW(TAG, "No efuse bits burnt, only test the regi2c analog register values"); diff --git a/components/esp_adc/test_apps/adc/main/test_adc_performance.c b/components/esp_adc/test_apps/adc/main/test_adc_performance.c index 366c288baca..db9b7294c84 100644 --- a/components/esp_adc/test_apps/adc/main/test_adc_performance.c +++ b/components/esp_adc/test_apps/adc/main/test_adc_performance.c @@ -324,7 +324,7 @@ static float test_adc_oneshot_std(adc_atten_t atten, bool is_performance_test) //-------------ADC Calibration Init---------------// bool do_calibration = false; adc_cali_handle_t cali_handle = NULL; - do_calibration = test_adc_calibration_init(ADC_UNIT_1, atten, ADC_BITWIDTH_DEFAULT, &cali_handle); + do_calibration = test_adc_calibration_init(ADC_UNIT_1, channel, atten, ADC_BITWIDTH_DEFAULT, &cali_handle); if (!do_calibration) { ESP_LOGW(TAG, "calibration fail, jump calibration\n"); } @@ -420,7 +420,7 @@ static void s_adc_cali_speed(adc_unit_t unit_id, adc_channel_t channel) bool do_calibration = false; adc_cali_handle_t cali_handle[TEST_ATTEN_NUMS] = {}; for (int i = 0; i < TEST_ATTEN_NUMS; i++) { - do_calibration = test_adc_calibration_init(unit_id, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); + do_calibration = test_adc_calibration_init(unit_id, channel, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); } if (!do_calibration) { diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.c b/components/esp_adc/test_apps/adc/main/test_common_adc.c index f9cc81ebf1d..9bb4a3b79f8 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.c +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.c @@ -39,7 +39,7 @@ adc_digi_iir_filter_coeff_t g_test_filter_coeff[TEST_FILTER_COEFF_NUMS] = { /*--------------------------------------------------------------- ADC Calibration ---------------------------------------------------------------*/ -bool test_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle) +bool test_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle) { esp_err_t ret = ESP_FAIL; adc_cali_handle_t handle = NULL; @@ -49,6 +49,7 @@ bool test_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_bitwidth_ ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); adc_cali_curve_fitting_config_t cali_config = { .unit_id = unit, + .chan = channel, .atten = atten, .bitwidth = bitwidth, }; diff --git a/components/esp_adc/test_apps/adc/main/test_common_adc.h b/components/esp_adc/test_apps/adc/main/test_common_adc.h index 87f81d024e8..f77200add22 100644 --- a/components/esp_adc/test_apps/adc/main/test_common_adc.h +++ b/components/esp_adc/test_apps/adc/main/test_common_adc.h @@ -71,11 +71,11 @@ extern "C" { #define ADC_TEST_HIGH_VAL 3400 #define ADC_TEST_HIGH_THRESH 200 -#elif CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5312 -#define ADC_TEST_LOW_VAL 2144 -#define ADC_TEST_LOW_THRESH 200 +#elif CONFIG_IDF_TARGET_ESP32C6 +#define ADC_TEST_LOW_VAL 0 +#define ADC_TEST_LOW_THRESH 15 -#define ADC_TEST_HIGH_VAL 4081 +#define ADC_TEST_HIGH_VAL 3350 #define ADC_TEST_HIGH_VAL_DMA 4081 #define ADC_TEST_HIGH_THRESH 200 @@ -114,13 +114,17 @@ extern adc_digi_iir_filter_coeff_t g_test_filter_coeff[TEST_FILTER_COEFF_NUMS]; /** * @brief Initialise ADC Calibration * - * @param[out] out_handle ADC calibration handle + * @param[in] unit ADC unit + * @param[in] channel ADC channel + * @param[in] atten ADC attenuation + * @param[in] bitwidth ADC bit width + * @param[out] out_handle ADC calibration handle * * @return * - True Calibration success * - False Calibration fail */ -bool test_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle); +bool test_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle); /** * @brief De-initialise ADC Calibration diff --git a/components/esp_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index 5a7cc4a7ac5..57325e8aad8 100644 --- a/components/esp_hw_support/adc_share_hw_ctrl.c +++ b/components/esp_hw_support/adc_share_hw_ctrl.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -68,7 +68,9 @@ void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten) uint32_t init_code = 0; - if (version == ESP_EFUSE_ADC_CALIB_VER) { + if ((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)) { + // Guarantee the calibration version before calling efuse function init_code = esp_efuse_rtc_calib_get_init_code(version, adc_n, atten); } #if SOC_ADC_SELF_HW_CALI_SUPPORTED @@ -96,6 +98,25 @@ void IRAM_ATTR adc_set_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten) { adc_hal_set_calibration_param(adc_n, s_adc_cali_param[adc_n][atten]); } + +#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED +static int s_adc_cali_chan_compens[SOC_ADC_MAX_CHANNEL_NUM][SOC_ADC_ATTEN_NUM] = {}; +void adc_load_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten) +{ + int version = esp_efuse_rtc_calib_get_ver(); + if ((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) && + (version <= ESP_EFUSE_ADC_CALIB_VER_MAX)) { + // Guarantee the calibration version before calling efuse function + s_adc_cali_chan_compens[chan][atten] = esp_efuse_rtc_calib_get_chan_compens(version, adc_n, chan, atten); + } + // No warning when version doesn't match because should has warned in adc_calc_hw_calibration_code +} + +int IRAM_ATTR adc_get_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten) +{ + return s_adc_cali_chan_compens[chan][atten]; +} +#endif // SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED diff --git a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h index d1e118cf727..4d9de5270c6 100644 --- a/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h +++ b/components/esp_hw_support/include/esp_private/adc_share_hw_ctrl.h @@ -45,6 +45,28 @@ void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten); * @param atten Attenuation to use */ void adc_set_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten); + +#if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED +/** + * @brief Load the channel compensation of the ADC HW calibration from eFuse to a static array + * + * @param adc_n ADC unit to compensation + * @param chan ADC channel to compensation + * @param atten Attenuation to use + */ +void adc_load_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten); + +/** + * @brief Get the channel compensation of the ADC HW calibration from the static array + * that have been loaded from eFuse + * + * @param adc_n ADC unit to compensation + * @param chan ADC channel to compensation + * @param atten Attenuation to use + * @return The channel compensation + */ +int adc_get_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten); +#endif // SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED diff --git a/components/esp_hw_support/port/esp32c6/CMakeLists.txt b/components/esp_hw_support/port/esp32c6/CMakeLists.txt index 92e9f981b47..e82e407cb0e 100644 --- a/components/esp_hw_support/port/esp32c6/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c6/CMakeLists.txt @@ -5,6 +5,7 @@ set(srcs "rtc_clk_init.c" "pmu_sleep.c" "rtc_time.c" "chip_info.c" + "ocode_init.c" ) if(NOT BOOTLOADER_BUILD) diff --git a/components/esp_hw_support/port/esp32c6/ocode_init.c b/components/esp_hw_support/port/esp32c6/ocode_init.c new file mode 100644 index 00000000000..04743d7d6a7 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/ocode_init.c @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/regi2c_dig_reg.h" +#include "soc/regi2c_lp_bias.h" +#include "hal/efuse_hal.h" +#include "hal/efuse_ll.h" +#include "regi2c_ctrl.h" +#include "esp_hw_log.h" + + +static const char *TAG = "ocode_init"; + +static void set_ocode_by_efuse(int ocode_scheme_ver) +{ + assert(ocode_scheme_ver == 1); + unsigned int ocode = efuse_ll_get_ocode(); + + //set ext_ocode + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode); + REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1); +} + +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). + Method: + 1. read current cpu config, save in old_config; + 2. switch cpu to xtal because PLL will be closed when o-code calibration; + 3. begin o-code calibration; + 4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout; + 5. set cpu to old-config. + */ + soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); + rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX; + if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + cal_clk = RTC_CAL_32K_OSC_SLOW; + } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + cal_clk = RTC_CAL_32K_XTAL; + } + + uint64_t max_delay_time_us = 10000; + 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 cycle0 = rtc_time_get(); + uint64_t timeout_cycle = cycle0 + max_delay_cycle; + uint64_t cycle1 = 0; + + rtc_cpu_freq_config_t old_config; + rtc_clk_cpu_freq_get_config(&old_config); + 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, 1); + bool odone_flag = 0; + bool bg_odone_flag = 0; + while (1) { + 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); + cycle1 = rtc_time_get(); + if (odone_flag && bg_odone_flag) { + break; + } + if (cycle1 >= timeout_cycle) { + ESP_HW_LOGW(TAG, "o_code calibration fail\n"); + break; + } + } + rtc_clk_cpu_freq_set_config(&old_config); +} + +void esp_ocode_calib_init(void) +{ + if (efuse_hal_blk_version() >= 1) { + set_ocode_by_efuse(1); + } else { + calibrate_ocode(); + } +} diff --git a/components/esp_hw_support/port/esp32c6/private_include/ocode_init.h b/components/esp_hw_support/port/esp32c6/private_include/ocode_init.h new file mode 100644 index 00000000000..44f1f887096 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/private_include/ocode_init.h @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize OCode + * + */ +void esp_ocode_calib_init(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index fd3dff36785..fa1d6682e1c 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -26,6 +26,7 @@ #include "esp_private/esp_pmu.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" +#include "ocode_init.h" /* Number of cycles to wait from the 32k XTAL oscillator to consider it running. * Larger values increase startup delay. Smaller values may cause false positive @@ -44,6 +45,9 @@ static const char *TAG = "clk"; { #if !CONFIG_IDF_ENV_FPGA pmu_init(); + if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { + esp_ocode_calib_init(); + } assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); diff --git a/components/hal/adc_hal_common.c b/components/hal/adc_hal_common.c index 7d39ca139c8..4ea7ff95364 100644 --- a/components/hal/adc_hal_common.c +++ b/components/hal/adc_hal_common.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -204,7 +204,6 @@ uint32_t adc_hal_self_calibration(adc_unit_t adc_n, adc_atten_t atten, bool inte adc_ll_calibration_finish(adc_n); return ret; - return 0; } #endif //#if SOC_ADC_SELF_HW_CALI_SUPPORTED #endif //SOC_ADC_CALIBRATION_V1_SUPPORTED diff --git a/components/hal/efuse_hal.c b/components/hal/efuse_hal.c index 6a46c85d36f..8d94e82641b 100644 --- a/components/hal/efuse_hal.c +++ b/components/hal/efuse_hal.c @@ -24,6 +24,16 @@ IRAM_ATTR uint32_t efuse_hal_chip_revision(void) return efuse_hal_get_major_chip_version() * 100 + efuse_hal_get_minor_chip_version(); } +uint32_t efuse_hal_blk_version(void) +{ + return efuse_ll_get_blk_version_major() * 100 + efuse_ll_get_blk_version_minor(); +} + +IRAM_ATTR bool efuse_hal_get_disable_wafer_version_major(void) +{ + return efuse_ll_get_disable_wafer_version_major(); +} + IRAM_ATTR bool efuse_hal_flash_encryption_enabled(void) { uint32_t flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt(); diff --git a/components/hal/esp32/include/hal/efuse_ll.h b/components/hal/esp32/include/hal/efuse_ll.h index 17cdd2b133d..62e6b267f88 100644 --- a/components/hal/esp32/include/hal/efuse_ll.h +++ b/components/hal/esp32/include/hal/efuse_ll.h @@ -119,6 +119,16 @@ __attribute__((always_inline)) static inline bool efuse_ll_get_disable_wafer_ver return false; } +__attribute__((always_inline)) static inline bool efuse_ll_get_blk_version_major(void) +{ + return 0; +} + +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_blk_version_minor(void) +{ + return 0; +} + __attribute__((always_inline)) static inline uint32_t efuse_ll_get_coding_scheme(void) { return EFUSE.blk0_rdata6.rd_coding_scheme; diff --git a/components/hal/esp32c6/include/hal/adc_ll.h b/components/hal/esp32c6/include/hal/adc_ll.h index 90eb962f8dc..6f9a675540e 100644 --- a/components/hal/esp32c6/include/hal/adc_ll.h +++ b/components/hal/esp32c6/include/hal/adc_ll.h @@ -540,7 +540,7 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c __attribute__((always_inline)) static inline void adc_ll_calibration_init(adc_unit_t adc_n) { - HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)adc_n; REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); } diff --git a/components/hal/esp32c6/include/hal/efuse_ll.h b/components/hal/esp32c6/include/hal/efuse_ll.h index 91a005e6270..d9a10ba584a 100644 --- a/components/hal/esp32c6/include/hal/efuse_ll.h +++ b/components/hal/esp32c6/include/hal/efuse_ll.h @@ -82,6 +82,11 @@ __attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg( return EFUSE.rd_mac_spi_sys_3.pkg_version; } +__attribute__((always_inline)) static inline uint32_t efuse_ll_get_ocode(void) +{ + return EFUSE.rd_sys_part1_data4.ocode; +} + /******************* eFuse control functions *************************/ __attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void) diff --git a/components/hal/esp32h2/include/hal/adc_ll.h b/components/hal/esp32h2/include/hal/adc_ll.h index 22266ca152e..4e67ad81de4 100644 --- a/components/hal/esp32h2/include/hal/adc_ll.h +++ b/components/hal/esp32h2/include/hal/adc_ll.h @@ -540,7 +540,7 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c __attribute__((always_inline)) static inline void adc_ll_calibration_init(adc_unit_t adc_n) { - HAL_ASSERT(adc_n == ADC_UNIT_1); + (void)adc_n; REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); } diff --git a/components/hal/include/hal/efuse_hal.h b/components/hal/include/hal/efuse_hal.h index a30c77da5ad..469b869d447 100644 --- a/components/hal/include/hal/efuse_hal.h +++ b/components/hal/include/hal/efuse_hal.h @@ -27,6 +27,13 @@ void efuse_hal_get_mac(uint8_t *mac); */ uint32_t efuse_hal_chip_revision(void); +/** + * @brief Return block version + * + * @return Block version in format: Major * 100 + Minor + */ +uint32_t efuse_hal_blk_version(void); + /** * @brief Is flash encryption currently enabled in hardware? * diff --git a/components/idf_test/include/esp32c6/idf_performance_target.h b/components/idf_test/include/esp32c6/idf_performance_target.h index 61c8f64acb4..f300dfc5784 100644 --- a/components/idf_test/include/esp32c6/idf_performance_target.h +++ b/components/idf_test/include/esp32c6/idf_performance_target.h @@ -23,10 +23,10 @@ #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 32 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 15 -//TODO: IDF-5312 -#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER 10 -#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2 10 -#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4 10 -#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8 10 -#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16 10 -#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64 10 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER 5 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2 5 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4 5 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8 5 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16 5 +#define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64 5 +#define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3 5 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 67da921a0fc..6c94bda2b36 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -285,7 +285,15 @@ config SOC_ADC_RTC_MAX_BITWIDTH config SOC_ADC_CALIBRATION_V1_SUPPORTED bool - default n + default y + +config SOC_ADC_SELF_HW_CALI_SUPPORTED + bool + default y + +config SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED + bool + default y config SOC_ADC_TEMPERATURE_SHARE_INTR bool diff --git a/components/soc/esp32c6/include/soc/efuse_reg.h b/components/soc/esp32c6/include/soc/efuse_reg.h index 2d539b55088..6caf63d8900 100644 --- a/components/soc/esp32c6/include/soc/efuse_reg.h +++ b/components/soc/esp32c6/include/soc/efuse_reg.h @@ -799,49 +799,168 @@ extern "C" { * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA4_REG (DR_REG_EFUSE_BASE + 0x6c) -/** EFUSE_SYS_DATA_PART1_4 : RO; bitpos: [31:0]; default: 0; - * Stores the fourth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_4 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_4_M (EFUSE_SYS_DATA_PART1_4_V << EFUSE_SYS_DATA_PART1_4_S) -#define EFUSE_SYS_DATA_PART1_4_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_4_S 0 +/** EFUSE_TEMP_CALIB : R; bitpos: [8:0]; default: 0; + * Temperature calibration data + */ +#define EFUSE_TEMP_CALIB 0x000001FFU +#define EFUSE_TEMP_CALIB_M (EFUSE_TEMP_CALIB_V << EFUSE_TEMP_CALIB_S) +#define EFUSE_TEMP_CALIB_V 0x000001FFU +#define EFUSE_TEMP_CALIB_S 0 +/** EFUSE_OCODE : R; bitpos: [16:9]; default: 0; + * ADC OCode + */ +#define EFUSE_OCODE 0x000000FFU +#define EFUSE_OCODE_M (EFUSE_OCODE_V << EFUSE_OCODE_S) +#define EFUSE_OCODE_V 0x000000FFU +#define EFUSE_OCODE_S 9 +/** EFUSE_ADC1_INIT_CODE_ATTEN0 : R; bitpos: [26:17]; default: 0; + * ADC1 init code at atten0 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_M (EFUSE_ADC1_INIT_CODE_ATTEN0_V << EFUSE_ADC1_INIT_CODE_ATTEN0_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_V 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_S 17 +/** EFUSE_ADC1_INIT_CODE_ATTEN1 : R; bitpos: [31:27]; default: 0; + * ADC1 init code at atten1 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN1 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_M (EFUSE_ADC1_INIT_CODE_ATTEN1_V << EFUSE_ADC1_INIT_CODE_ATTEN1_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN1_V 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_S 27 /** EFUSE_RD_SYS_PART1_DATA5_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA5_REG (DR_REG_EFUSE_BASE + 0x70) -/** EFUSE_SYS_DATA_PART1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_5 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_M (EFUSE_SYS_DATA_PART1_5_V << EFUSE_SYS_DATA_PART1_5_S) -#define EFUSE_SYS_DATA_PART1_5_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_5_S 0 +/** EFUSE_ADC1_INIT_CODE_ATTEN1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 init code at atten1 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1_M (EFUSE_ADC1_INIT_CODE_ATTEN1_1_V << EFUSE_ADC1_INIT_CODE_ATTEN1_1_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1_V 0x0000001FU +#define EFUSE_ADC1_INIT_CODE_ATTEN1_1_S 0 +/** EFUSE_ADC1_INIT_CODE_ATTEN2 : R; bitpos: [14:5]; default: 0; + * ADC1 init code at atten2 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN2 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN2_M (EFUSE_ADC1_INIT_CODE_ATTEN2_V << EFUSE_ADC1_INIT_CODE_ATTEN2_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN2_S 5 +/** EFUSE_ADC1_INIT_CODE_ATTEN3 : R; bitpos: [24:15]; default: 0; + * ADC1 init code at atten3 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN3 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN3_M (EFUSE_ADC1_INIT_CODE_ATTEN3_V << EFUSE_ADC1_INIT_CODE_ATTEN3_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN3_V 0x000003FFU +#define EFUSE_ADC1_INIT_CODE_ATTEN3_S 15 +/** EFUSE_ADC1_CAL_VOL_ATTEN0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration voltage at atten0 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN0 0x0000007FU +#define EFUSE_ADC1_CAL_VOL_ATTEN0_M (EFUSE_ADC1_CAL_VOL_ATTEN0_V << EFUSE_ADC1_CAL_VOL_ATTEN0_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN0_V 0x0000007FU +#define EFUSE_ADC1_CAL_VOL_ATTEN0_S 25 /** EFUSE_RD_SYS_PART1_DATA6_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA6_REG (DR_REG_EFUSE_BASE + 0x74) -/** EFUSE_SYS_DATA_PART1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. - */ -#define EFUSE_SYS_DATA_PART1_6 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_M (EFUSE_SYS_DATA_PART1_6_V << EFUSE_SYS_DATA_PART1_6_S) -#define EFUSE_SYS_DATA_PART1_6_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_6_S 0 +/** EFUSE_ADC1_CAL_VOL_ATTEN0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration voltage at atten0 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1 0x00000007U +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1_M (EFUSE_ADC1_CAL_VOL_ATTEN0_1_V << EFUSE_ADC1_CAL_VOL_ATTEN0_1_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1_V 0x00000007U +#define EFUSE_ADC1_CAL_VOL_ATTEN0_1_S 0 +/** EFUSE_ADC1_CAL_VOL_ATTEN1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration voltage at atten1 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN1 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN1_M (EFUSE_ADC1_CAL_VOL_ATTEN1_V << EFUSE_ADC1_CAL_VOL_ATTEN1_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN1_V 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN1_S 3 +/** EFUSE_ADC1_CAL_VOL_ATTEN2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration voltage at atten2 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN2 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN2_M (EFUSE_ADC1_CAL_VOL_ATTEN2_V << EFUSE_ADC1_CAL_VOL_ATTEN2_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN2_V 0x000003FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN2_S 13 +/** EFUSE_ADC1_CAL_VOL_ATTEN3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration voltage at atten3 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN3 0x000001FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN3_M (EFUSE_ADC1_CAL_VOL_ATTEN3_V << EFUSE_ADC1_CAL_VOL_ATTEN3_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN3_V 0x000001FFU +#define EFUSE_ADC1_CAL_VOL_ATTEN3_S 23 /** EFUSE_RD_SYS_PART1_DATA7_REG register * Register $n of BLOCK2 (system). */ #define EFUSE_RD_SYS_PART1_DATA7_REG (DR_REG_EFUSE_BASE + 0x78) -/** EFUSE_SYS_DATA_PART1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. +/** EFUSE_ADC1_CAL_VOL_ATTEN3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration voltage at atten3 + */ +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1 (BIT(0)) +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1_M (EFUSE_ADC1_CAL_VOL_ATTEN3_1_V << EFUSE_ADC1_CAL_VOL_ATTEN3_1_S) +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1_V 0x00000001U +#define EFUSE_ADC1_CAL_VOL_ATTEN3_1_S 0 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH0 : R; bitpos: [4:1]; default: 0; + * ADC1 init code at atten0 ch0 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH0_S 1 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH1 : R; bitpos: [8:5]; default: 0; + * ADC1 init code at atten0 ch1 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH1_S 5 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH2 : R; bitpos: [12:9]; default: 0; + * ADC1 init code at atten0 ch2 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH2_S 9 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH3 : R; bitpos: [16:13]; default: 0; + * ADC1 init code at atten0 ch3 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH3_S 13 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH4 : R; bitpos: [20:17]; default: 0; + * ADC1 init code at atten0 ch4 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH4_S 17 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH5 : R; bitpos: [24:21]; default: 0; + * ADC1 init code at atten0 ch5 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH5_S 21 +/** EFUSE_ADC1_INIT_CODE_ATTEN0_CH6 : R; bitpos: [28:25]; default: 0; + * ADC1 init code at atten0 ch6 + */ +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_M (EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_V << EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_S) +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_V 0x0000000FU +#define EFUSE_ADC1_INIT_CODE_ATTEN0_CH6_S 25 +/** EFUSE_RESERVED_2_253 : R; bitpos: [31:29]; default: 0; + * reserved */ -#define EFUSE_SYS_DATA_PART1_7 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_M (EFUSE_SYS_DATA_PART1_7_V << EFUSE_SYS_DATA_PART1_7_S) -#define EFUSE_SYS_DATA_PART1_7_V 0xFFFFFFFFU -#define EFUSE_SYS_DATA_PART1_7_S 0 +#define EFUSE_RESERVED_2_253 0x00000007U +#define EFUSE_RESERVED_2_253_M (EFUSE_RESERVED_2_253_V << EFUSE_RESERVED_2_253_S) +#define EFUSE_RESERVED_2_253_V 0x00000007U +#define EFUSE_RESERVED_2_253_S 29 /** EFUSE_RD_USR_DATA0_REG register * Register $n of BLOCK3 (user). diff --git a/components/soc/esp32c6/include/soc/efuse_struct.h b/components/soc/esp32c6/include/soc/efuse_struct.h index 8342078efb6..08a60cf5b14 100644 --- a/components/soc/esp32c6/include/soc/efuse_struct.h +++ b/components/soc/esp32c6/include/soc/efuse_struct.h @@ -639,10 +639,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_4 : RO; bitpos: [31:0]; default: 0; - * Stores the fourth 32 bits of the first part of system data. + /** temp_calib : R; bitpos: [8:0]; default: 0; + * Temperature calibration data */ - uint32_t sys_data_part1_4:32; + uint32_t temp_calib:9; + /** ocode : R; bitpos: [16:9]; default: 0; + * ADC OCode + */ + uint32_t ocode:8; + /** adc1_init_code_atten0 : R; bitpos: [26:17]; default: 0; + * ADC1 init code at atten0 + */ + uint32_t adc1_init_code_atten0:10; + /** adc1_init_code_atten1 : R; bitpos: [31:27]; default: 0; + * ADC1 init code at atten1 + */ + uint32_t adc1_init_code_atten1:5; }; uint32_t val; } efuse_rd_sys_part1_data4_reg_t; @@ -652,10 +664,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_5 : RO; bitpos: [31:0]; default: 0; - * Stores the fifth 32 bits of the first part of system data. + /** adc1_init_code_atten1_1 : R; bitpos: [4:0]; default: 0; + * ADC1 init code at atten1 + */ + uint32_t adc1_init_code_atten1_1:5; + /** adc1_init_code_atten2 : R; bitpos: [14:5]; default: 0; + * ADC1 init code at atten2 + */ + uint32_t adc1_init_code_atten2:10; + /** adc1_init_code_atten3 : R; bitpos: [24:15]; default: 0; + * ADC1 init code at atten3 */ - uint32_t sys_data_part1_5:32; + uint32_t adc1_init_code_atten3:10; + /** adc1_cal_vol_atten0 : R; bitpos: [31:25]; default: 0; + * ADC1 calibration voltage at atten0 + */ + uint32_t adc1_cal_vol_atten0:7; }; uint32_t val; } efuse_rd_sys_part1_data5_reg_t; @@ -665,10 +689,22 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_6 : RO; bitpos: [31:0]; default: 0; - * Stores the sixth 32 bits of the first part of system data. + /** adc1_cal_vol_atten0_1 : R; bitpos: [2:0]; default: 0; + * ADC1 calibration voltage at atten0 + */ + uint32_t adc1_cal_vol_atten0_1:3; + /** adc1_cal_vol_atten1 : R; bitpos: [12:3]; default: 0; + * ADC1 calibration voltage at atten1 + */ + uint32_t adc1_cal_vol_atten1:10; + /** adc1_cal_vol_atten2 : R; bitpos: [22:13]; default: 0; + * ADC1 calibration voltage at atten2 + */ + uint32_t adc1_cal_vol_atten2:10; + /** adc1_cal_vol_atten3 : R; bitpos: [31:23]; default: 0; + * ADC1 calibration voltage at atten3 */ - uint32_t sys_data_part1_6:32; + uint32_t adc1_cal_vol_atten3:9; }; uint32_t val; } efuse_rd_sys_part1_data6_reg_t; @@ -678,10 +714,42 @@ typedef union { */ typedef union { struct { - /** sys_data_part1_7 : RO; bitpos: [31:0]; default: 0; - * Stores the seventh 32 bits of the first part of system data. + /** adc1_cal_vol_atten3_1 : R; bitpos: [0]; default: 0; + * ADC1 calibration voltage at atten3 + */ + uint32_t adc1_cal_vol_atten3_1:1; + /** adc1_init_code_atten0_ch0 : R; bitpos: [4:1]; default: 0; + * ADC1 init code at atten0 ch0 + */ + uint32_t adc1_init_code_atten0_ch0:4; + /** adc1_init_code_atten0_ch1 : R; bitpos: [8:5]; default: 0; + * ADC1 init code at atten0 ch1 + */ + uint32_t adc1_init_code_atten0_ch1:4; + /** adc1_init_code_atten0_ch2 : R; bitpos: [12:9]; default: 0; + * ADC1 init code at atten0 ch2 + */ + uint32_t adc1_init_code_atten0_ch2:4; + /** adc1_init_code_atten0_ch3 : R; bitpos: [16:13]; default: 0; + * ADC1 init code at atten0 ch3 + */ + uint32_t adc1_init_code_atten0_ch3:4; + /** adc1_init_code_atten0_ch4 : R; bitpos: [20:17]; default: 0; + * ADC1 init code at atten0 ch4 + */ + uint32_t adc1_init_code_atten0_ch4:4; + /** adc1_init_code_atten0_ch5 : R; bitpos: [24:21]; default: 0; + * ADC1 init code at atten0 ch5 + */ + uint32_t adc1_init_code_atten0_ch5:4; + /** adc1_init_code_atten0_ch6 : R; bitpos: [28:25]; default: 0; + * ADC1 init code at atten0 ch6 + */ + uint32_t adc1_init_code_atten0_ch6:4; + /** reserved_2_253 : R; bitpos: [31:29]; default: 0; + * reserved */ - uint32_t sys_data_part1_7:32; + uint32_t reserved_2_253:3; }; uint32_t val; } efuse_rd_sys_part1_data7_reg_t; diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index c13854ee916..fb715701bad 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -114,7 +114,9 @@ #define SOC_ADC_RTC_MAX_BITWIDTH (12) /*!< Calibration */ -#define SOC_ADC_CALIBRATION_V1_SUPPORTED (0) /*!< support HW offset calibration version 1*/ +#define SOC_ADC_CALIBRATION_V1_SUPPORTED (1) /*!< support HW offset calibration version 1*/ +#define SOC_ADC_SELF_HW_CALI_SUPPORTED (1) /*!< support HW offset self calibration */ +#define SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED (1) /*!< support channel compensation to the HW offset calibration */ /*!< Interrupt */ #define SOC_ADC_TEMPERATURE_SHARE_INTR (1) diff --git a/docs/en/api-reference/peripherals/adc_calibration.rst b/docs/en/api-reference/peripherals/adc_calibration.rst index 78dcaead03f..c058219c51e 100644 --- a/docs/en/api-reference/peripherals/adc_calibration.rst +++ b/docs/en/api-reference/peripherals/adc_calibration.rst @@ -80,16 +80,27 @@ For those users who use their custom ADC calibration schemes, you could either m ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle)); -.. only:: esp32c3 or esp32s3 +.. only:: esp32c3 or esp32s3 or esp32c6 ADC Calibration Curve Fitting Scheme ```````````````````````````````````` {IDF_TARGET_NAME} supports :c:macro:`ADC_CALI_SCHEME_VER_CURVE_FITTING` scheme. To create this scheme, set up :cpp:type:`adc_cali_curve_fitting_config_t` first. - - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. - - :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. - - :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, the ADC raw result bitwidth. + + .. only:: not esp32c6 + + - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. + - :cpp:member:`adc_cali_curve_fitting_config_t::chan`, this member is kept here for extensibility. The calibration scheme only differs by attenuation, there's no difference among different channels. + - :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. + - :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, the ADC raw result bitwidth. + + .. only:: esp32c6 + + - :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. + - :cpp:member:`adc_cali_curve_fitting_config_t::chan`, the ADC channel that your ADC raw results are from. The calibration scheme not only differs by attenuation but also related to the channels. + - :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. + - :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, the ADC raw result bitwidth. After setting up the configuration structure, call :cpp:func:`adc_cali_create_scheme_curve_fitting` to create a Curve Fitting calibration scheme handle. This function may fail due to reasons such as :c:macro:`ESP_ERR_INVALID_ARG` or :c:macro:`ESP_ERR_NO_MEM`. Especially, when the function return :c:macro:`ESP_ERR_NOT_SUPPORTED`, this means the calibration scheme required eFuse bits are not burnt on your board. diff --git a/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c b/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c index dd831b1f89f..25ffc14d8bf 100644 --- a/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c +++ b/examples/peripherals/adc/oneshot_read/main/oneshot_read_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -49,7 +49,7 @@ const static char *TAG = "EXAMPLE"; static int adc_raw[2][10]; static int voltage[2][10]; -static bool example_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle); +static bool example_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_cali_handle_t *out_handle); static void example_adc_calibration_deinit(adc_cali_handle_t handle); @@ -71,8 +71,10 @@ void app_main(void) ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config)); //-------------ADC1 Calibration Init---------------// - adc_cali_handle_t adc1_cali_handle = NULL; - bool do_calibration1 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC_ATTEN, &adc1_cali_handle); + adc_cali_handle_t adc1_cali_chan0_handle = NULL; + adc_cali_handle_t adc1_cali_chan1_handle = NULL; + bool do_calibration1_chan0 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN0, EXAMPLE_ADC_ATTEN, &adc1_cali_chan0_handle); + bool do_calibration1_chan1 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN1, EXAMPLE_ADC_ATTEN, &adc1_cali_chan1_handle); #if EXAMPLE_USE_ADC2 @@ -86,7 +88,7 @@ void app_main(void) //-------------ADC2 Calibration Init---------------// adc_cali_handle_t adc2_cali_handle = NULL; - bool do_calibration2 = example_adc_calibration_init(ADC_UNIT_2, EXAMPLE_ADC_ATTEN, &adc2_cali_handle); + bool do_calibration2 = example_adc_calibration_init(ADC_UNIT_2, EXAMPLE_ADC2_CHAN0, EXAMPLE_ADC_ATTEN, &adc2_cali_handle); //-------------ADC2 Config---------------// ESP_ERROR_CHECK(adc_oneshot_config_channel(adc2_handle, EXAMPLE_ADC2_CHAN0, &config)); @@ -95,16 +97,16 @@ void app_main(void) while (1) { ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0])); ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]); - if (do_calibration1) { - ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, adc_raw[0][0], &voltage[0][0])); + if (do_calibration1_chan0) { + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, adc_raw[0][0], &voltage[0][0])); ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]); } vTaskDelay(pdMS_TO_TICKS(1000)); ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN1, &adc_raw[0][1])); ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN1, adc_raw[0][1]); - if (do_calibration1) { - ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, adc_raw[0][1], &voltage[0][1])); + if (do_calibration1_chan1) { + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan1_handle, adc_raw[0][1], &voltage[0][1])); ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN1, voltage[0][1]); } vTaskDelay(pdMS_TO_TICKS(1000)); @@ -122,8 +124,11 @@ void app_main(void) //Tear Down ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle)); - if (do_calibration1) { - example_adc_calibration_deinit(adc1_cali_handle); + if (do_calibration1_chan0) { + example_adc_calibration_deinit(adc1_cali_chan0_handle); + } + if (do_calibration1_chan1) { + example_adc_calibration_deinit(adc1_cali_chan1_handle); } #if EXAMPLE_USE_ADC2 @@ -138,7 +143,7 @@ void app_main(void) /*--------------------------------------------------------------- ADC Calibration ---------------------------------------------------------------*/ -static bool example_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle) +static bool example_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_cali_handle_t *out_handle) { adc_cali_handle_t handle = NULL; esp_err_t ret = ESP_FAIL; @@ -149,6 +154,7 @@ static bool example_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); adc_cali_curve_fitting_config_t cali_config = { .unit_id = unit, + .chan = channel, .atten = atten, .bitwidth = ADC_BITWIDTH_DEFAULT, };