From 4a05274dc47c83bddfa57a42f266ea1debc99b38 Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 6 Jun 2023 14:14:45 +0800 Subject: [PATCH] adc: fixed the issue that multiply overflow before type expand --- components/esp_adc/adc_cali_curve_fitting.c | 11 ++--------- .../esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c | 2 +- .../esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/components/esp_adc/adc_cali_curve_fitting.c b/components/esp_adc/adc_cali_curve_fitting.c index 6360d610bc..4347448175 100644 --- a/components/esp_adc/adc_cali_curve_fitting.c +++ b/components/esp_adc/adc_cali_curve_fitting.c @@ -22,12 +22,10 @@ const __attribute__((unused)) static char *TAG = "adc_cali"; - // coeff_a is actually a float number // it is scaled to put them into uint32_t so that the headers do not have to be changed static const int coeff_a_scaling = 65536; - /* -------------------- Characterization Helper Data Types ------------------ */ typedef struct { uint32_t voltage; @@ -43,7 +41,6 @@ typedef struct { } ref_data; } adc_calib_info_t; - /* ------------------------ Context Structure--------------------------- */ typedef struct { uint32_t coeff_a; ///< Gradient of ADC-Voltage curve @@ -63,7 +60,6 @@ typedef struct { cali_chars_second_step_t chars_second_step; ///< Calibration second step characteristics } cali_chars_curve_fitting_t; - /* ----------------------- 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); @@ -71,7 +67,6 @@ static void calc_second_step_coefficients(const adc_cali_curve_fitting_config_t 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); - /* ------------------------ Interface Functions --------------------------- */ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage); @@ -131,14 +126,13 @@ esp_err_t adc_cali_delete_scheme_curve_fitting(adc_cali_handle_t handle) return ESP_OK; } - /* ------------------------ Interface Functions --------------------------- */ 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; - uint64_t v_cali_1 = raw * ctx->chars_first_step.coeff_a / coeff_a_scaling + ctx->chars_first_step.coeff_b; + 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); *voltage = (int32_t)v_cali_1 - error; @@ -146,7 +140,6 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) return ESP_OK; } - /* ----------------------- Characterization Functions ----------------------- */ //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) @@ -217,7 +210,7 @@ static int32_t get_reading_error(uint64_t v_cali_1, const cali_chars_second_step error = (int32_t)term[0] * (*param->sign)[atten][0]; for (int i = 1; i < term_num; i++) { - variable[i] = variable[i-1] * v_cali_1; + variable[i] = variable[i - 1] * v_cali_1; coeff = (*param->coeff)[atten][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); diff --git a/components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c index e35e00dfbc..1755344799 100644 --- a/components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c +++ b/components/esp_adc/deprecated/esp32c3/esp_adc_cal_legacy.c @@ -163,7 +163,7 @@ uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_char assert(chars != NULL); int32_t error = 0; - uint64_t v_cali_1 = adc_reading * chars->coeff_a / coeff_a_scaling; + uint64_t v_cali_1 = (uint64_t)adc_reading * chars->coeff_a / coeff_a_scaling; esp_adc_error_calc_param_t param = { .v_cali_input = v_cali_1, .term_num = (chars->atten == 3) ? 5 : 3, diff --git a/components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c b/components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c index 1f98689ec3..53122d8507 100644 --- a/components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c +++ b/components/esp_adc/deprecated/esp32s3/esp_adc_cal_legacy.c @@ -167,7 +167,7 @@ uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc_reading, const esp_adc_cal_char uint64_t v_cali_1 = 0; //raw * gradient * 1000000 - v_cali_1 = adc_reading * chars->coeff_a; + v_cali_1 = (uint64_t)adc_reading * chars->coeff_a; //convert to real number v_cali_1 = v_cali_1 / coeff_a_scaling; ESP_LOGV(LOG_TAG, "v_cali_1 is %llu", v_cali_1);