diff --git a/components/efuse/esp32c2/esp_efuse_rtc_calib.c b/components/efuse/esp32c2/esp_efuse_rtc_calib.c index 79c3409ddf..0e36070959 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 f4e42f2996..a012fc872d 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 5977b43291..be61b54f89 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 1f6e4748bd..b5c9912d20 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 782943ce0b..5477b095a4 100644 --- a/components/efuse/esp32c6/esp_efuse_rtc_calib.c +++ b/components/efuse/esp32c6/esp_efuse_rtc_calib.c @@ -20,8 +20,11 @@ int esp_efuse_rtc_calib_get_ver(void) { uint32_t cali_version = 0; - if (efuse_hal_blk_version() >= 1) { - cali_version = ESP_EFUSE_ADC_CALIB_VER; + 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"); } @@ -31,7 +34,7 @@ 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); + /* Version validation should be guaranteed in the caller */ assert(atten >=0 && atten < 4); (void) adc_unit; @@ -56,7 +59,7 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten) { - assert(version == ESP_EFUSE_ADC_CALIB_VER); + /* Version validation should be guaranteed in the caller */ assert(atten < 4); assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit)); @@ -95,34 +98,35 @@ int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_ 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; - uint32_t calib_vol_expected_mv; - if (version != ESP_EFUSE_ADC_CALIB_VER) { + 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; } - if (atten == 0) { - cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN0; - calib_vol_expected_mv = 400; - } else if (atten == 1) { - cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN1; - calib_vol_expected_mv = 550; - } else if (atten == 2) { - cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN2; - calib_vol_expected_mv = 750; - } else { - cal_vol_efuse = ESP_EFUSE_ADC1_CAL_VOL_ATTEN3; - calib_vol_expected_mv = 1370; - } - assert(cal_vol_efuse[0]->bit_count == 10); + + assert(cal_vol_efuse[atten][0]->bit_count == 10); uint32_t cal_vol = 0; - ESP_ERROR_CHECK(esp_efuse_read_field_blob(cal_vol_efuse, &cal_vol, cal_vol_efuse[0]->bit_count)); - - *out_digi = 1500 + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9); - *out_vol_mv = calib_vol_expected_mv; + 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 8a787731a7..e6bf085e8a 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. diff --git a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h index be31c4a2e3..e2cb7610fd 100644 --- a/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h +++ b/components/efuse/esp32c6/include/esp_efuse_rtc_calib.h @@ -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 * diff --git a/components/efuse/esp32c6/include/esp_efuse_table.h b/components/efuse/esp32c6/include/esp_efuse_table.h index 5c58f61359..28379f9672 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. diff --git a/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h b/components/efuse/esp32h2/include/esp_efuse_rtc_calib.h index f2dcc89d2d..a71ed13784 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 f6f5d16845..e9b8679485 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 800a2abeaf..540fd9afc0 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 0f0f37938d..49712040a0 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 b401536871..38db70f525 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,11 +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"; @@ -48,12 +48,6 @@ 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 @@ -65,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); @@ -81,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"); @@ -100,7 +94,7 @@ 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; @@ -157,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; @@ -183,19 +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 || SOC_ADC_PERIPH_NUM == 1 - // 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->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) { @@ -211,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/curve_fitting_coefficients.h b/components/esp_adc/curve_fitting_coefficients.h index 1a77ac6b76..79f08dc7bf 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 -/** - * @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 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 - */ -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]; +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; /** - * Term sign + * @brief Assign the second step coefficients for curve calibration + * + * @param config the curve fitting configuration + * @param ctx the context pointer of the second step configuration structure */ -extern const int32_t adc1_error_sign[COEFF_GROUP_NUM][TERM_MAX]; -extern const int32_t adc2_error_sign[COEFF_GROUP_NUM][TERM_MAX]; +void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx); + +#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 dde0ebe40f..6eae21f7a5 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 c8f8d5776e..47a4b4eec7 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 index b008de1de7..39d0f7d324 100644 --- a/components/esp_adc/esp32c6/curve_fitting_coefficients.c +++ b/components/esp_adc/esp32c6/curve_fitting_coefficients.c @@ -4,7 +4,12 @@ * 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 @@ -15,22 +20,53 @@ * * @note {0,0} stands for unused item * @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 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 uint64_t adc1_error_coef_atten[4][5][2] = { - {{487166399931449, 1e16}, {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 - }; +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 int32_t adc1_error_sign[4][5] = { - {-1, 1, 1, 0, 0}, //atten0 - {-1, 1, 1, 0, 0}, //atten1 - {-1, 1, 1, 0, 0}, //atten2 - {-1, -1, 1, 0, 0} //atten3 - }; +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/esp32s3/curve_fitting_coefficients.c b/components/esp_adc/esp32s3/curve_fitting_coefficients.c index b81ad58c63..6020130f30 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_hw_support/adc_share_hw_ctrl.c b/components/esp_hw_support/adc_share_hw_ctrl.c index 8a96b90b35..57325e8aad 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 @@ -102,7 +104,12 @@ 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(); - s_adc_cali_chan_compens[chan][atten] = esp_efuse_rtc_calib_get_chan_compens(version, adc_n, chan, atten); + 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)