Browse Source

Merge branch 'fix/adc_hal_reading_efuse_in_critical' into 'master'

adc: fixed efuse called in critical section issue

See merge request espressif/esp-idf!11519
Michael (XIAO Xufeng) 5 năm trước cách đây
mục cha
commit
49022d4d92

+ 26 - 13
components/driver/adc_common.c

@@ -121,6 +121,16 @@ static esp_pm_lock_handle_t s_adc2_arbiter_lock;
                     ADC Common
 ---------------------------------------------------------------*/
 
+#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
+static uint32_t get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan)
+{
+    adc_atten_t atten = adc_hal_get_atten(adc_n, chan);
+
+    extern uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool no_cal);
+    return adc_get_calibration_offset(adc_n, chan, atten, false);
+}
+#endif
+
 void adc_power_acquire(void)
 {
     bool powered_on = false;
@@ -269,13 +279,6 @@ esp_err_t adc_rtc_reset(void)
     ADC_EXIT_CRITICAL();
     return ESP_OK;
 }
-
-static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel)
-{
-    adc_atten_t atten = adc_hal_get_atten(adc_n, channel);
-    uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false);
-    adc_hal_set_calibration_param(adc_n, cal_val);
-}
 #endif
 
 /*-------------------------------------------------------------------------------------
@@ -369,20 +372,25 @@ int adc1_get_raw(adc1_channel_t channel)
     adc1_rtc_mode_acquire();
     adc_power_acquire();
 
+#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
+    // Get calibration value before going into critical section
+    uint32_t cal_val = get_calibration_offset(ADC_NUM_1, channel);
+#endif
+
     ADC_ENTER_CRITICAL();
 #ifdef CONFIG_IDF_TARGET_ESP32
     adc_hal_hall_disable(); //Disable other peripherals.
     adc_hal_amp_disable();  //Currently the LNA is not open, close it by default.
 #endif
-#if !CONFIG_IDF_TARGET_ESP32
-    adc_set_init_code(ADC_NUM_1, channel);             // calibration for adc
+#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
+    adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
 #endif
     adc_hal_set_controller(ADC_NUM_1, ADC_CTRL_RTC);    //Set controller
     adc_hal_convert(ADC_NUM_1, channel, &adc_value);   //Start conversion, For ADC1, the data always valid.
-    ADC_EXIT_CRITICAL();
 #if !CONFIG_IDF_TARGET_ESP32
     adc_hal_rtc_reset();    //Reset FSM of rtc controller
 #endif
+    ADC_EXIT_CRITICAL();
 
     adc_power_release();
     adc1_lock_release();
@@ -520,6 +528,11 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
 
     adc_power_acquire();         //in critical section with whole rtc module
 
+#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
+    // Get calibration value before going into critical section
+    uint32_t cal_val = get_calibration_offset(ADC_NUM_2, channel);
+#endif
+
     ADC2_ENTER_CRITICAL();  //avoid collision with other tasks
 
     if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) { //try the lock, return if failed (wifi using).
@@ -532,7 +545,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
 #endif
     adc2_config_width(width_bit);   // in critical section with whole rtc module. because the PWDET use the same registers, place it here.
 #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3
-    adc_set_init_code(ADC_NUM_2, channel);  // calibration for adc
+    adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
 #endif
     adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);// set controller
 
@@ -557,12 +570,12 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
 #endif //CONFIG_PM_ENABLE
 #endif //CONFIG_IDF_TARGET_ESP32
 
-    ADC2_WIFI_LOCK_RELEASE();
-    ADC2_EXIT_CRITICAL();
 
 #if !CONFIG_IDF_TARGET_ESP32
     adc_rtc_reset();
 #endif
+    ADC2_WIFI_LOCK_RELEASE();
+    ADC2_EXIT_CRITICAL();
 
     if (adc_value < 0) {
         ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." );

+ 65 - 0
components/driver/esp32s2/adc.c

@@ -29,6 +29,7 @@
 #include "driver/rtc_cntl.h"
 #include "driver/gpio.h"
 #include "driver/adc.h"
+#include "esp32s2/esp_efuse_rtc_table.h"
 
 #include "hal/adc_types.h"
 #include "hal/adc_hal.h"
@@ -61,6 +62,8 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi
 static esp_pm_lock_handle_t s_adc_digi_arbiter_lock = NULL;
 #endif  //CONFIG_PM_ENABLE
 
+esp_err_t adc_cal_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten);
+
 /*---------------------------------------------------------------
                     Digital controller setting
 ---------------------------------------------------------------*/
