Skip to content

Commit

Permalink
Merge branch 'feature/support_adc_calibration_on_c6_v5.1' into 'relea…
Browse files Browse the repository at this point in the history
…se/v5.1'

adc_cali: supported adc calibration on esp32c6 (v5.1)

See merge request espressif/esp-idf!23936
  • Loading branch information
ginkgm committed Jul 7, 2023
2 parents 6cb39b4 + 57312e6 commit 5c11366
Show file tree
Hide file tree
Showing 50 changed files with 1,205 additions and 195 deletions.
6 changes: 6 additions & 0 deletions components/driver/deprecated/adc_dma_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void)
* update this when bringing up the calibration on that chip
*/
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
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions components/driver/deprecated/adc_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,12 @@ static __attribute__((constructor)) void adc_hw_calibration(void)
* update this when bringing up the calibration on that chip
*/
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
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@
#define ADC_TEST_HIGH_VAL 3400
#define ADC_TEST_HIGH_THRESH 200

#elif CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5312
#define ADC_TEST_LOW_VAL 2144
#define ADC_TEST_LOW_THRESH 200
#elif CONFIG_IDF_TARGET_ESP32C6
#define ADC_TEST_LOW_VAL 0
#define ADC_TEST_LOW_THRESH 15

#define ADC_TEST_HIGH_VAL 4081
#define ADC_TEST_HIGH_VAL 3350
#define ADC_TEST_HIGH_THRESH 200

#elif CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-6216
Expand Down
8 changes: 5 additions & 3 deletions components/efuse/esp32c2/esp_efuse_rtc_calib.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -26,7 +26,8 @@ int esp_efuse_rtc_calib_get_ver(void)

uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten)
{
assert(version == ESP_EFUSE_ADC_CALIB_VER);
assert((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) &&
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
assert(atten <= ADC_ATTEN_DB_11);
(void) adc_unit;

Expand Down Expand Up @@ -64,7 +65,8 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a

esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t *out_digi, uint32_t *out_vol_mv)
{
assert(version == ESP_EFUSE_ADC_CALIB_VER);
assert((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) &&
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
assert(atten <= ADC_ATTEN_DB_11);
(void) adc_unit;

Expand Down
4 changes: 3 additions & 1 deletion components/efuse/esp32c2/include/esp_efuse_rtc_calib.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ extern "C" {
#endif

//This is the ADC calibration value version burnt in efuse
#define ESP_EFUSE_ADC_CALIB_VER 1
#define ESP_EFUSE_ADC_CALIB_VER 1
#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER
#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER

/**
* @brief Get the RTC calibration efuse version
Expand Down
8 changes: 5 additions & 3 deletions components/efuse/esp32c3/esp_efuse_rtc_calib.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -24,7 +24,8 @@ int esp_efuse_rtc_calib_get_ver(void)

uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten)
{
assert(version == ESP_EFUSE_ADC_CALIB_VER);
assert((version >= ESP_EFUSE_ADC_CALIB_VER_MIN) &&
(version <= ESP_EFUSE_ADC_CALIB_VER_MAX));
(void) adc_unit;
const esp_efuse_desc_t** init_code_efuse;
assert(atten < 4);
Expand All @@ -51,7 +52,8 @@ esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, in
(void)adc_unit; //On esp32c3, V1 we don't have calibration data for ADC2, using the efuse data of ADC1
const esp_efuse_desc_t** cal_vol_efuse;
uint32_t calib_vol_expected_mv;
if (version != ESP_EFUSE_ADC_CALIB_VER) {
if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) ||
(version > ESP_EFUSE_ADC_CALIB_VER_MAX)) {
return ESP_ERR_INVALID_ARG;
}
if (atten >= 4) {
Expand Down
4 changes: 3 additions & 1 deletion components/efuse/esp32c3/include/esp_efuse_rtc_calib.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ extern "C" {
#endif

//This is the ADC calibration value version burnt in efuse
#define ESP_EFUSE_ADC_CALIB_VER 1
#define ESP_EFUSE_ADC_CALIB_VER 1
#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER
#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER

/**
* @brief Get the RTC calibration efuse version
Expand Down
122 changes: 109 additions & 13 deletions components/efuse/esp32c6/esp_efuse_rtc_calib.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,126 @@
#include <esp_bit_defs.h>
#include "esp_efuse.h"
#include "esp_efuse_table.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)
{
uint32_t result = 0;
esp_efuse_read_field_blob(ESP_EFUSE_BLK_VERSION_MAJOR, &result, ESP_EFUSE_BLK_VERSION_MAJOR[0]->bit_count); // IDF-5366
return result;
uint32_t cali_version = 0;
uint32_t blk_ver = efuse_hal_blk_version();
if (blk_ver == 1) {
cali_version = ESP_EFUSE_ADC_CALIB_VER1;
} else if (blk_ver >= 2) {
cali_version = ESP_EFUSE_ADC_CALIB_VER2;
} else {
ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0");
}

return cali_version;
}

uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten)
{
// Currently calibration is not supported on ESP32-C6, IDF-5236
(void) version;
/* Version validation should be guaranteed in the caller */
assert(atten >=0 && atten < 4);
(void) adc_unit;
(void) atten;
return 0;

const esp_efuse_desc_t** init_code_efuse;
if (atten == 0) {
init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0;
} else if (atten == 1) {
init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN1;
} else if (atten == 2) {
init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN2;
} else {
init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN3;
}

int init_code_size = esp_efuse_get_field_size(init_code_efuse);
assert(init_code_size == 10);

uint32_t init_code = 0;
ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size));
return init_code + 1600; // version 1 logic
}

esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, int atten, uint32_t* out_digi, uint32_t* out_vol_mv)
int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten)
{
// Currently calibration is not supported on ESP32-C6, IDF-5236
(void) version;
(void) atten;
(void) out_digi;
(void) out_vol_mv;
/* Version validation should be guaranteed in the caller */
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)
{
(void) adc_unit;
const esp_efuse_desc_t** cal_vol_efuse[4] = {
ESP_EFUSE_ADC1_CAL_VOL_ATTEN0,
ESP_EFUSE_ADC1_CAL_VOL_ATTEN1,
ESP_EFUSE_ADC1_CAL_VOL_ATTEN2,
ESP_EFUSE_ADC1_CAL_VOL_ATTEN3,
};
const uint32_t input_vout_mv[2][4] = {
{400, 550, 750, 1370}, // Calibration V1 coefficients
{750, 1000, 1500, 2800}, // Calibration V2 coefficients
};

if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) ||
(version > ESP_EFUSE_ADC_CALIB_VER_MAX)) {
return ESP_ERR_INVALID_ARG;
}
if (atten >= 4 || atten < 0) {
return ESP_ERR_INVALID_ARG;
}

assert(cal_vol_efuse[atten][0]->bit_count == 10);

uint32_t cal_vol = 0;
esp_err_t ret = esp_efuse_read_field_blob(cal_vol_efuse[atten], &cal_vol, cal_vol_efuse[atten][0]->bit_count);
if (ret != ESP_OK) {
return ret;
}
uint32_t chk_offset = (version == ESP_EFUSE_ADC_CALIB_VER1) ? 1500 : (atten == 2) ? 2900 : 2850;
*out_digi = chk_offset + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9);
*out_vol_mv = input_vout_mv[VER2IDX(version)][atten];
return ESP_OK;
}

Expand Down
Loading

0 comments on commit 5c11366

Please sign in to comment.