mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
adc_calib: support calibration v2 on esp32c6
This commit is contained in:
parent
6fc45d4978
commit
f949819976
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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,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 >=0 && atten < 4);
|
||||
(void) adc_unit;
|
||||
|
||||
@ -56,7 +60,8 @@ 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);
|
||||
assert((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) &&
|
||||
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
|
||||
assert(atten < 4);
|
||||
assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit));
|
||||
|
||||
@ -95,34 +100,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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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, 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];
|
||||
|
@ -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 <stdint.h>
|
||||
#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
|
||||
|
@ -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;
|
||||
|
@ -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 <stdint.h>
|
||||
#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;
|
||||
}
|
||||
|
@ -4,7 +4,12 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#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,54 @@
|
||||
*
|
||||
* @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;
|
||||
printf("ver %lu index %lu\n", adc_calib_ver, VER2IDX(adc_calib_ver));
|
||||
ctx->coeff = &adc1_error_coef_atten[VER2IDX(adc_calib_ver)];
|
||||
ctx->sign = &adc1_error_sign[VER2IDX(adc_calib_ver)];
|
||||
}
|
||||
|
@ -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 <stdint.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -68,7 +68,8 @@ 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)) {
|
||||
init_code = esp_efuse_rtc_calib_get_init_code(version, adc_n, atten);
|
||||
}
|
||||
#if SOC_ADC_SELF_HW_CALI_SUPPORTED
|
||||
|
Loading…
Reference in New Issue
Block a user