@@ -106,6 +109,17 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
     }
 #endif //CONFIG_PM_ENABLE
 
+    if (config->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
+        for (int i = 0; i < config->adc1_pattern_len; i++) {
+            adc_cal_offset(ADC_NUM_1, config->adc1_pattern[i].channel, config->adc1_pattern[i].atten);
+        }
+    }
+    if (config->conv_mode & ADC_CONV_SINGLE_UNIT_2) {
+        for (int i = 0; i < config->adc2_pattern_len; i++) {
+            adc_cal_offset(ADC_NUM_2, config->adc2_pattern[i].channel, config->adc2_pattern[i].atten);
+        }
+    }
+
     ADC_ENTER_CRITICAL();
     adc_hal_digi_controller_config(config);
     ADC_EXIT_CRITICAL();
@@ -413,3 +427,54 @@ esp_err_t adc_digi_isr_deregister(void)
 /*---------------------------------------------------------------
                     RTC controller setting
 ---------------------------------------------------------------*/
+
+/*---------------------------------------------------------------
+                    Calibration
+---------------------------------------------------------------*/
+
+static uint16_t s_adc_cali_param[ADC_NUM_MAX][ADC_ATTEN_MAX] = { {0}, {0} };
+
+//NOTE: according to calibration version, different types of lock may be taken during the process:
+//  1. Semaphore when reading efuse
+//  2. Spinlock when actually doing ADC calibration
+//This function shoudn't be called inside critical section or ISR
+uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool no_cal)
+{
+#ifdef CONFIG_IDF_ENV_FPGA
+    return 0;
+#endif
+
+    if (s_adc_cali_param[adc_n][atten]) {
+        ESP_LOGV(ADC_TAG, "Use calibrated val ADC%d atten=%d: %04X", adc_n, atten, s_adc_cali_param[adc_n][atten]);
+        return (uint32_t)s_adc_cali_param[adc_n][atten];
+    }
+
+    if (no_cal) {
+        return 0;   //indicating failure
+    }
+
+    uint32_t dout = 0;
+    // check if we can fetch the values from eFuse.
+    int version = esp_efuse_rtc_table_read_calib_version();
+    if (version == 2) {
+        int tag = esp_efuse_rtc_table_get_tag(version, adc_n + 1, atten, RTCCALIB_V2_PARAM_VINIT);
+        dout = esp_efuse_rtc_table_get_parsed_efuse_value(tag, false);
+    } else {
+        const bool internal_gnd = true;
+        ADC_ENTER_CRITICAL();
+        dout = adc_hal_self_calibration(adc_n, channel, atten, internal_gnd);
+        ADC_EXIT_CRITICAL();
+    }
+    ESP_LOGD(ADC_TAG, "Calib(V%d) ADC%d atten=%d: %04X", version, adc_n, atten, dout);
+    s_adc_cali_param[adc_n][atten] = (uint16_t)dout;
+    return dout;
+}
+
+esp_err_t adc_cal_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
+{
+    uint32_t cal_val = adc_get_calibration_offset(adc_n, channel, atten, false);
+    ADC_ENTER_CRITICAL();
+    adc_hal_set_calibration_param(adc_n, cal_val);
+    ADC_EXIT_CRITICAL();
+    return ESP_OK;
+}

+ 5 - 1
components/driver/esp32s2/adc2_init_cal.c

