mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-05 04:15:21 +02:00
Merge branch 'feature/sync_adc_changes_from_c3_to_master_last' into 'master'
adc: sync adc changes from c3 to master (last time) Closes IDF-2694 See merge request espressif/esp-idf!12134
This commit is contained in:
@@ -146,86 +146,3 @@ void adc_hal_arbiter_config(adc_arbiter_t *config)
|
||||
adc_ll_set_arbiter_work_mode(config->mode);
|
||||
adc_ll_set_arbiter_priority(config->rtc_pri, config->dig_pri, config->pwdet_pri);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
ADC calibration setting
|
||||
---------------------------------------------------------------*/
|
||||
#define ADC_HAL_CAL_TIMES (10)
|
||||
#define ADC_HAL_CAL_OFFSET_RANGE (4096)
|
||||
|
||||
static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel)
|
||||
{
|
||||
adc_ll_rtc_start_convert(adc_n, channel);
|
||||
while (adc_ll_rtc_convert_is_done(adc_n) != true);
|
||||
return (uint32_t)adc_ll_rtc_get_convert_value(adc_n);
|
||||
}
|
||||
|
||||
uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
|
||||
{
|
||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
||||
|
||||
if (adc_n == ADC_NUM_2) {
|
||||
adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
|
||||
adc_hal_arbiter_config(&config);
|
||||
}
|
||||
adc_hal_set_controller(adc_n, ADC_CTRL_RTC); //Set controller
|
||||
|
||||
|
||||
adc_ll_calibration_prepare(adc_n, channel, internal_gnd);
|
||||
/* Enable/disable internal connect GND (for calibration). */
|
||||
if (internal_gnd) {
|
||||
adc_ll_rtc_disable_channel(adc_n, channel);
|
||||
adc_ll_set_atten(adc_n, 0, atten); // Note: when disable all channel, HW auto select channel0 atten param.
|
||||
} else {
|
||||
adc_ll_rtc_enable_channel(adc_n, channel);
|
||||
adc_ll_set_atten(adc_n, channel, atten);
|
||||
}
|
||||
|
||||
uint32_t code_list[ADC_HAL_CAL_TIMES] = {0};
|
||||
uint32_t code_sum = 0;
|
||||
uint32_t code_h = 0;
|
||||
uint32_t code_l = 0;
|
||||
uint32_t chk_code = 0;
|
||||
|
||||
for (uint8_t rpt = 0 ; rpt < ADC_HAL_CAL_TIMES ; rpt ++) {
|
||||
code_h = ADC_HAL_CAL_OFFSET_RANGE;
|
||||
code_l = 0;
|
||||
chk_code = (code_h + code_l) / 2;
|
||||
adc_ll_set_calibration_param(adc_n, chk_code);
|
||||
uint32_t self_cal = read_cal_channel(adc_n, channel);
|
||||
while (code_h - code_l > 1) {
|
||||
if (self_cal == 0) {
|
||||
code_h = chk_code;
|
||||
} else {
|
||||
code_l = chk_code;
|
||||
}
|
||||
chk_code = (code_h + code_l) / 2;
|
||||
adc_ll_set_calibration_param(adc_n, chk_code);
|
||||
self_cal = read_cal_channel(adc_n, channel);
|
||||
if ((code_h - code_l == 1)) {
|
||||
chk_code += 1;
|
||||
adc_ll_set_calibration_param(adc_n, chk_code);
|
||||
self_cal = read_cal_channel(adc_n, channel);
|
||||
}
|
||||
}
|
||||
code_list[rpt] = chk_code;
|
||||
code_sum += chk_code;
|
||||
}
|
||||
code_l = code_list[0];
|
||||
code_h = code_list[0];
|
||||
for (uint8_t i = 0 ; i < ADC_HAL_CAL_TIMES ; i++) {
|
||||
if (code_l > code_list[i]) {
|
||||
code_l = code_list[i];
|
||||
}
|
||||
if (code_h < code_list[i]) {
|
||||
code_h = code_list[i];
|
||||
}
|
||||
}
|
||||
chk_code = code_h + code_l;
|
||||
uint32_t ret = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
|
||||
? (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2)
|
||||
: (code_sum - chk_code) / (ADC_HAL_CAL_TIMES - 2) + 1;
|
||||
|
||||
adc_ll_calibration_finish(adc_n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -214,35 +214,6 @@ void adc_hal_digi_monitor_config(adc_ll_num_t adc_n, adc_digi_monitor_t *config)
|
||||
*/
|
||||
void adc_hal_arbiter_config(adc_arbiter_t *config);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
ADC calibration setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Calibrate the ADC using internal connections.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
* @param channel adc channel number.
|
||||
* @param atten The attenuation for the channel
|
||||
* @param internal_gnd true: Disconnect from the IO port and use the internal GND as the calibration voltage.
|
||||
* false: Use IO external voltage as calibration voltage.
|
||||
*
|
||||
* @return
|
||||
* - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
|
||||
*/
|
||||
uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd);
|
||||
|
||||
/**
|
||||
* Set the calibration result (initial data) to ADC.
|
||||
*
|
||||
* @note Different ADC units and different attenuation options use different calibration data (initial data).
|
||||
*
|
||||
* @param adc_n ADC index number.
|
||||
*/
|
||||
#define adc_hal_set_calibration_param(adc_n, param) adc_ll_set_calibration_param(adc_n, param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -690,7 +690,7 @@ static inline void adc_ll_rtc_enable_channel(adc_ll_num_t adc_n, int channel)
|
||||
* @param adc_n ADC unit.
|
||||
* @param channel ADC channel number for each ADCn.
|
||||
*/
|
||||
static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n, int channel)
|
||||
static inline void adc_ll_rtc_disable_channel(adc_ll_num_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
SENS.sar_meas1_ctrl2.sar1_en_pad = 0; //only one channel is selected.
|
||||
@@ -1123,6 +1123,18 @@ static inline void adc_ll_disable_sleep_controller(void)
|
||||
}
|
||||
|
||||
/* ADC calibration code. */
|
||||
/**
|
||||
* @brief Set common calibration configuration. Should be shared with other parts (PWDET).
|
||||
*/
|
||||
static inline void adc_ll_calibration_init(adc_ll_num_t adc_n)
|
||||
{
|
||||
if (adc_n == ADC_NUM_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.
|
||||
*
|
||||
@@ -1143,14 +1155,12 @@ static inline void adc_ll_calibration_prepare(adc_ll_num_t adc_n, adc_channel_t
|
||||
|
||||
/* Enable/disable internal connect GND (for calibration). */
|
||||
if (adc_n == ADC_NUM_1) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR1_DREF_ADDR, 4);
|
||||
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 {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_DREF_ADDR, 4);
|
||||
if (internal_gnd) {
|
||||
REGI2C_WRITE_MASK(I2C_SAR_ADC, ADC_SAR2_ENCAL_GND_ADDR, 1);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user