kopia lustrzana https://github.com/espressif/esp-idf
adc: support adc self-calibration on esp32s3
rodzic
6704f4c92f
commit
ddd0235783
|
@ -247,11 +247,16 @@ uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t channel, a
|
||||||
uint32_t init_code = 0;
|
uint32_t init_code = 0;
|
||||||
if (version == 1) {
|
if (version == 1) {
|
||||||
init_code = esp_efuse_rtc_calib_get_init_code(version, adc_n, atten);
|
init_code = esp_efuse_rtc_calib_get_init_code(version, adc_n, atten);
|
||||||
s_adc_cali_param[adc_n][atten] = init_code;
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(ADC_TAG, "Calibration eFuse is not configured, skip calibration");
|
ESP_LOGV(ADC_TAG, "Calibration eFuse is not configured, use self-calibration for ICode");
|
||||||
|
adc_power_acquire();
|
||||||
|
RTC_ENTER_CRITICAL();
|
||||||
|
const bool internal_gnd = true;
|
||||||
|
init_code = adc_hal_self_calibration(adc_n, channel, atten, internal_gnd);
|
||||||
|
RTC_EXIT_CRITICAL();
|
||||||
|
adc_power_release();
|
||||||
}
|
}
|
||||||
|
s_adc_cali_param[adc_n][atten] = init_code;
|
||||||
return s_adc_cali_param[adc_n][atten];
|
return s_adc_cali_param[adc_n][atten];
|
||||||
}
|
}
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
#define I2C_SAR_ADC 0X69
|
#define I2C_SAR_ADC 0X69
|
||||||
#define I2C_SAR_ADC_HOSTID 0
|
#define I2C_SAR_ADC_HOSTID 0
|
||||||
|
|
||||||
|
#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_SAR2_ENCAL_GND_ADDR 0x7
|
||||||
|
#define ADC_SAR2_ENCAL_GND_ADDR_MSB 7
|
||||||
|
#define ADC_SAR2_ENCAL_GND_ADDR_LSB 7
|
||||||
|
|
||||||
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR 0x1
|
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR 0x1
|
||||||
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3
|
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB 0x3
|
||||||
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0
|
#define ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB 0x0
|
||||||
|
|
|
@ -71,10 +71,14 @@ void adc_hal_set_calibration_param(adc_ll_num_t adc_n, uint32_t param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
|
static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32S2
|
||||||
adc_hal_set_controller(adc_n, ADC_CTRL_RTC); //Set controller
|
adc_hal_set_controller(adc_n, ADC_CTRL_RTC); //Set controller
|
||||||
|
#else
|
||||||
|
adc_hal_set_controller(adc_n, ADC_LL_CTRL_ARB); //Set controller
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable/disable internal connect GND (for calibration). */
|
/* Enable/disable internal connect GND (for calibration). */
|
||||||
if (internal_gnd) {
|
if (internal_gnd) {
|
||||||
|
@ -134,7 +138,6 @@ static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
|
||||||
#define ADC_HAL_CAL_TIMES (10)
|
#define ADC_HAL_CAL_TIMES (10)
|
||||||
#define ADC_HAL_CAL_OFFSET_RANGE (4096)
|
#define ADC_HAL_CAL_OFFSET_RANGE (4096)
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
|
||||||
uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
|
uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
|
||||||
{
|
{
|
||||||
if (adc_n == ADC_NUM_2) {
|
if (adc_n == ADC_NUM_2) {
|
||||||
|
@ -190,9 +193,9 @@ uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc
|
||||||
: (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
|
: (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
|
||||||
|
|
||||||
adc_ll_calibration_finish(adc_n);
|
adc_ll_calibration_finish(adc_n);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif //#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
|
||||||
#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED
|
#endif //SOC_ADC_CALIBRATION_V1_SUPPORTED
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32H2
|
||||||
|
|
|
@ -129,8 +129,12 @@ static inline void adc_ll_digi_set_fsm_time(uint32_t rst_wait, uint32_t start_wa
|
||||||
*/
|
*/
|
||||||
static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
|
static inline void adc_ll_set_sample_cycle(uint32_t sample_cycle)
|
||||||
{
|
{
|
||||||
//To be added including RTC_CNTR reg and functions
|
/* Should be called before writing I2C registers. */
|
||||||
abort();
|
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M);
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
|
||||||
|
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
|
||||||
|
|
||||||
|
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_SAMPLE_CYCLE_ADDR, sample_cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -720,16 +724,32 @@ static inline void adc_ll_calibration_init(adc_ll_num_t adc_n)
|
||||||
/**
|
/**
|
||||||
* Configure the registers for ADC calibration. You need to call the ``adc_ll_calibration_finish`` interface to resume after calibration.
|
* 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 adc_n ADC index number.
|
||||||
* @param channel adc channel number.
|
* @param channel Not used
|
||||||
* @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage.
|
* @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.
|
* false: Use IO external voltage as calibration voltage.
|
||||||
*/
|
*/
|
||||||
static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd)
|
static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t channel, bool internal_gnd)
|
||||||
{
|
{
|
||||||
abort();
|
/* Should be called before writing I2C registers. */
|
||||||
|
SET_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M);
|
||||||
|
CLEAR_PERI_REG_MASK(ANA_CONFIG_REG, I2C_SAR_M);
|
||||||
|
SET_PERI_REG_MASK(ANA_CONFIG2_REG, ANA_SAR_CFG2_M);
|
||||||
|
|
||||||
|
/* Enable/disable internal connect GND (for calibration). */
|
||||||
|
if (adc_n == ADC_NUM_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 { //adc_n == ADC_NUM_2
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -739,7 +759,11 @@ static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t
|
||||||
*/
|
*/
|
||||||
static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n)
|
static inline void adc_ll_calibration_finish(adc_ll_num_t adc_n)
|
||||||
{
|
{
|
||||||
abort();
|
if (adc_n == ADC_NUM_1) {
|
||||||
|
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_ENCAL_GND_ADDR, 0);
|
||||||
|
} else { //adc_n == ADC_NUM_2
|
||||||
|
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -54,9 +54,9 @@ static bool adc_calibration_init(void)
|
||||||
|
|
||||||
ret = esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME);
|
ret = esp_adc_cal_check_efuse(ADC_EXAMPLE_CALI_SCHEME);
|
||||||
if (ret == ESP_ERR_NOT_SUPPORTED) {
|
if (ret == ESP_ERR_NOT_SUPPORTED) {
|
||||||
ESP_LOGW(TAG, "Calibration scheme not supported, skip calibration");
|
ESP_LOGW(TAG, "Calibration scheme not supported, skip software calibration");
|
||||||
} else if (ret == ESP_ERR_INVALID_VERSION) {
|
} else if (ret == ESP_ERR_INVALID_VERSION) {
|
||||||
ESP_LOGW(TAG, "eFuse not burnt, skip calibration");
|
ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
|
||||||
} else if (ret == ESP_OK) {
|
} else if (ret == ESP_OK) {
|
||||||
cali_enable = true;
|
cali_enable = true;
|
||||||
esp_adc_cal_characterize(ADC_UNIT_1, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars);
|
esp_adc_cal_characterize(ADC_UNIT_1, ADC_EXAMPLE_ATTEN, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars);
|
||||||
|
|
Ładowanie…
Reference in New Issue