@@ -25,7 +25,11 @@ Don't put any other code into this file. */
  */
 static __attribute__((constructor)) void adc2_init_code_calibration(void)
 {
-    adc_hal_set_calibration_param(ADC_NUM_2, adc_hal_calibration(ADC_NUM_2, 0, ADC_ATTEN_DB_11, true, false));
+    const adc_ll_num_t adc_n = ADC_NUM_2;
+    const adc_atten_t atten = ADC_ATTEN_DB_11;
+    const adc_channel_t channel = 0;
+    extern esp_err_t adc_cal_offset(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten);
+    adc_cal_offset(adc_n, channel, atten);
 }
 
 /** Don't call `adc2_cal_include` in user code. */

+ 16 - 37
components/hal/esp32c3/adc_hal.c

@@ -40,12 +40,6 @@ void adc_hal_digi_deinit(void)
     adc_hal_deinit();
 }
 
-static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
-{
-    uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false);
-    adc_hal_set_calibration_param(adc_n, cal_val);
-}
-
 void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
 {
     /* If enable digtal controller, adc xpd should always on. */
@@ -58,7 +52,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
             adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
             for (int i = 0; i < cfg->adc1_pattern_len; i++) {
                 adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
-                adc_set_init_code(ADC_NUM_1, cfg->adc1_pattern[i].channel, cfg->adc1_pattern[i].atten);
             }
         }
     }
@@ -68,7 +61,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
             adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
             for (int i = 0; i < cfg->adc2_pattern_len; i++) {
                 adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
-                adc_set_init_code(ADC_NUM_2, cfg->adc2_pattern[i].channel, cfg->adc2_pattern[i].atten);
             }
         }
     }
@@ -162,44 +154,27 @@ void adc_hal_arbiter_config(adc_arbiter_t *config)
 /*---------------------------------------------------------------
                     ADC calibration setting
 ---------------------------------------------------------------*/
-
-#define ADC_HAL_CAL_OFFSET_RANGE (4096)
 #define ADC_HAL_CAL_TIMES        (10)
+#define ADC_HAL_CAL_OFFSET_RANGE (4096)
 
-static uint16_t s_adc_cali_param[ADC_NUM_MAX][ADC_ATTEN_MAX] = { {0}, {0} };
-
-static uint32_t adc_hal_read_self_cal(adc_ll_num_t adc_n, int channel)
+static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
 {
     adc_ll_rtc_start_convert(adc_n, channel);
     while (adc_ll_rtc_convert_is_done(adc_n) != true);
     return (uint32_t)adc_ll_rtc_get_convert_value(adc_n);
 }
 
-uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal)
+uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
 {
-    if (!force_cal) {
-        if (s_adc_cali_param[adc_n][atten]) {
-            return (uint32_t)s_adc_cali_param[adc_n][atten];
-        }
-    }
-
-    uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
-    uint32_t code_sum = 0;
-    uint32_t code_h = 0;
-    uint32_t code_l = 0;
-    uint32_t chk_code = 0;
-    uint32_t dout = 0;
-
     adc_hal_set_power_manage(ADC_POWER_SW_ON);
+
     if (adc_n == ADC_NUM_2) {
         adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
         adc_hal_arbiter_config(&config);
     }
     adc_hal_set_controller(adc_n, ADC_CTRL_RTC);    //Set controller
 
-    // adc_hal_arbiter_config(adc_arbiter_t *config)
     adc_ll_calibration_prepare(adc_n, channel, internal_gnd);
-
     /* Enable/disable internal connect GND (for calibration). */
     if (internal_gnd) {
         adc_ll_rtc_disable_channel(adc_n, channel);
@@ -209,25 +184,31 @@ uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atte
         adc_ll_set_atten(adc_n, channel, atten);
     }
 
+    uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
+    uint32_t code_sum = 0;
+    uint32_t code_h = 0;
+    uint32_t code_l = 0;
+    uint32_t chk_code = 0;
+
     for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) {
         code_h = ADC_HAL_CAL_OFFSET_RANGE;
         code_l = 0;
         chk_code = (code_h + code_l) / 2;
         adc_ll_set_calibration_param(adc_n, chk_code);
-        dout = adc_hal_read_self_cal(adc_n, channel);
+        uint32_t self_cal = read_cal_channel(adc_n, channel);
         while (code_h - code_l > 1) {
-            if (dout == 0) {
+            if (self_cal == 0) {
                 code_h = chk_code;
             } else {
                 code_l = chk_code;
             }
             chk_code = (code_h + code_l) / 2;
             adc_ll_set_calibration_param(adc_n, chk_code);
-            dout = adc_hal_read_self_cal(adc_n, channel);
+            self_cal = read_cal_channel(adc_n, channel);
             if ((code_h - code_l == 1)) {
                 chk_code += 1;
                 adc_ll_set_calibration_param(adc_n, chk_code);
-                dout = adc_hal_read_self_cal(adc_n, channel);
+                self_cal = read_cal_channel(adc_n, channel);
             }
         }
         code_list[rpt] = chk_code;
@@ -244,12 +225,10 @@ uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atte
         }
     }
     chk_code = code_h + code_l;
