mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
refactor(adc_calib): Simplify 2nd step coefficient calculation
- remove unnecessary variables and calculations - improve readability of code
This commit is contained in:
parent
5354759735
commit
edc1abc8ea
@ -65,10 +65,14 @@ 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_MIN) &&
|
||||
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
|
||||
assert(atten <= ADC_ATTEN_DB_11);
|
||||
(void) adc_unit;
|
||||
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 == ADC_ATTEN_DB_2_5 || atten == ADC_ATTEN_DB_6) {
|
||||
/**
|
||||
|
@ -34,8 +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_MIN) &&
|
||||
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
|
||||
/* Version validation should be guaranteed in the caller */
|
||||
assert(atten >=0 && atten < 4);
|
||||
(void) adc_unit;
|
||||
|
||||
@ -60,8 +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_MIN) &&
|
||||
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
|
||||
/* Version validation should be guaranteed in the caller */
|
||||
assert(atten < 4);
|
||||
assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit));
|
||||
|
||||
|
@ -63,9 +63,13 @@ 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_MIN) &&
|
||||
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
|
||||
assert(atten < 4);
|
||||
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(adc_unit <= ADC_UNIT_2);
|
||||
|
||||
int efuse_vol_bits = 0;
|
||||
|
@ -59,7 +59,7 @@ 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 int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step_t *param, adc_atten_t atten);
|
||||
static int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step_t *param);
|
||||
static esp_err_t check_valid(const adc_cali_curve_fitting_config_t *config);
|
||||
|
||||
/* ------------------------ Interface Functions --------------------------- */
|
||||
@ -140,7 +140,7 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage)
|
||||
#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);
|
||||
int32_t error = get_reading_error(v_cali_1, &(ctx->chars_second_step));
|
||||
|
||||
*voltage = (int32_t)v_cali_1 - error;
|
||||
|
||||
@ -179,9 +179,9 @@ static void calc_first_step_coefficients(const adc_calib_info_t *parsed_data, ca
|
||||
}
|
||||
|
||||
|
||||
static int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step_t *param, adc_atten_t atten)
|
||||
static int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step_t *param)
|
||||
{
|
||||
if (v_cali_1 == 0) {
|
||||
if (v_cali_1 == 0 || param->term_num == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -193,19 +193,23 @@ 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));
|
||||
|
||||
/**
|
||||
* The scheme formula is:
|
||||
* error = (K0 * X^0) + (K1 * X^1) + (K2 * X^2) + (K3 * X^3) + ... + (Kn * X^n);
|
||||
*/
|
||||
variable[0] = 1;
|
||||
coeff = (*param->coeff)[atten][0][0];
|
||||
term[0] = variable[0] * coeff / (*param->coeff)[atten][0][1];
|
||||
error = (int32_t)term[0] * (*param->sign)[atten][0];
|
||||
coeff = (param->coeff)[0][0];
|
||||
term[0] = variable[0] * coeff / (param->coeff)[0][1];
|
||||
error = (int32_t)term[0] * (param->sign)[0];
|
||||
|
||||
for (int i = 1; i < term_num; i++) {
|
||||
variable[i] = variable[i - 1] * v_cali_1;
|
||||
coeff = (*param->coeff)[atten][i][0];
|
||||
coeff = (param->coeff)[i][0];
|
||||
term[i] = variable[i] * coeff;
|
||||
ESP_LOGV(TAG, "big coef is %llu, big term%d is %llu, coef_id is %d", coeff, i, term[i], i);
|
||||
|
||||
term[i] = term[i] / (*param->coeff)[atten][i][1];
|
||||
error += (int32_t)term[i] * (*param->sign)[atten][i];
|
||||
term[i] = term[i] / (param->coeff)[i][1];
|
||||
error += (int32_t)term[i] * (param->sign)[i];
|
||||
ESP_LOGV(TAG, "term%d is %llu, error is %"PRId32, i, term[i], error);
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,10 @@
|
||||
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
|
||||
const uint64_t (*coeff)[2]; ///< Coeff of each term. See `adc_error_coef_atten` for details (and the magic number 2)
|
||||
const int32_t (*sign); ///< Sign of each term
|
||||
} cali_chars_second_step_t;
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,9 @@
|
||||
#include <stdint.h>
|
||||
#include "../curve_fitting_coefficients.h"
|
||||
|
||||
#define COEFF_GROUP_NUM 4
|
||||
#define TERM_MAX 5
|
||||
|
||||
/**
|
||||
* @note Error Calculation
|
||||
* Coefficients for calculating the reading voltage error.
|
||||
@ -41,6 +44,6 @@ void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *
|
||||
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;
|
||||
ctx->coeff = adc1_error_coef_atten[config->atten];
|
||||
ctx->sign = adc1_error_sign[config->atten];
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "../curve_fitting_coefficients.h"
|
||||
|
||||
#define COEFF_VERSION_NUM 2 // Currently C6 has two versions of curve calibration schemes
|
||||
#define COEFF_GROUP_NUM 4
|
||||
#define TERM_MAX 3
|
||||
|
||||
/**
|
||||
* @note Error Calculation
|
||||
@ -26,17 +28,17 @@
|
||||
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
|
||||
{{487166399931449, 1e15}, {6436483033201, 1e16}, {30410131806, 1e16}}, //atten0
|
||||
{{8665498165817785, 1e16}, {15239070452946, 1e16}, {13818878844, 1e16}}, //atten1
|
||||
{{12277821756674387, 1e16}, {22275554717885, 1e16}, {5924302667, 1e16}}, //atten2
|
||||
{{3801417550380255, 1e16}, {6020352420772, 1e16}, {12442478488, 1e16}}, //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
|
||||
{{0, 0}, {0, 0}, {0, 0}}, //atten0
|
||||
{{0, 0}, {0, 0}, {0, 0}}, //atten1
|
||||
{{12217864764388775, 1e16}, {1954123107752, 1e16}, {6409679727, 1e16}}, //atten2
|
||||
{{3915910437042445 , 1e16}, {31536470857564, 1e16}, {12493873014, 1e16}}, //atten3
|
||||
},
|
||||
};
|
||||
|
||||
@ -46,17 +48,17 @@ const static uint64_t adc1_error_coef_atten[COEFF_VERSION_NUM][COEFF_GROUP_NUM][
|
||||
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
|
||||
{-1, 1, 1}, //atten0
|
||||
{-1, 1, 1}, //atten1
|
||||
{-1, 1, 1}, //atten2
|
||||
{-1, -1, 1}, //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
|
||||
{ 0, 0, 0}, //atten0
|
||||
{ 0, 0, 0}, //atten1
|
||||
{-1, -1, 1}, //atten2
|
||||
{-1, -1, 1}, //atten3
|
||||
},
|
||||
};
|
||||
|
||||
@ -66,8 +68,13 @@ void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *
|
||||
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)];
|
||||
if (adc_calib_ver == ESP_EFUSE_ADC_CALIB_VER2 && config->atten < 2) {
|
||||
ctx->term_num = 0;
|
||||
ctx->coeff = NULL;
|
||||
ctx->sign = NULL;
|
||||
} else {
|
||||
ctx->term_num = 3;
|
||||
ctx->coeff = adc1_error_coef_atten[VER2IDX(adc_calib_ver)][config->atten];
|
||||
ctx->sign = adc1_error_sign[VER2IDX(adc_calib_ver)][config->atten];
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,12 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal/adc_types.h"
|
||||
#include "../curve_fitting_coefficients.h"
|
||||
|
||||
#define COEFF_GROUP_NUM 4
|
||||
#define TERM_MAX 5
|
||||
|
||||
/**
|
||||
* @note Error Calculation
|
||||
* Coefficients for calculating the reading voltage error.
|
||||
@ -50,6 +54,10 @@ const static 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)
|
||||
{
|
||||
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;
|
||||
ctx->coeff = config->unit_id == ADC_UNIT_1 ?
|
||||
adc1_error_coef_atten[config->atten] :
|
||||
adc2_error_coef_atten[config->atten];
|
||||
ctx->sign = config->unit_id == ADC_UNIT_1 ?
|
||||
adc1_error_sign[config->atten] :
|
||||
adc2_error_sign[config->atten];
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
@ -70,6 +70,7 @@ void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten)
|
||||
|
||||
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
|
||||
@ -103,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)
|
||||
|
Loading…
Reference in New Issue
Block a user