mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-10-30 20:51:41 +00:00 
			
		
		
		
	adc_cali: supported channel compensation of adc calibration on esp32c6
This commit is contained in:
		| @@ -605,6 +605,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void) | |||||||
|              * update this when bringing up the calibration on that chip |              * update this when bringing up the calibration on that chip | ||||||
|              */ |              */ | ||||||
|             adc_calc_hw_calibration_code(i, j); |             adc_calc_hw_calibration_code(i, j); | ||||||
|  | #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
|  |             /* Load the channel compensation from efuse */ | ||||||
|  |             for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { | ||||||
|  |                 adc_load_hw_calibration_chan_compens(i, k, j); | ||||||
|  |             } | ||||||
|  | #endif | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -947,6 +947,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void) | |||||||
|              * update this when bringing up the calibration on that chip |              * update this when bringing up the calibration on that chip | ||||||
|              */ |              */ | ||||||
|             adc_calc_hw_calibration_code(i, j); |             adc_calc_hw_calibration_code(i, j); | ||||||
|  | #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
|  |             /* Load the channel compensation from efuse */ | ||||||
|  |             for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { | ||||||
|  |                 adc_load_hw_calibration_chan_compens(i, k, j); | ||||||
|  |             } | ||||||
|  | #endif | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -53,11 +53,11 @@ | |||||||
| #define ADC_TEST_HIGH_VAL        3400 | #define ADC_TEST_HIGH_VAL        3400 | ||||||
| #define ADC_TEST_HIGH_THRESH     200 | #define ADC_TEST_HIGH_THRESH     200 | ||||||
|  |  | ||||||
| #elif CONFIG_IDF_TARGET_ESP32C6  // TODO: IDF-5312 | #elif CONFIG_IDF_TARGET_ESP32C6 | ||||||
| #define ADC_TEST_LOW_VAL         2144 | #define ADC_TEST_LOW_VAL         0 | ||||||
| #define ADC_TEST_LOW_THRESH      200 | #define ADC_TEST_LOW_THRESH      15 | ||||||
|  |  | ||||||
| #define ADC_TEST_HIGH_VAL        4081 | #define ADC_TEST_HIGH_VAL        3350 | ||||||
| #define ADC_TEST_HIGH_THRESH     200 | #define ADC_TEST_HIGH_THRESH     200 | ||||||
|  |  | ||||||
| #elif CONFIG_IDF_TARGET_ESP32H2  // TODO: IDF-6216 | #elif CONFIG_IDF_TARGET_ESP32H2  // TODO: IDF-6216 | ||||||
|   | |||||||
| @@ -8,26 +8,36 @@ | |||||||
| #include "esp_efuse.h" | #include "esp_efuse.h" | ||||||
| #include "esp_efuse_table.h" | #include "esp_efuse_table.h" | ||||||
| #include "esp_efuse_rtc_calib.h" | #include "esp_efuse_rtc_calib.h" | ||||||
|  | #include "hal/efuse_hal.h" | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Get the signed value by the raw data that read from eFuse | ||||||
|  |  * @param data  The raw data that read from eFuse | ||||||
|  |  * @param sign_bit  The index of the sign bit, start from 0 | ||||||
|  |  */ | ||||||
|  | #define RTC_CALIB_GET_SIGNED_VAL(data, sign_bit)    ((data & BIT##sign_bit) ? -(int)(data & ~BIT##sign_bit) : (int)data) | ||||||
|  |  | ||||||
| int esp_efuse_rtc_calib_get_ver(void) | int esp_efuse_rtc_calib_get_ver(void) | ||||||
| { | { | ||||||
|     uint32_t blk_ver_minor = 0; |     uint32_t blk_ver = efuse_hal_blk_version(); | ||||||
|     esp_efuse_read_field_blob(ESP_EFUSE_BLK_VERSION_MINOR, &blk_ver_minor, ESP_EFUSE_BLK_VERSION_MINOR[0]->bit_count); |  | ||||||
|  |  | ||||||
|     uint32_t cali_version = (blk_ver_minor == 1) ? ESP_EFUSE_ADC_CALIB_VER : 0; |     uint32_t cali_version = 0; | ||||||
|     if (!cali_version) { |     if (blk_ver > 0) { | ||||||
|  |         cali_version = ESP_EFUSE_ADC_CALIB_VER; | ||||||
|  |     } else { | ||||||
|         ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0"); |         ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return blk_ver_minor; |     return cali_version; | ||||||
| } | } | ||||||
|  |  | ||||||
| uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten) | 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); | ||||||
|  |     assert(atten >=0 && atten < 4); | ||||||
|     (void) adc_unit; |     (void) adc_unit; | ||||||
|  |  | ||||||
|     const esp_efuse_desc_t** init_code_efuse; |     const esp_efuse_desc_t** init_code_efuse; | ||||||
|     assert(atten < 4); |  | ||||||
|     if (atten == 0) { |     if (atten == 0) { | ||||||
|         init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0; |         init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0; | ||||||
|     } else if (atten == 1) { |     } else if (atten == 1) { | ||||||
| @@ -43,7 +53,45 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a | |||||||
|  |  | ||||||
|     uint32_t init_code = 0; |     uint32_t init_code = 0; | ||||||
|     ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size)); |     ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size)); | ||||||
|     return init_code + 1000;    // version 1 logic |     return init_code + 1600;    // version 1 logic | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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(atten < 4); | ||||||
|  |     assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit)); | ||||||
|  |  | ||||||
|  |     const esp_efuse_desc_t** chan_diff_efuse = NULL; | ||||||
|  |     switch (adc_channel) { | ||||||
|  |         case 0: | ||||||
|  |             chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH0; | ||||||
|  |             break; | ||||||
|  |         case 1: | ||||||
|  |             chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1; | ||||||
|  |             break; | ||||||
|  |         case 2: | ||||||
|  |             chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2; | ||||||
|  |             break; | ||||||
|  |         case 3: | ||||||
|  |             chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3; | ||||||
|  |             break; | ||||||
|  |         case 4: | ||||||
|  |             chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4; | ||||||
|  |             break; | ||||||
|  |         case 5: | ||||||
|  |             chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6; | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     int chan_diff_size = esp_efuse_get_field_size(chan_diff_efuse); | ||||||
|  |     assert(chan_diff_size == 4); | ||||||
|  |     uint32_t chan_diff = 0; | ||||||
|  |     ESP_ERROR_CHECK(esp_efuse_read_field_blob(chan_diff_efuse, &chan_diff, chan_diff_size)); | ||||||
|  |     return RTC_CALIB_GET_SIGNED_VAL(chan_diff, 3) * (4 - atten); | ||||||
| } | } | ||||||
|  |  | ||||||
| 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) | 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) | ||||||
| @@ -75,7 +123,7 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in | |||||||
|     uint32_t cal_vol = 0; |     uint32_t cal_vol = 0; | ||||||
|     ESP_ERROR_CHECK(esp_efuse_read_field_blob(cal_vol_efuse, &cal_vol, cal_vol_efuse[0]->bit_count)); |     ESP_ERROR_CHECK(esp_efuse_read_field_blob(cal_vol_efuse, &cal_vol, cal_vol_efuse[0]->bit_count)); | ||||||
|  |  | ||||||
|     *out_digi = 2000 + ((cal_vol & BIT(9))? -(cal_vol & ~BIT9): cal_vol); |     *out_digi = 1500 + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9); | ||||||
|     *out_vol_mv = calib_vol_expected_mv; |     *out_vol_mv = calib_vol_expected_mv; | ||||||
|     return ESP_OK; |     return ESP_OK; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,6 +31,17 @@ 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); | uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Get the channel specific calibration compensation | ||||||
|  |  * | ||||||
|  |  * @param version   Version of the stored efuse | ||||||
|  |  * @param adc_unit  ADC unit. Not used, for compatibility. On esp32c6, for calibration v1, both ADC units use the same init code (calibrated by ADC1) | ||||||
|  |  * @param adc_channel ADC channel number | ||||||
|  |  * @param atten     Attenuation of the init code | ||||||
|  |  * @return The channel calibration compensation value | ||||||
|  |  */ | ||||||
|  | int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief Get the calibration digits stored in the efuse, and the corresponding voltage. |  * @brief Get the calibration digits stored in the efuse, and the corresponding voltage. | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
| #include "esp_adc/adc_cali_scheme.h" | #include "esp_adc/adc_cali_scheme.h" | ||||||
| #include "adc_cali_interface.h" | #include "adc_cali_interface.h" | ||||||
| #include "curve_fitting_coefficients.h" | #include "curve_fitting_coefficients.h" | ||||||
|  | #include "esp_private/adc_share_hw_ctrl.h" | ||||||
|  |  | ||||||
| #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED | #if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED | ||||||
| #include "esp_efuse_rtc_calib.h" | #include "esp_efuse_rtc_calib.h" | ||||||
| @@ -55,6 +56,7 @@ typedef struct { | |||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     adc_unit_t unit_id;                            ///< ADC unit |     adc_unit_t unit_id;                            ///< ADC unit | ||||||
|  |     adc_channel_t chan;                            ///< ADC channel | ||||||
|     adc_atten_t atten;                             ///< ADC attenuation |     adc_atten_t atten;                             ///< ADC attenuation | ||||||
|     cali_chars_first_step_t chars_first_step;      ///< Calibration first step characteristics |     cali_chars_first_step_t chars_first_step;      ///< Calibration first step characteristics | ||||||
|     cali_chars_second_step_t chars_second_step;    ///< Calibration second step characteristics |     cali_chars_second_step_t chars_second_step;    ///< Calibration second step characteristics | ||||||
| @@ -100,6 +102,7 @@ esp_err_t adc_cali_create_scheme_curve_fitting(const adc_cali_curve_fitting_conf | |||||||
|     //Set second step calibration context |     //Set second step calibration context | ||||||
|     calc_second_step_coefficients(config, chars); |     calc_second_step_coefficients(config, chars); | ||||||
|     chars->unit_id = config->unit_id; |     chars->unit_id = config->unit_id; | ||||||
|  |     chars->chan = config->chan; | ||||||
|     chars->atten = config->atten; |     chars->atten = config->atten; | ||||||
|  |  | ||||||
|     *ret_handle = scheme; |     *ret_handle = scheme; | ||||||
| @@ -132,6 +135,16 @@ static esp_err_t cali_raw_to_voltage(void *arg, int raw, int *voltage) | |||||||
|     //pointers are checked in the upper layer |     //pointers are checked in the upper layer | ||||||
|  |  | ||||||
|     cali_chars_curve_fitting_t *ctx = arg; |     cali_chars_curve_fitting_t *ctx = arg; | ||||||
|  |  | ||||||
|  | #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
|  |     int chan_compensation = adc_get_hw_calibration_chan_compens(ctx->unit_id, ctx->chan, ctx->atten); | ||||||
|  |     raw -= chan_compensation; | ||||||
|  |     /* Limit the range */ | ||||||
|  |     int max_val = (1L << SOC_ADC_RTC_MAX_BITWIDTH) - 1; | ||||||
|  |     raw = raw <= 0 ? 0 : | ||||||
|  |           raw > max_val ? max_val : raw; | ||||||
|  | #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; |     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), ctx->atten); | ||||||
|  |  | ||||||
| @@ -173,8 +186,9 @@ static void calc_first_step_coefficients(const adc_calib_info_t *parsed_data, ca | |||||||
| static void calc_second_step_coefficients(const adc_cali_curve_fitting_config_t *config, cali_chars_curve_fitting_t *ctx) | 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; |     ctx->chars_second_step.term_num = (config->atten == 3) ? 5 : 3; | ||||||
| #if CONFIG_IDF_TARGET_ESP32C3 | #if CONFIG_IDF_TARGET_ESP32C3 || SOC_ADC_PERIPH_NUM == 1 | ||||||
|     // On esp32c3, ADC1 and ADC2 share the second step coefficients |     // 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.coeff = &adc1_error_coef_atten; | ||||||
|     ctx->chars_second_step.sign = &adc1_error_sign; |     ctx->chars_second_step.sign = &adc1_error_sign; | ||||||
| #else | #else | ||||||
|   | |||||||
| @@ -102,6 +102,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void) | |||||||
|              * update this when bringing up the calibration on that chip |              * update this when bringing up the calibration on that chip | ||||||
|              */ |              */ | ||||||
|             adc_calc_hw_calibration_code(i, j); |             adc_calc_hw_calibration_code(i, j); | ||||||
|  | #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
|  |             /* Load the channel compensation from efuse */ | ||||||
|  |             for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) { | ||||||
|  |                 adc_load_hw_calibration_chan_compens(i, k, j); | ||||||
|  |             } | ||||||
|  | #endif | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -173,7 +173,7 @@ esp_err_t adc_oneshot_read(adc_oneshot_unit_handle_t handle, adc_channel_t chan, | |||||||
|     adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); |     adc_atten_t atten = adc_ll_get_atten(handle->unit_id, chan); | ||||||
|     adc_hal_calibration_init(handle->unit_id); |     adc_hal_calibration_init(handle->unit_id); | ||||||
|     adc_set_hw_calibration_code(handle->unit_id, atten); |     adc_set_hw_calibration_code(handle->unit_id, atten); | ||||||
| #endif | #endif  // SOC_ADC_CALIBRATION_V1_SUPPORTED | ||||||
|     bool valid = false; |     bool valid = false; | ||||||
|     valid = adc_oneshot_hal_convert(&(handle->hal), out_raw); |     valid = adc_oneshot_hal_convert(&(handle->hal), out_raw); | ||||||
|     sar_periph_ctrl_adc_oneshot_power_release(); |     sar_periph_ctrl_adc_oneshot_power_release(); | ||||||
|   | |||||||
| @@ -14,10 +14,9 @@ | |||||||
|  * For each item, first element is the Coefficient, second element is the Multiple. (Coefficient / Multiple) is the real coefficient. |  * 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 {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 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 Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered. | ||||||
|  * @note ADC1 and ADC2 use same coeffients |  | ||||||
|  */ |  */ | ||||||
| const uint64_t adc1_error_coef_atten[4][5][2] = { | const uint64_t adc1_error_coef_atten[4][5][2] = { | ||||||
|                                                 {{487166399931449,   1e16}, {6436483033201,   1e16}, {30410131806, 1e16}, {0, 0}, {0, 0}},   //atten0 |                                                 {{487166399931449,   1e16}, {6436483033201,   1e16}, {30410131806, 1e16}, {0, 0}, {0, 0}},   //atten0 | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ extern "C" { | |||||||
| ---------------------------------------------------------------*/ | ---------------------------------------------------------------*/ | ||||||
| typedef struct { | typedef struct { | ||||||
|     adc_unit_t unit_id;         ///< ADC unit |     adc_unit_t unit_id;         ///< ADC unit | ||||||
|  |     adc_channel_t chan;         ///< ADC channel, for chips with SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED, calibration can be per channel | ||||||
|     adc_atten_t atten;          ///< ADC attenuation |     adc_atten_t atten;          ///< ADC attenuation | ||||||
|     adc_bitwidth_t bitwidth;    ///< ADC raw output bitwidth |     adc_bitwidth_t bitwidth;    ///< ADC raw output bitwidth | ||||||
| } adc_cali_curve_fitting_config_t; | } adc_cali_curve_fitting_config_t; | ||||||
|   | |||||||
| @@ -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 |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  */ |  */ | ||||||
| @@ -149,7 +149,7 @@ static void s_adc_oneshot_with_sleep(adc_unit_t unit_id, adc_channel_t channel) | |||||||
|     bool do_calibration = false; |     bool do_calibration = false; | ||||||
|     adc_cali_handle_t cali_handle[TEST_ATTEN_NUMS] = {}; |     adc_cali_handle_t cali_handle[TEST_ATTEN_NUMS] = {}; | ||||||
|     for (int i = 0; i < TEST_ATTEN_NUMS; i++) { |     for (int i = 0; i < TEST_ATTEN_NUMS; i++) { | ||||||
|         do_calibration = test_adc_calibration_init(unit_id, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); |         do_calibration = test_adc_calibration_init(unit_id, channel, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); | ||||||
|     } |     } | ||||||
|     if (!do_calibration) { |     if (!do_calibration) { | ||||||
|         ESP_LOGW(TAG, "No efuse bits burnt, only test the regi2c analog register values"); |         ESP_LOGW(TAG, "No efuse bits burnt, only test the regi2c analog register values"); | ||||||
|   | |||||||
| @@ -324,7 +324,7 @@ static float test_adc_oneshot_std(adc_atten_t atten, bool is_performance_test) | |||||||
|     //-------------ADC Calibration Init---------------// |     //-------------ADC Calibration Init---------------// | ||||||
|     bool do_calibration = false; |     bool do_calibration = false; | ||||||
|     adc_cali_handle_t cali_handle = NULL; |     adc_cali_handle_t cali_handle = NULL; | ||||||
|     do_calibration = test_adc_calibration_init(ADC_UNIT_1, atten, ADC_BITWIDTH_DEFAULT, &cali_handle); |     do_calibration = test_adc_calibration_init(ADC_UNIT_1, channel, atten, ADC_BITWIDTH_DEFAULT, &cali_handle); | ||||||
|     if (!do_calibration) { |     if (!do_calibration) { | ||||||
|         ESP_LOGW(TAG, "calibration fail, jump calibration\n"); |         ESP_LOGW(TAG, "calibration fail, jump calibration\n"); | ||||||
|     } |     } | ||||||
| @@ -420,7 +420,7 @@ static void s_adc_cali_speed(adc_unit_t unit_id, adc_channel_t channel) | |||||||
|     bool do_calibration = false; |     bool do_calibration = false; | ||||||
|     adc_cali_handle_t cali_handle[TEST_ATTEN_NUMS] = {}; |     adc_cali_handle_t cali_handle[TEST_ATTEN_NUMS] = {}; | ||||||
|     for (int i = 0; i < TEST_ATTEN_NUMS; i++) { |     for (int i = 0; i < TEST_ATTEN_NUMS; i++) { | ||||||
|         do_calibration = test_adc_calibration_init(unit_id, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); |         do_calibration = test_adc_calibration_init(unit_id, channel, g_test_atten[i], SOC_ADC_RTC_MAX_BITWIDTH, &cali_handle[i]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (!do_calibration) { |     if (!do_calibration) { | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ adc_digi_iir_filter_coeff_t g_test_filter_coeff[TEST_FILTER_COEFF_NUMS] = { | |||||||
| /*--------------------------------------------------------------- | /*--------------------------------------------------------------- | ||||||
|         ADC Calibration |         ADC Calibration | ||||||
| ---------------------------------------------------------------*/ | ---------------------------------------------------------------*/ | ||||||
| bool test_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle) | bool test_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle) | ||||||
| { | { | ||||||
|     esp_err_t ret = ESP_FAIL; |     esp_err_t ret = ESP_FAIL; | ||||||
|     adc_cali_handle_t handle = NULL; |     adc_cali_handle_t handle = NULL; | ||||||
| @@ -49,6 +49,7 @@ bool test_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_bitwidth_ | |||||||
|     ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); |     ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); | ||||||
|     adc_cali_curve_fitting_config_t cali_config = { |     adc_cali_curve_fitting_config_t cali_config = { | ||||||
|         .unit_id = unit, |         .unit_id = unit, | ||||||
|  |         .chan = channel, | ||||||
|         .atten = atten, |         .atten = atten, | ||||||
|         .bitwidth = bitwidth, |         .bitwidth = bitwidth, | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -71,11 +71,11 @@ extern "C" { | |||||||
| #define ADC_TEST_HIGH_VAL        3400 | #define ADC_TEST_HIGH_VAL        3400 | ||||||
| #define ADC_TEST_HIGH_THRESH     200 | #define ADC_TEST_HIGH_THRESH     200 | ||||||
|  |  | ||||||
| #elif CONFIG_IDF_TARGET_ESP32C6  // TODO: IDF-5312 | #elif CONFIG_IDF_TARGET_ESP32C6 | ||||||
| #define ADC_TEST_LOW_VAL         2144 | #define ADC_TEST_LOW_VAL         0 | ||||||
| #define ADC_TEST_LOW_THRESH      200 | #define ADC_TEST_LOW_THRESH      15 | ||||||
|  |  | ||||||
| #define ADC_TEST_HIGH_VAL        4081 | #define ADC_TEST_HIGH_VAL        3350 | ||||||
| #define ADC_TEST_HIGH_VAL_DMA    4081 | #define ADC_TEST_HIGH_VAL_DMA    4081 | ||||||
| #define ADC_TEST_HIGH_THRESH     200 | #define ADC_TEST_HIGH_THRESH     200 | ||||||
|  |  | ||||||
| @@ -114,13 +114,17 @@ extern adc_digi_iir_filter_coeff_t g_test_filter_coeff[TEST_FILTER_COEFF_NUMS]; | |||||||
| /** | /** | ||||||
|  * @brief Initialise ADC Calibration |  * @brief Initialise ADC Calibration | ||||||
|  * |  * | ||||||
|  |  * @param[in]  unit         ADC unit | ||||||
|  |  * @param[in]  channel      ADC channel | ||||||
|  |  * @param[in]  atten        ADC attenuation | ||||||
|  |  * @param[in]  bitwidth     ADC bit width | ||||||
|  * @param[out] out_handle   ADC calibration handle |  * @param[out] out_handle   ADC calibration handle | ||||||
|  * |  * | ||||||
|  * @return |  * @return | ||||||
|  *        - True  Calibration success |  *        - True  Calibration success | ||||||
|  *        - False Calibration fail |  *        - False Calibration fail | ||||||
|  */ |  */ | ||||||
| bool test_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle); | bool test_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_bitwidth_t bitwidth, adc_cali_handle_t *out_handle); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief De-initialise ADC Calibration |  * @brief De-initialise ADC Calibration | ||||||
|   | |||||||
| @@ -96,6 +96,20 @@ void IRAM_ATTR adc_set_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten) | |||||||
| { | { | ||||||
|     adc_hal_set_calibration_param(adc_n, s_adc_cali_param[adc_n][atten]); |     adc_hal_set_calibration_param(adc_n, s_adc_cali_param[adc_n][atten]); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
|  | 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); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int IRAM_ATTR adc_get_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten) | ||||||
|  | { | ||||||
|  |     return s_adc_cali_chan_compens[chan][atten]; | ||||||
|  | } | ||||||
|  | #endif  // SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
| #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED | #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -45,6 +45,28 @@ void adc_calc_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten); | |||||||
|  * @param atten Attenuation to use |  * @param atten Attenuation to use | ||||||
|  */ |  */ | ||||||
| void adc_set_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten); | void adc_set_hw_calibration_code(adc_unit_t adc_n, adc_atten_t atten); | ||||||
|  |  | ||||||
|  | #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
|  | /** | ||||||
|  |  * @brief Load the channel compensation of the ADC HW calibration from eFuse to a static array | ||||||
|  |  * | ||||||
|  |  * @param adc_n ADC unit to compensation | ||||||
|  |  * @param chan  ADC channel to compensation | ||||||
|  |  * @param atten Attenuation to use | ||||||
|  |  */ | ||||||
|  | void adc_load_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Get the channel compensation of the ADC HW calibration from the static array | ||||||
|  |  *        that have been loaded from eFuse | ||||||
|  |  * | ||||||
|  |  * @param adc_n ADC unit to compensation | ||||||
|  |  * @param chan  ADC channel to compensation | ||||||
|  |  * @param atten Attenuation to use | ||||||
|  |  * @return The channel compensation | ||||||
|  |  */ | ||||||
|  | int adc_get_hw_calibration_chan_compens(adc_unit_t adc_n, adc_channel_t chan, adc_atten_t atten); | ||||||
|  | #endif  // SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
| #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED | #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ set(srcs "rtc_clk_init.c" | |||||||
|          "pmu_sleep.c" |          "pmu_sleep.c" | ||||||
|          "rtc_time.c" |          "rtc_time.c" | ||||||
|          "chip_info.c" |          "chip_info.c" | ||||||
|  |          "ocode_init.c" | ||||||
|          ) |          ) | ||||||
|  |  | ||||||
| if(NOT BOOTLOADER_BUILD) | if(NOT BOOTLOADER_BUILD) | ||||||
|   | |||||||
							
								
								
									
										98
									
								
								components/esp_hw_support/port/esp32c6/ocode_init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								components/esp_hw_support/port/esp32c6/ocode_init.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <stdint.h> | ||||||
|  | #include "soc/soc.h" | ||||||
|  | #include "soc/rtc.h" | ||||||
|  | #include "soc/regi2c_dig_reg.h" | ||||||
|  | #include "soc/regi2c_lp_bias.h" | ||||||
|  | #include "hal/efuse_hal.h" | ||||||
|  | #include "hal/efuse_ll.h" | ||||||
|  | #include "regi2c_ctrl.h" | ||||||
|  | #include "esp_hw_log.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static const char *TAG = "ocode_init"; | ||||||
|  |  | ||||||
|  | static void set_ocode_by_efuse(int ocode_scheme_ver) | ||||||
|  | { | ||||||
|  |     assert(ocode_scheme_ver == 1); | ||||||
|  |     unsigned int ocode = efuse_ll_get_ocode(); | ||||||
|  |  | ||||||
|  |     //set ext_ocode | ||||||
|  |     REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_EXT_CODE, ocode); | ||||||
|  |     REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_CODE, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void calibrate_ocode(void) | ||||||
|  | { | ||||||
|  |     /* | ||||||
|  |     Bandgap output voltage is not precise when calibrate o-code by hardware sometimes, so need software o-code calibration (must turn off PLL). | ||||||
|  |     Method: | ||||||
|  |     1. read current cpu config, save in old_config; | ||||||
|  |     2. switch cpu to xtal because PLL will be closed when o-code calibration; | ||||||
|  |     3. begin o-code calibration; | ||||||
|  |     4. wait o-code calibration done flag(odone_flag & bg_odone_flag) or timeout; | ||||||
|  |     5. set cpu to old-config. | ||||||
|  |     */ | ||||||
|  |     soc_rtc_slow_clk_src_t slow_clk_src = rtc_clk_slow_src_get(); | ||||||
|  |     rtc_cal_sel_t cal_clk = RTC_CAL_RTC_MUX; | ||||||
|  |     if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { | ||||||
|  |         cal_clk = RTC_CAL_32K_OSC_SLOW; | ||||||
|  |     } else if (slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { | ||||||
|  |         cal_clk  = RTC_CAL_32K_XTAL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     uint64_t max_delay_time_us = 10000; | ||||||
|  |     uint32_t slow_clk_period = rtc_clk_cal(cal_clk, 100); | ||||||
|  |     uint64_t max_delay_cycle = rtc_time_us_to_slowclk(max_delay_time_us, slow_clk_period); | ||||||
|  |     uint64_t cycle0 = rtc_time_get(); | ||||||
|  |     uint64_t timeout_cycle = cycle0 + max_delay_cycle; | ||||||
|  |     uint64_t cycle1 = 0; | ||||||
|  |  | ||||||
|  |     rtc_cpu_freq_config_t old_config; | ||||||
|  |     rtc_clk_cpu_freq_get_config(&old_config); | ||||||
|  |     rtc_clk_cpu_freq_set_xtal(); | ||||||
|  |  | ||||||
|  |     REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 0); | ||||||
|  |     REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_RESETB, 1); | ||||||
|  |     bool odone_flag = 0; | ||||||
|  |     bool bg_odone_flag = 0; | ||||||
|  |     while (1) { | ||||||
|  |         odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_O_DONE_FLAG); | ||||||
|  |         bg_odone_flag = REGI2C_READ_MASK(I2C_ULP, I2C_ULP_BG_O_DONE_FLAG); | ||||||
|  |         cycle1 = rtc_time_get(); | ||||||
|  |         if (odone_flag && bg_odone_flag) { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         if (cycle1 >= timeout_cycle) { | ||||||
|  |             ESP_HW_LOGW(TAG, "o_code calibration fail\n"); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     rtc_clk_cpu_freq_set_config(&old_config); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void esp_ocode_calib_init(void) | ||||||
|  | { | ||||||
|  |     bool ignore_major = efuse_ll_get_disable_blk_version_major(); | ||||||
|  |     uint32_t blk_version = efuse_hal_blk_version(); | ||||||
|  |  | ||||||
|  |     uint8_t ocode_scheme_ver = 0; | ||||||
|  |     if(blk_version == 0 && !ignore_major) { | ||||||
|  |         ESP_HW_LOGE(TAG, "Invalid blk_version\n"); | ||||||
|  |         abort(); | ||||||
|  |     } | ||||||
|  |     if(blk_version > 0) { | ||||||
|  |         ocode_scheme_ver = 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (ocode_scheme_ver == 1) { | ||||||
|  |         set_ocode_by_efuse(ocode_scheme_ver); | ||||||
|  |     } else { | ||||||
|  |         calibrate_ocode(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | /* | ||||||
|  |  * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Initialize OCode | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void esp_ocode_calib_init(void); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @@ -26,6 +26,7 @@ | |||||||
| #include "esp_private/esp_pmu.h" | #include "esp_private/esp_pmu.h" | ||||||
| #include "esp_rom_uart.h" | #include "esp_rom_uart.h" | ||||||
| #include "esp_rom_sys.h" | #include "esp_rom_sys.h" | ||||||
|  | #include "ocode_init.h" | ||||||
|  |  | ||||||
| /* Number of cycles to wait from the 32k XTAL oscillator to consider it running. | /* Number of cycles to wait from the 32k XTAL oscillator to consider it running. | ||||||
|  * Larger values increase startup delay. Smaller values may cause false positive |  * Larger values increase startup delay. Smaller values may cause false positive | ||||||
| @@ -44,6 +45,9 @@ static const char *TAG = "clk"; | |||||||
| { | { | ||||||
| #if !CONFIG_IDF_ENV_FPGA | #if !CONFIG_IDF_ENV_FPGA | ||||||
|     pmu_init(); |     pmu_init(); | ||||||
|  |     if (esp_rom_get_reset_reason(0) == RESET_REASON_CHIP_POWER_ON) { | ||||||
|  |         esp_ocode_calib_init(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); |     assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  */ |  */ | ||||||
| @@ -204,7 +204,6 @@ uint32_t adc_hal_self_calibration(adc_unit_t adc_n, adc_atten_t atten, bool inte | |||||||
|  |  | ||||||
|     adc_ll_calibration_finish(adc_n); |     adc_ll_calibration_finish(adc_n); | ||||||
|     return ret; |     return ret; | ||||||
|     return 0; |  | ||||||
| } | } | ||||||
| #endif  //#if SOC_ADC_SELF_HW_CALI_SUPPORTED | #endif  //#if SOC_ADC_SELF_HW_CALI_SUPPORTED | ||||||
| #endif //SOC_ADC_CALIBRATION_V1_SUPPORTED | #endif //SOC_ADC_CALIBRATION_V1_SUPPORTED | ||||||
|   | |||||||
| @@ -24,6 +24,16 @@ IRAM_ATTR uint32_t efuse_hal_chip_revision(void) | |||||||
|     return efuse_hal_get_major_chip_version() * 100 + efuse_hal_get_minor_chip_version(); |     return efuse_hal_get_major_chip_version() * 100 + efuse_hal_get_minor_chip_version(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | uint32_t efuse_hal_blk_version(void) | ||||||
|  | { | ||||||
|  |     return efuse_ll_get_blk_version_major() * 100 + efuse_ll_get_blk_version_minor(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | IRAM_ATTR bool efuse_hal_get_disable_wafer_version_major(void) | ||||||
|  | { | ||||||
|  |     return efuse_ll_get_disable_wafer_version_major(); | ||||||
|  | } | ||||||
|  |  | ||||||
| IRAM_ATTR bool efuse_hal_flash_encryption_enabled(void) | IRAM_ATTR bool efuse_hal_flash_encryption_enabled(void) | ||||||
| { | { | ||||||
|     uint32_t flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt(); |     uint32_t flash_crypt_cnt = efuse_ll_get_flash_crypt_cnt(); | ||||||
|   | |||||||
| @@ -119,6 +119,16 @@ __attribute__((always_inline)) static inline bool efuse_ll_get_disable_wafer_ver | |||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | __attribute__((always_inline)) static inline bool efuse_ll_get_blk_version_major(void) | ||||||
|  | { | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | __attribute__((always_inline)) static inline uint32_t efuse_ll_get_blk_version_minor(void) | ||||||
|  | { | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| __attribute__((always_inline)) static inline uint32_t efuse_ll_get_coding_scheme(void) | __attribute__((always_inline)) static inline uint32_t efuse_ll_get_coding_scheme(void) | ||||||
| { | { | ||||||
|     return EFUSE.blk0_rdata6.rd_coding_scheme; |     return EFUSE.blk0_rdata6.rd_coding_scheme; | ||||||
|   | |||||||
| @@ -540,7 +540,7 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c | |||||||
| __attribute__((always_inline)) | __attribute__((always_inline)) | ||||||
| static inline void adc_ll_calibration_init(adc_unit_t adc_n) | static inline void adc_ll_calibration_init(adc_unit_t adc_n) | ||||||
| { | { | ||||||
|     HAL_ASSERT(adc_n == ADC_UNIT_1); |     (void)adc_n; | ||||||
|     REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); |     REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -82,6 +82,11 @@ __attribute__((always_inline)) static inline uint32_t efuse_ll_get_chip_ver_pkg( | |||||||
|     return EFUSE.rd_mac_spi_sys_3.pkg_version; |     return EFUSE.rd_mac_spi_sys_3.pkg_version; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | __attribute__((always_inline)) static inline uint32_t efuse_ll_get_ocode(void) | ||||||
|  | { | ||||||
|  |     return EFUSE.rd_sys_part1_data4.ocode; | ||||||
|  | } | ||||||
|  |  | ||||||
| /******************* eFuse control functions *************************/ | /******************* eFuse control functions *************************/ | ||||||
|  |  | ||||||
| __attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void) | __attribute__((always_inline)) static inline bool efuse_ll_get_read_cmd(void) | ||||||
|   | |||||||
| @@ -540,7 +540,7 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c | |||||||
| __attribute__((always_inline)) | __attribute__((always_inline)) | ||||||
| static inline void adc_ll_calibration_init(adc_unit_t adc_n) | static inline void adc_ll_calibration_init(adc_unit_t adc_n) | ||||||
| { | { | ||||||
|     HAL_ASSERT(adc_n == ADC_UNIT_1); |     (void)adc_n; | ||||||
|     REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); |     REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,6 +27,13 @@ void efuse_hal_get_mac(uint8_t *mac); | |||||||
|  */ |  */ | ||||||
| uint32_t efuse_hal_chip_revision(void); | uint32_t efuse_hal_chip_revision(void); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @brief Return block version | ||||||
|  |  * | ||||||
|  |  * @return Block version in format: Major * 100 + Minor | ||||||
|  |  */ | ||||||
|  | uint32_t efuse_hal_blk_version(void); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @brief Is flash encryption currently enabled in hardware? |  * @brief Is flash encryption currently enabled in hardware? | ||||||
|  * |  * | ||||||
|   | |||||||
| @@ -23,10 +23,10 @@ | |||||||
| #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     32 | #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     32 | ||||||
| #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15 | #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15 | ||||||
|  |  | ||||||
| //TODO: IDF-5312 | #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER                 5 | ||||||
| #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_NO_FILTER                 10 | #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2                  5 | ||||||
| #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_2                  10 | #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4                  5 | ||||||
| #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_4                  10 | #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8                  5 | ||||||
| #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_8                  10 | #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16                 5 | ||||||
| #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_16                 10 | #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64                 5 | ||||||
| #define IDF_PERFORMANCE_MAX_ADC_CONTINUOUS_STD_ATTEN3_FILTER_64                 10 | #define IDF_PERFORMANCE_MAX_ADC_ONESHOT_STD_ATTEN3                              5 | ||||||
|   | |||||||
| @@ -285,7 +285,15 @@ config SOC_ADC_RTC_MAX_BITWIDTH | |||||||
|  |  | ||||||
| config SOC_ADC_CALIBRATION_V1_SUPPORTED | config SOC_ADC_CALIBRATION_V1_SUPPORTED | ||||||
|     bool |     bool | ||||||
|     default n |     default y | ||||||
|  |  | ||||||
|  | config SOC_ADC_SELF_HW_CALI_SUPPORTED | ||||||
|  |     bool | ||||||
|  |     default y | ||||||
|  |  | ||||||
|  | config SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED | ||||||
|  |     bool | ||||||
|  |     default y | ||||||
|  |  | ||||||
| config SOC_ADC_TEMPERATURE_SHARE_INTR | config SOC_ADC_TEMPERATURE_SHARE_INTR | ||||||
|     bool |     bool | ||||||
|   | |||||||
| @@ -114,7 +114,9 @@ | |||||||
| #define SOC_ADC_RTC_MAX_BITWIDTH                (12) | #define SOC_ADC_RTC_MAX_BITWIDTH                (12) | ||||||
|  |  | ||||||
| /*!< Calibration */ | /*!< Calibration */ | ||||||
| #define SOC_ADC_CALIBRATION_V1_SUPPORTED        (0) /*!< support HW offset calibration version 1*/ | #define SOC_ADC_CALIBRATION_V1_SUPPORTED        (1) /*!< support HW offset calibration version 1*/ | ||||||
|  | #define SOC_ADC_SELF_HW_CALI_SUPPORTED          (1) /*!< support HW offset self calibration */ | ||||||
|  | #define SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED (1) /*!< support channel compensation to the HW offset calibration */ | ||||||
|  |  | ||||||
| /*!< Interrupt */ | /*!< Interrupt */ | ||||||
| #define SOC_ADC_TEMPERATURE_SHARE_INTR          (1) | #define SOC_ADC_TEMPERATURE_SHARE_INTR          (1) | ||||||
|   | |||||||
| @@ -80,14 +80,25 @@ For those users who use their custom ADC calibration schemes, you could either m | |||||||
|         ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle)); |         ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle)); | ||||||
|  |  | ||||||
|  |  | ||||||
| .. only:: esp32c3 or esp32s3 | .. only:: esp32c3 or esp32s3 or esp32c6 | ||||||
|  |  | ||||||
|     ADC Calibration Curve Fitting Scheme |     ADC Calibration Curve Fitting Scheme | ||||||
|     ```````````````````````````````````` |     ```````````````````````````````````` | ||||||
|  |  | ||||||
|     {IDF_TARGET_NAME} supports :c:macro:`ADC_CALI_SCHEME_VER_CURVE_FITTING` scheme. To create this scheme, set up :cpp:type:`adc_cali_curve_fitting_config_t` first. |     {IDF_TARGET_NAME} supports :c:macro:`ADC_CALI_SCHEME_VER_CURVE_FITTING` scheme. To create this scheme, set up :cpp:type:`adc_cali_curve_fitting_config_t` first. | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     .. only:: not esp32c6 | ||||||
|  |  | ||||||
|         -  :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. |         -  :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. | ||||||
|  |         -  :cpp:member:`adc_cali_curve_fitting_config_t::chan`, this member is kept here for extensibility. The calibration scheme only differs by attenuation, there's no difference among different channels. | ||||||
|  |         -  :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. | ||||||
|  |         -  :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, the ADC raw result bitwidth. | ||||||
|  |  | ||||||
|  |     .. only:: esp32c6 | ||||||
|  |  | ||||||
|  |         -  :cpp:member:`adc_cali_curve_fitting_config_t::unit_id`, the ADC that your ADC raw results are from. | ||||||
|  |         -  :cpp:member:`adc_cali_curve_fitting_config_t::chan`, the ADC channel that your ADC raw results are from. The calibration scheme not only differs by attenuation but also related to the channels. | ||||||
|         -  :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. |         -  :cpp:member:`adc_cali_curve_fitting_config_t::atten`, ADC attenuation that your ADC raw results use. | ||||||
|         -  :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, the ADC raw result bitwidth. |         -  :cpp:member:`adc_cali_curve_fitting_config_t::bitwidth`, the ADC raw result bitwidth. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 |  * SPDX-License-Identifier: Apache-2.0 | ||||||
|  */ |  */ | ||||||
| @@ -49,7 +49,7 @@ const static char *TAG = "EXAMPLE"; | |||||||
|  |  | ||||||
| static int adc_raw[2][10]; | static int adc_raw[2][10]; | ||||||
| static int voltage[2][10]; | static int voltage[2][10]; | ||||||
| static bool example_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle); | static bool example_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_cali_handle_t *out_handle); | ||||||
| static void example_adc_calibration_deinit(adc_cali_handle_t handle); | static void example_adc_calibration_deinit(adc_cali_handle_t handle); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -71,8 +71,10 @@ void app_main(void) | |||||||
|     ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config)); |     ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, EXAMPLE_ADC1_CHAN1, &config)); | ||||||
|  |  | ||||||
|     //-------------ADC1 Calibration Init---------------// |     //-------------ADC1 Calibration Init---------------// | ||||||
|     adc_cali_handle_t adc1_cali_handle = NULL; |     adc_cali_handle_t adc1_cali_chan0_handle = NULL; | ||||||
|     bool do_calibration1 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC_ATTEN, &adc1_cali_handle); |     adc_cali_handle_t adc1_cali_chan1_handle = NULL; | ||||||
|  |     bool do_calibration1_chan0 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN0, EXAMPLE_ADC_ATTEN, &adc1_cali_chan0_handle); | ||||||
|  |     bool do_calibration1_chan1 = example_adc_calibration_init(ADC_UNIT_1, EXAMPLE_ADC1_CHAN1, EXAMPLE_ADC_ATTEN, &adc1_cali_chan1_handle); | ||||||
|  |  | ||||||
|  |  | ||||||
| #if EXAMPLE_USE_ADC2 | #if EXAMPLE_USE_ADC2 | ||||||
| @@ -86,7 +88,7 @@ void app_main(void) | |||||||
|  |  | ||||||
|     //-------------ADC2 Calibration Init---------------// |     //-------------ADC2 Calibration Init---------------// | ||||||
|     adc_cali_handle_t adc2_cali_handle = NULL; |     adc_cali_handle_t adc2_cali_handle = NULL; | ||||||
|     bool do_calibration2 = example_adc_calibration_init(ADC_UNIT_2, EXAMPLE_ADC_ATTEN, &adc2_cali_handle); |     bool do_calibration2 = example_adc_calibration_init(ADC_UNIT_2, EXAMPLE_ADC2_CHAN0, EXAMPLE_ADC_ATTEN, &adc2_cali_handle); | ||||||
|  |  | ||||||
|     //-------------ADC2 Config---------------// |     //-------------ADC2 Config---------------// | ||||||
|     ESP_ERROR_CHECK(adc_oneshot_config_channel(adc2_handle, EXAMPLE_ADC2_CHAN0, &config)); |     ESP_ERROR_CHECK(adc_oneshot_config_channel(adc2_handle, EXAMPLE_ADC2_CHAN0, &config)); | ||||||
| @@ -95,16 +97,16 @@ void app_main(void) | |||||||
|     while (1) { |     while (1) { | ||||||
|         ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0])); |         ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN0, &adc_raw[0][0])); | ||||||
|         ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]); |         ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, adc_raw[0][0]); | ||||||
|         if (do_calibration1) { |         if (do_calibration1_chan0) { | ||||||
|             ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, adc_raw[0][0], &voltage[0][0])); |             ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, adc_raw[0][0], &voltage[0][0])); | ||||||
|             ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]); |             ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN0, voltage[0][0]); | ||||||
|         } |         } | ||||||
|         vTaskDelay(pdMS_TO_TICKS(1000)); |         vTaskDelay(pdMS_TO_TICKS(1000)); | ||||||
|  |  | ||||||
|         ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN1, &adc_raw[0][1])); |         ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, EXAMPLE_ADC1_CHAN1, &adc_raw[0][1])); | ||||||
|         ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN1, adc_raw[0][1]); |         ESP_LOGI(TAG, "ADC%d Channel[%d] Raw Data: %d", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN1, adc_raw[0][1]); | ||||||
|         if (do_calibration1) { |         if (do_calibration1_chan1) { | ||||||
|             ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, adc_raw[0][1], &voltage[0][1])); |             ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan1_handle, adc_raw[0][1], &voltage[0][1])); | ||||||
|             ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN1, voltage[0][1]); |             ESP_LOGI(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", ADC_UNIT_1 + 1, EXAMPLE_ADC1_CHAN1, voltage[0][1]); | ||||||
|         } |         } | ||||||
|         vTaskDelay(pdMS_TO_TICKS(1000)); |         vTaskDelay(pdMS_TO_TICKS(1000)); | ||||||
| @@ -122,8 +124,11 @@ void app_main(void) | |||||||
|  |  | ||||||
|     //Tear Down |     //Tear Down | ||||||
|     ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle)); |     ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle)); | ||||||
|     if (do_calibration1) { |     if (do_calibration1_chan0) { | ||||||
|         example_adc_calibration_deinit(adc1_cali_handle); |         example_adc_calibration_deinit(adc1_cali_chan0_handle); | ||||||
|  |     } | ||||||
|  |     if (do_calibration1_chan1) { | ||||||
|  |         example_adc_calibration_deinit(adc1_cali_chan1_handle); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| #if EXAMPLE_USE_ADC2 | #if EXAMPLE_USE_ADC2 | ||||||
| @@ -138,7 +143,7 @@ void app_main(void) | |||||||
| /*--------------------------------------------------------------- | /*--------------------------------------------------------------- | ||||||
|         ADC Calibration |         ADC Calibration | ||||||
| ---------------------------------------------------------------*/ | ---------------------------------------------------------------*/ | ||||||
| static bool example_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle) | static bool example_adc_calibration_init(adc_unit_t unit, adc_channel_t channel, adc_atten_t atten, adc_cali_handle_t *out_handle) | ||||||
| { | { | ||||||
|     adc_cali_handle_t handle = NULL; |     adc_cali_handle_t handle = NULL; | ||||||
|     esp_err_t ret = ESP_FAIL; |     esp_err_t ret = ESP_FAIL; | ||||||
| @@ -149,6 +154,7 @@ static bool example_adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc | |||||||
|         ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); |         ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); | ||||||
|         adc_cali_curve_fitting_config_t cali_config = { |         adc_cali_curve_fitting_config_t cali_config = { | ||||||
|             .unit_id = unit, |             .unit_id = unit, | ||||||
|  |             .chan = channel, | ||||||
|             .atten = atten, |             .atten = atten, | ||||||
|             .bitwidth = ADC_BITWIDTH_DEFAULT, |             .bitwidth = ADC_BITWIDTH_DEFAULT, | ||||||
|         }; |         }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 laokaiyao
					laokaiyao