-    dout = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
+    uint32_t ret = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
            ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2)
            : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
 
-    adc_ll_set_calibration_param(adc_n, dout);
     adc_ll_calibration_finish(adc_n);
-    s_adc_cali_param[adc_n][atten] = (uint16_t)dout;
-    return dout;
+    return ret;
 }

+ 3 - 4
components/hal/esp32c3/include/hal/adc_hal.h

@@ -232,21 +232,20 @@ void adc_hal_arbiter_config(adc_arbiter_t *config);
 ---------------------------------------------------------------*/
 
 /**
- * Calibrate the ADC according to the parameters.
+ * Calibrate the ADC using internal connections.
  *
  * @note  Different ADC units and different attenuation options use different calibration data (initial data).
  *
  * @param adc_n ADC index number.
  * @param channel adc channel number.
+ * @param atten The attenuation for the channel
  * @param internal_gnd true:  Disconnect from the IO port and use the internal GND as the calibration voltage.
  *                     false: Use IO external voltage as calibration voltage.
- * @param force_cal true:  Do not use the results that have already been verified, and perform the verification again. It will take a long time.
- *                  false: Use the result of the last calibration.
  *
  * @return
  *      - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
  */
-uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal);
+uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd);
 
 /**
  * Set the calibration result (initial data) to ADC.

+ 51 - 84
components/hal/esp32s2/adc_hal.c

@@ -19,7 +19,6 @@
 #include "hal/adc_types.h"
 #include "hal/adc_hal_conf.h"
 #include "esp_log.h"
-#include "esp32s2/esp_efuse_rtc_table.h"
 
 /*---------------------------------------------------------------
                     Digital controller setting
@@ -44,12 +43,6 @@ void adc_hal_digi_deinit(void)
     adc_hal_deinit();
 }
 
-static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
-{
-    uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false);
-    adc_hal_set_calibration_param(adc_n, cal_val);
-}
-
 void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
 {
     /* If enable digtal controller, adc xpd should always on. */
@@ -62,7 +55,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
             adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
             for (int i = 0; i < cfg->adc1_pattern_len; i++) {
                 adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
-                adc_set_init_code(ADC_NUM_1, cfg->adc1_pattern[i].channel, cfg->adc1_pattern[i].atten);
             }
         }
     }
@@ -72,7 +64,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
             adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
             for (int i = 0; i < cfg->adc2_pattern_len; i++) {
                 adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
-                adc_set_init_code(ADC_NUM_2, cfg->adc2_pattern[i].channel, cfg->adc2_pattern[i].atten);
             }
         }
     }
@@ -166,106 +157,82 @@ void adc_hal_arbiter_config(adc_arbiter_t *config)
 /*---------------------------------------------------------------
                     ADC calibration setting
 ---------------------------------------------------------------*/
-
-#define ADC_HAL_CAL_OFFSET_RANGE (4096)
 #define ADC_HAL_CAL_TIMES        (10)
+#define ADC_HAL_CAL_OFFSET_RANGE (4096)
 
