mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
feat(adc): support ADC calibration on ESP32P4
This commit is contained in:
parent
cfa487b4e0
commit
1b49a1674e
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -30,8 +30,8 @@ static void adc1_fix_initcode_set(uint32_t initcode_value)
|
||||
{
|
||||
uint32_t msb = initcode_value >> 8;
|
||||
uint32_t lsb = initcode_value & 0xff;
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_SAR1_INIT_CODE_MSB, msb);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_SAR1_INIT_CODE_LSB, lsb);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb);
|
||||
}
|
||||
|
||||
//total 4 tables
|
||||
@ -100,14 +100,8 @@ void bootloader_random_disable(void)
|
||||
// disable analog i2c master clock
|
||||
ANALOG_CLOCK_DISABLE();
|
||||
|
||||
//TODO IDF-4714
|
||||
// disable timer
|
||||
REG_CLR_BIT(ADC_CTRL2_REG, ADC_TIMER_EN);
|
||||
// Write reset value of this register
|
||||
REG_WRITE(ADC_SAR1_PATT_TAB1_REG, 0xFFFFFF);
|
||||
// Revert ADC I2C configuration and initial voltage source setting
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_SAR1_INIT_CODE_MSB, 0);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_SAR1_INIT_CODE_LSB, 0);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, 0);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, 0);
|
||||
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_ENT_VDD_GRP1, 0);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, I2C_SAR_ADC_DTEST_VDD_GRP1, 0);
|
||||
|
@ -18,9 +18,6 @@ components/driver/test_apps/legacy_adc_driver:
|
||||
disable:
|
||||
- if: SOC_ADC_SUPPORTED != 1
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32p4"
|
||||
temporary: true
|
||||
reason: lack of runners, TODO IDF-9573
|
||||
- if: IDF_TARGET == "esp32c61"
|
||||
temporary: true
|
||||
reason: lack of runners
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -69,10 +69,10 @@
|
||||
#define ADC_TEST_HIGH_THRESH 200
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ADC_TEST_LOW_VAL 2152
|
||||
#define ADC_TEST_LOW_THRESH 200
|
||||
#define ADC_TEST_LOW_VAL 0
|
||||
#define ADC_TEST_LOW_THRESH 10
|
||||
|
||||
#define ADC_TEST_HIGH_VAL 4095
|
||||
#define ADC_TEST_HIGH_VAL 3360
|
||||
#define ADC_TEST_HIGH_THRESH 200
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
|
@ -11,6 +11,7 @@ from pytest_embedded import Dut
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.esp32c5
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.adc
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -8,30 +8,190 @@
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "esp_efuse_rtc_calib.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/adc_types.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)
|
||||
{
|
||||
//TODO: IDF-7467, eFuses are not defined yet
|
||||
return 0;
|
||||
uint32_t cali_version = 0;
|
||||
uint32_t blk_ver = efuse_hal_blk_version();
|
||||
if (blk_ver >= 1 && blk_ver < 100) {
|
||||
cali_version = ESP_EFUSE_ADC_CALIB_VER1;
|
||||
} 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)
|
||||
{
|
||||
//TODO: IDF-7467, check below, eFuses are not defined yet
|
||||
(void) version;
|
||||
(void) adc_unit;
|
||||
(void) atten;
|
||||
return 0;
|
||||
/* Version validation should be guaranteed in the caller */
|
||||
assert(atten >=0 && atten < 4);
|
||||
|
||||
const esp_efuse_desc_t** init_code_efuse;
|
||||
if (adc_unit == 0) {
|
||||
if (atten == 0) {
|
||||
init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN0;
|
||||
} else if (atten == 1) {
|
||||
init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN1;
|
||||
} else if (atten == 2) {
|
||||
init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN2;
|
||||
} else {
|
||||
init_code_efuse = ESP_EFUSE_ADC1_AVE_INITCODE_ATTEN3;
|
||||
}
|
||||
} else {
|
||||
if (atten == 0) {
|
||||
init_code_efuse = ESP_EFUSE_ADC2_AVE_INITCODE_ATTEN0;
|
||||
} else if (atten == 1) {
|
||||
init_code_efuse = ESP_EFUSE_ADC2_AVE_INITCODE_ATTEN1;
|
||||
} else if (atten == 2) {
|
||||
init_code_efuse = ESP_EFUSE_ADC2_AVE_INITCODE_ATTEN2;
|
||||
} else {
|
||||
init_code_efuse = ESP_EFUSE_ADC2_AVE_INITCODE_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 + 1400; // 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)
|
||||
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)
|
||||
{
|
||||
//TODO: IDF-7467, check below, eFuses are not defined yet
|
||||
(void) version;
|
||||
(void) atten;
|
||||
(void) out_digi;
|
||||
(void) out_vol_mv;
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
const esp_efuse_desc_t** cal_vol_adc1_efuse[4] = {
|
||||
ESP_EFUSE_ADC1_HI_DOUT_ATTEN0,
|
||||
ESP_EFUSE_ADC1_HI_DOUT_ATTEN1,
|
||||
ESP_EFUSE_ADC1_HI_DOUT_ATTEN2,
|
||||
ESP_EFUSE_ADC1_HI_DOUT_ATTEN3,
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t** cal_vol_adc2_efuse[4] = {
|
||||
ESP_EFUSE_ADC2_HI_DOUT_ATTEN0,
|
||||
ESP_EFUSE_ADC2_HI_DOUT_ATTEN1,
|
||||
ESP_EFUSE_ADC2_HI_DOUT_ATTEN2,
|
||||
ESP_EFUSE_ADC2_HI_DOUT_ATTEN3,
|
||||
};
|
||||
|
||||
|
||||
const uint32_t input_vout_mv[1][4] = {
|
||||
{600, 800, 1200, 2300}, // Calibration V1 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_adc1_efuse[atten][0]->bit_count == 10);
|
||||
assert(cal_vol_adc2_efuse[atten][0]->bit_count == 10);
|
||||
|
||||
uint32_t cal_vol = 0;
|
||||
esp_err_t ret = ESP_OK;
|
||||
if (adc_unit == ADC_UNIT_1) {
|
||||
ret = esp_efuse_read_field_blob(cal_vol_adc1_efuse[atten], &cal_vol, cal_vol_adc1_efuse[atten][0]->bit_count);
|
||||
} else {
|
||||
ret = esp_efuse_read_field_blob(cal_vol_adc2_efuse[atten], &cal_vol, cal_vol_adc2_efuse[atten][0]->bit_count);
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
uint32_t chk_offset;
|
||||
if (atten == 0) {
|
||||
chk_offset = 2300;
|
||||
} else if (atten == 1) {
|
||||
chk_offset = 2300;
|
||||
} else if (atten == 2) {
|
||||
chk_offset = 2350;
|
||||
} else {
|
||||
chk_offset = 2350;
|
||||
}
|
||||
|
||||
*out_digi = chk_offset + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9);
|
||||
*out_vol_mv = input_vout_mv[VER2IDX(version)][atten];
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten)
|
||||
{
|
||||
/* 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;
|
||||
if (adc_unit == ADC_UNIT_1) {
|
||||
switch (adc_channel) {
|
||||
case 0:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH0_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 1:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH1_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 2:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH2_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 3:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH3_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 4:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH4_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 5:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH5_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 6:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH6_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
default:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC1_CH7_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (adc_channel) {
|
||||
case 0:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC2_CH0_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 1:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC2_CH1_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 2:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC2_CH2_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 3:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC2_CH3_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
case 4:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC2_CH4_ATTEN0_INITCODE_DIFF;
|
||||
break;
|
||||
default:
|
||||
chan_diff_efuse = ESP_EFUSE_ADC2_CH5_ATTEN0_INITCODE_DIFF;
|
||||
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_tsens_val(float* tsens_cal)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,7 +12,10 @@ 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_VER1 1
|
||||
#define ESP_EFUSE_ADC_CALIB_VER_MIN ESP_EFUSE_ADC_CALIB_VER1
|
||||
#define ESP_EFUSE_ADC_CALIB_VER_MAX ESP_EFUSE_ADC_CALIB_VER1
|
||||
#define VER2IDX(ver) ((ver) - 1) // Version number to index number of the array
|
||||
|
||||
/**
|
||||
* @brief Get the RTC calibration efuse version
|
||||
@ -31,6 +34,16 @@ 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);
|
||||
|
||||
/**
|
||||
* @brief Get the channel specific calibration compensation
|
||||
*
|
||||
* @param version Version of the stored efuse
|
||||
* @param adc_unit ADC unit. Not used, for compatibility. ESP32H2 only supports one ADC unit
|
||||
* @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.
|
||||
*
|
||||
@ -42,7 +55,7 @@ uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int a
|
||||
* - ESP_ERR_INVALID_ARG: If efuse version or attenuation is invalid
|
||||
* - ESP_OK: if success
|
||||
*/
|
||||
esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, 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);
|
||||
|
||||
/**
|
||||
* @brief Get the temperature sensor calibration number delta_T stored in the efuse.
|
||||
|
88
components/esp_adc/esp32p4/curve_fitting_coefficients.c
Normal file
88
components/esp_adc/esp32p4/curve_fitting_coefficients.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_efuse_rtc_calib.h"
|
||||
#include "../curve_fitting_coefficients.h"
|
||||
|
||||
#define COEFF_VERSION_NUM 1 // Currently P4 has one versions of curve calibration schemes
|
||||
#define COEFF_GROUP_NUM 4
|
||||
#define TERM_MAX 2
|
||||
|
||||
/**
|
||||
* @note Error Calculation
|
||||
* Coefficients for calculating the reading voltage error.
|
||||
* Four sets of coefficients for atten0 ~ atten3 respectively.
|
||||
*
|
||||
* 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 In case of the overflow, these coefficients are recorded as Absolute Value
|
||||
* @note For atten0 ~ 3, error = (K0 * X^0) + (K1 * X^1)
|
||||
* @note Above formula is rewritten from the original documentation, please note that the coefficients are re-ordered.
|
||||
*/
|
||||
const static uint64_t adc1_error_coef_atten[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX][2] = {
|
||||
/* Coefficients of calibration version 1 */
|
||||
{
|
||||
{{7170501832480995, 1e16}, {10598497992115, 1e16}}, //atten0
|
||||
{{9960085535084866, 1e16}, {15840076608145, 1e16}}, //atten1
|
||||
{{14711053224678996, 1e16}, {1594266424857, 1e17}}, //atten2
|
||||
{{28811493455181565, 1e16}, {10082311568625, 1e16}}, //atten3
|
||||
},
|
||||
};
|
||||
|
||||
const static uint64_t adc2_error_coef_atten[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX][2] = {
|
||||
/* Coefficients of calibration version 1 */
|
||||
{
|
||||
{{4900967548489932, 1e16}, {5037402667913, 1e16}}, //atten0
|
||||
{{7296214814536025, 1e16}, {11021577596635, 1e16}}, //atten1
|
||||
{{10991620450220592, 1e16}, {11623930881896, 1e16}}, //atten2
|
||||
{{24421401024626730, 1e16}, {9458501263393, 1e16}}, //atten3
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Term sign ADC1
|
||||
*/
|
||||
const static int32_t adc1_error_sign[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX] = {
|
||||
/* Coefficient sign of calibration version 1 */
|
||||
{
|
||||
{-1, 1}, //atten0
|
||||
{-1, 1}, //atten1
|
||||
{-1, 1}, //atten2
|
||||
{-1, 1}, //atten3
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Term sign ADC2
|
||||
*/
|
||||
const static int32_t adc2_error_sign[COEFF_VERSION_NUM][COEFF_GROUP_NUM][TERM_MAX] = {
|
||||
/* Coefficient sign of calibration version 1 */
|
||||
{
|
||||
{-1, 1}, //atten0
|
||||
{-1, 1}, //atten1
|
||||
{-1, 1}, //atten2
|
||||
{-1, 1}, //atten3
|
||||
},
|
||||
};
|
||||
|
||||
void curve_fitting_get_second_step_coeff(const adc_cali_curve_fitting_config_t *config, cali_chars_second_step_t *ctx)
|
||||
{
|
||||
uint32_t adc_calib_ver = esp_efuse_rtc_calib_get_ver();
|
||||
assert((adc_calib_ver >= ESP_EFUSE_ADC_CALIB_VER_MIN) &&
|
||||
(adc_calib_ver <= ESP_EFUSE_ADC_CALIB_VER_MAX));
|
||||
|
||||
ctx->term_num = 2;
|
||||
|
||||
ctx->coeff = config->unit_id == ADC_UNIT_1 ?
|
||||
adc1_error_coef_atten[VER2IDX(adc_calib_ver)][config->atten] :
|
||||
adc2_error_coef_atten[VER2IDX(adc_calib_ver)][config->atten];
|
||||
ctx->sign = config->unit_id == ADC_UNIT_1 ?
|
||||
adc1_error_sign[VER2IDX(adc_calib_ver)][config->atten] :
|
||||
adc2_error_sign[VER2IDX(adc_calib_ver)][config->atten];
|
||||
}
|
@ -12,4 +12,4 @@
|
||||
* @brief Supported calibration schemes
|
||||
*/
|
||||
|
||||
//Now no scheme supported
|
||||
#define ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -88,10 +88,10 @@ extern "C" {
|
||||
#define ADC_TEST_HIGH_THRESH 200
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ADC_TEST_LOW_VAL 2152
|
||||
#define ADC_TEST_LOW_THRESH 200
|
||||
#define ADC_TEST_LOW_VAL 0
|
||||
#define ADC_TEST_LOW_THRESH 10
|
||||
|
||||
#define ADC_TEST_HIGH_VAL 4095
|
||||
#define ADC_TEST_HIGH_VAL 3360
|
||||
#define ADC_TEST_HIGH_VAL_DMA 4095
|
||||
#define ADC_TEST_HIGH_THRESH 200
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -651,6 +651,86 @@ static inline void adc_ll_set_controller(adc_unit_t adc_n, adc_ll_controller_t c
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Calibration
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Set common calibration configuration. Should be shared with other parts (PWDET).
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void adc_ll_calibration_init(adc_unit_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 4);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_DREF_ADDR, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
* @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.
|
||||
*/
|
||||
static inline void adc_ll_calibration_prepare(adc_unit_t adc_n, bool internal_gnd)
|
||||
{
|
||||
/* Enable/disable internal connect GND (for calibration). */
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
if (internal_gnd) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 1);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
|
||||
}
|
||||
} else {
|
||||
if (internal_gnd) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 1);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume register status after calibration.
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
*/
|
||||
static inline void adc_ll_calibration_finish(adc_unit_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
|
||||
} else { //adc_n == ADC_UNIT_2
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the calibration result to ADC.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void adc_ll_set_calibration_param(adc_unit_t adc_n, uint32_t param)
|
||||
{
|
||||
uint8_t msb = param >> 8;
|
||||
uint8_t lsb = param & 0xFF;
|
||||
|
||||
if (adc_n == ADC_UNIT_1) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_HIGH_ADDR, msb);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_INITIAL_CODE_LOW_ADDR, lsb);
|
||||
} else {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_HIGH_ADDR, msb);
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_INITIAL_CODE_LOW_ADDR, lsb);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Oneshot Read
|
||||
---------------------------------------------------------------*/
|
||||
|
@ -429,7 +429,15 @@ config SOC_ADC_RTC_MAX_BITWIDTH
|
||||
|
||||
config SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||
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_SHARED_POWER
|
||||
bool
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -18,25 +18,13 @@
|
||||
#define I2C_SAR_ADC 0X69
|
||||
#define I2C_SAR_ADC_HOSTID 0
|
||||
|
||||
#define I2C_SARADC_TSENS_DAC 0x6
|
||||
#define I2C_SARADC_TSENS_DAC_MSB 3
|
||||
#define I2C_SARADC_TSENS_DAC_LSB 0
|
||||
#define ADC_SAR1_INITIAL_CODE_LOW_ADDR 0x0
|
||||
#define ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB 0x7
|
||||
#define ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB 0x0
|
||||
|
||||
#define I2C_SAR_ADC_SAR1_INIT_CODE_LSB 0
|
||||
#define I2C_SAR_ADC_SAR1_INIT_CODE_LSB_MSB 7
|
||||
#define I2C_SAR_ADC_SAR1_INIT_CODE_LSB_LSB 0
|
||||
|
||||
#define I2C_SAR_ADC_SAR1_INIT_CODE_MSB 1
|
||||
#define I2C_SAR_ADC_SAR1_INIT_CODE_MSB_MSB 3
|
||||
#define I2C_SAR_ADC_SAR1_INIT_CODE_MSB_LSB 0
|
||||
|
||||
#define I2C_SAR_ADC_ENT_VDD_GRP1 9
|
||||
#define I2C_SAR_ADC_ENT_VDD_GRP1_MSB 4
|
||||
#define I2C_SAR_ADC_ENT_VDD_GRP1_LSB 4
|
||||
|
||||
#define I2C_SAR_ADC_DTEST_VDD_GRP1 9
|
||||
#define I2C_SAR_ADC_DTEST_VDD_GRP1_MSB 3
|
||||
#define I2C_SAR_ADC_DTEST_VDD_GRP1_LSB 0
|
||||
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR 0x1
|
||||
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3
|
||||
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0
|
||||
|
||||
#define ADC_SAR1_SAMPLE_CYCLE_ADDR 0x2
|
||||
#define ADC_SAR1_SAMPLE_CYCLE_ADDR_MSB 0x2
|
||||
@ -62,18 +50,30 @@
|
||||
#define ADC_SAR2_DREF_ADDR_MSB 0x6
|
||||
#define ADC_SAR2_DREF_ADDR_LSB 0x4
|
||||
|
||||
#define I2C_SARADC_TSENS_DAC 0x6
|
||||
#define I2C_SARADC_TSENS_DAC_MSB 0x3
|
||||
#define I2C_SARADC_TSENS_DAC_LSB 0x0
|
||||
|
||||
#define ADC_SAR1_ENCAL_REF_ADDR 0x7
|
||||
#define ADC_SAR1_ENCAL_REF_ADDR_MSB 4
|
||||
#define ADC_SAR1_ENCAL_REF_ADDR_LSB 4
|
||||
#define ADC_SAR1_ENCAL_REF_ADDR_MSB 0X4
|
||||
#define ADC_SAR1_ENCAL_REF_ADDR_LSB 0X4
|
||||
|
||||
#define ADC_SAR1_ENCAL_GND_ADDR 0x7
|
||||
#define ADC_SAR1_ENCAL_GND_ADDR_MSB 5
|
||||
#define ADC_SAR1_ENCAL_GND_ADDR_LSB 5
|
||||
#define ADC_SAR1_ENCAL_GND_ADDR_MSB 0x5
|
||||
#define ADC_SAR1_ENCAL_GND_ADDR_LSB 0x5
|
||||
|
||||
#define ADC_SAR2_ENCAL_REF_ADDR 0x7
|
||||
#define ADC_SAR2_ENCAL_REF_ADDR_MSB 6
|
||||
#define ADC_SAR2_ENCAL_REF_ADDR_LSB 6
|
||||
#define ADC_SAR2_ENCAL_REF_ADDR_MSB 0x6
|
||||
#define ADC_SAR2_ENCAL_REF_ADDR_LSB 0x6
|
||||
|
||||
#define ADC_SAR2_ENCAL_GND_ADDR 0x7
|
||||
#define ADC_SAR2_ENCAL_GND_ADDR_MSB 7
|
||||
#define ADC_SAR2_ENCAL_GND_ADDR_LSB 7
|
||||
#define ADC_SAR2_ENCAL_GND_ADDR_MSB 0x7
|
||||
#define ADC_SAR2_ENCAL_GND_ADDR_LSB 0x7
|
||||
|
||||
#define I2C_SAR_ADC_DTEST_VDD_GRP1 0x9
|
||||
#define I2C_SAR_ADC_DTEST_VDD_GRP1_MSB 0x3
|
||||
#define I2C_SAR_ADC_DTEST_VDD_GRP1_LSB 0x0
|
||||
|
||||
#define I2C_SAR_ADC_ENT_VDD_GRP1 0x9
|
||||
#define I2C_SAR_ADC_ENT_VDD_GRP1_MSB 0x4
|
||||
#define I2C_SAR_ADC_ENT_VDD_GRP1_LSB 0x4
|
||||
|
@ -144,7 +144,9 @@
|
||||
#define SOC_ADC_RTC_MAX_BITWIDTH (12)
|
||||
|
||||
/*!< 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 */
|
||||
|
||||
/*!< ADC power control is shared by PWDET, TempSensor */
|
||||
#define SOC_ADC_SHARED_POWER 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user