-static uint16_t s_adc_cali_param[ADC_NUM_MAX][ADC_ATTEN_MAX] = { {0}, {0} };
-
-static uint32_t adc_hal_read_self_cal(adc_ll_num_t adc_n, int channel)
+static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
 {
     adc_ll_rtc_start_convert(adc_n, channel);
     while (adc_ll_rtc_convert_is_done(adc_n) != true);
     return (uint32_t)adc_ll_rtc_get_convert_value(adc_n);
 }
 
-uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal)
+uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
 {
-#ifdef CONFIG_IDF_ENV_FPGA
-    return 0;
-#endif
-
-    if (!force_cal) {
-        if (s_adc_cali_param[adc_n][atten]) {
-            return (uint32_t)s_adc_cali_param[adc_n][atten];
-        }
-    }
-
     adc_hal_set_power_manage(ADC_POWER_SW_ON);
+
     if (adc_n == ADC_NUM_2) {
         adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
         adc_hal_arbiter_config(&config);
     }
     adc_hal_set_controller(adc_n, ADC_CTRL_RTC);    //Set controller
 
-    // adc_hal_arbiter_config(adc_arbiter_t *config)
-    adc_ll_calibration_prepare(adc_n, channel, internal_gnd);
 
-    uint32_t dout = 0;
-    // check if we can fetch the values from eFuse.
-    int version = esp_efuse_rtc_table_read_calib_version();
-    if (version == 2) {
-        int tag = esp_efuse_rtc_table_get_tag(version, adc_n + 1, atten, RTCCALIB_V2_PARAM_VINIT);
-        dout = esp_efuse_rtc_table_get_parsed_efuse_value(tag, false);
+    adc_ll_calibration_prepare(adc_n, channel, internal_gnd);
+    /* Enable/disable internal connect GND (for calibration). */
+    if (internal_gnd) {
+        adc_ll_rtc_disable_channel(adc_n, channel);
+        adc_ll_set_atten(adc_n, 0, atten);  // Note: when disable all channel, HW auto select channel0 atten param.
     } else {
-        uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
-        uint32_t code_sum = 0;
-        uint32_t code_h = 0;
-        uint32_t code_l = 0;
-        uint32_t chk_code = 0;
-
-        /* Enable/disable internal connect GND (for calibration). */
-        if (internal_gnd) {
-            adc_ll_rtc_disable_channel(adc_n, channel);
-            adc_ll_set_atten(adc_n, 0, atten);  // Note: when disable all channel, HW auto select channel0 atten param.
-        } else {
-            adc_ll_rtc_enable_channel(adc_n, channel);
-            adc_ll_set_atten(adc_n, channel, atten);
-        }
+        adc_ll_rtc_enable_channel(adc_n, channel);
+        adc_ll_set_atten(adc_n, channel, atten);
+    }
 
-        for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) {
-            code_h = ADC_HAL_CAL_OFFSET_RANGE;
-            code_l = 0;
+    uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
+    uint32_t code_sum = 0;
+    uint32_t code_h = 0;
+    uint32_t code_l = 0;
+    uint32_t chk_code = 0;
+
+    for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) {
+        code_h = ADC_HAL_CAL_OFFSET_RANGE;
+        code_l = 0;
+        chk_code = (code_h + code_l) / 2;
+        adc_ll_set_calibration_param(adc_n, chk_code);
+        uint32_t self_cal = read_cal_channel(adc_n, channel);
+        while (code_h - code_l > 1) {
+            if (self_cal == 0) {
+                code_h = chk_code;
+            } else {
+                code_l = chk_code;
+            }
             chk_code = (code_h + code_l) / 2;
             adc_ll_set_calibration_param(adc_n, chk_code);
-            dout = adc_hal_read_self_cal(adc_n, channel);
-            while (code_h - code_l > 1) {
-                if (dout == 0) {
-                    code_h = chk_code;
-                } else {
-                    code_l = chk_code;
-                }
-                chk_code = (code_h + code_l) / 2;
+            self_cal = read_cal_channel(adc_n, channel);
+            if ((code_h - code_l == 1)) {
+                chk_code += 1;
                 adc_ll_set_calibration_param(adc_n, chk_code);
-                dout = adc_hal_read_self_cal(adc_n, channel);
-                if ((code_h - code_l == 1)) {
-                    chk_code += 1;
-                    adc_ll_set_calibration_param(adc_n, chk_code);
-                    dout = adc_hal_read_self_cal(adc_n, channel);
-                }
+                self_cal = read_cal_channel(adc_n, channel);
             }
-            code_list[rpt] = chk_code;
-            code_sum += chk_code;
         }
-        code_l = code_list[0];
-        code_h = code_list[0];
-        for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) {
-            if (code_l > code_list[i]) {
-                code_l = code_list[i];
-            }
-            if (code_h < code_list[i]) {
-                code_h = code_list[i];
-            }
+        code_list[rpt] = chk_code;
+        code_sum += chk_code;
+    }
+    code_l = code_list[0];
+    code_h = code_list[0];
+    for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) {
+        if (code_l > code_list[i]) {
+            code_l = code_list[i];
+        }
+        if (code_h < code_list[i]) {
+            code_h = code_list[i];
         }
-        chk_code = code_h + code_l;
-        dout = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
-               ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2)
-
-               : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
     }
-    adc_ll_set_calibration_param(adc_n, dout);
-    adc_ll_calibration_finish(adc_n);
-    s_adc_cali_param[adc_n][atten] = (uint16_t)dout;
+    chk_code = code_h + code_l;
+    uint32_t ret = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
+           ? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2)
+           : (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
 
-    return dout;
+    adc_ll_calibration_finish(adc_n);
+    return ret;
 }

+ 3 - 4
components/hal/esp32s2/include/hal/adc_hal.h

@@ -219,21 +219,20 @@ void adc_hal_arbiter_config(adc_arbiter_t *config);
 ---------------------------------------------------------------*/
 
 /**
- * Calibrate the ADC according to the parameters.
+ * Calibrate the ADC using internal connections.
  *
  * @note  Different ADC units and different attenuation options use different calibration data (initial data).
  *
  * @param adc_n ADC index number.
  * @param channel adc channel number.
+ * @param atten The attenuation for the channel
  * @param internal_gnd true:  Disconnect from the IO port and use the internal GND as the calibration voltage.
  *                     false: Use IO external voltage as calibration voltage.
- * @param force_cal true:  Do not use the results that have already been verified, and perform the verification again. It will take a long time(~40us).
- *                  false: Use the result of the last calibration. Return immediately.
  *
  * @return
  *      - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
  */
-uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal);
+uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd);
 
 /**
  * Set the calibration result (initial data) to ADC.

+ 3 - 4
components/hal/esp32s3/include/hal/adc_hal.h

@@ -232,21 +232,20 @@ void adc_hal_arbiter_config(adc_arbiter_t *config);
 ---------------------------------------------------------------*/
 
 /**
- * Calibrate the ADC according to the parameters.
+ * Calibrate the ADC using internal connections.
  *
  * @note  Different ADC units and different attenuation options use different calibration data (initial data).
  *
  * @param adc_n ADC index number.
  * @param channel adc channel number.
+ * @param atten The attenuation for the channel
  * @param internal_gnd true:  Disconnect from the IO port and use the internal GND as the calibration voltage.
  *                     false: Use IO external voltage as calibration voltage.
- * @param force_cal true:  Do not use the results that have already been verified, and perform the verification again. It will take a long time.
- *                  false: Use the result of the last calibration.
  *
  * @return
  *      - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
  */
-uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal);
+uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd);
 
 /**
  * Set the calibration result (initial data) to ADC.

+ 0 - 2
components/hal/esp32s3/include/hal/adc_ll.h

@@ -1053,8 +1053,6 @@ static inline void adc_ll_disable_sleep_controller(void)
 #define SAR2_DREF_ADDR_MSB  0x6
 #define SAR2_DREF_ADDR_LSB  0x4
 
-#define ADC_HAL_CAL_OFFSET_RANGE (4096)
-#define ADC_HAL_CAL_TIMES        (10)
 
 /**
  * Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration.