mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 12:35:28 +00:00
adc: fixed efuse called in critical section issue
This commit is contained in:
@@ -40,12 +40,6 @@ void adc_hal_digi_deinit(void)
|
||||
adc_hal_deinit();
|
||||
}
|
||||
|
||||
static inline void adc_set_init_code(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten)
|
||||
{
|
||||
uint32_t cal_val = adc_hal_calibration(adc_n, channel, atten, true, false);
|
||||
adc_hal_set_calibration_param(adc_n, cal_val);
|
||||
}
|
||||
|
||||
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
||||
{
|
||||
/* If enable digtal controller, adc xpd should always on. */
|
||||
@@ -58,7 +52,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_1, cfg->adc1_pattern_len);
|
||||
for (int i = 0; i < cfg->adc1_pattern_len; i++) {
|
||||
adc_ll_digi_set_pattern_table(ADC_NUM_1, i, cfg->adc1_pattern[i]);
|
||||
adc_set_init_code(ADC_NUM_1, cfg->adc1_pattern[i].channel, cfg->adc1_pattern[i].atten);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,7 +61,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
||||
adc_ll_digi_set_pattern_table_len(ADC_NUM_2, cfg->adc2_pattern_len);
|
||||
for (int i = 0; i < cfg->adc2_pattern_len; i++) {
|
||||
adc_ll_digi_set_pattern_table(ADC_NUM_2, i, cfg->adc2_pattern[i]);
|
||||
adc_set_init_code(ADC_NUM_2, cfg->adc2_pattern[i].channel, cfg->adc2_pattern[i].atten);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,44 +154,27 @@ void adc_hal_arbiter_config(adc_arbiter_t *config)
|
||||
/*---------------------------------------------------------------
|
||||
ADC calibration setting
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
#define ADC_HAL_CAL_OFFSET_RANGE (4096)
|
||||
#define ADC_HAL_CAL_TIMES (10)
|
||||
#define ADC_HAL_CAL_OFFSET_RANGE (4096)
|
||||
|
||||
static uint16_t s_adc_cali_param[ADC_NUM_MAX][ADC_ATTEN_MAX] = { {0}, {0} };
|
||||
|
||||
static uint32_t adc_hal_read_self_cal(adc_ll_num_t adc_n, int channel)
|
||||
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_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal)
|
||||
uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd)
|
||||
{
|
||||
if (!force_cal) {
|
||||
if (s_adc_cali_param[adc_n][atten]) {
|
||||
return (uint32_t)s_adc_cali_param[adc_n][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;
|
||||
uint32_t dout = 0;
|
||||
|
||||
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_hal_arbiter_config(adc_arbiter_t *config)
|
||||
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);
|
||||
@@ -209,25 +184,31 @@ uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atte
|
||||
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);
|
||||
dout = adc_hal_read_self_cal(adc_n, channel);
|
||||
uint32_t self_cal = read_cal_channel(adc_n, channel);
|
||||
while (code_h - code_l > 1) {
|
||||
if (dout == 0) {
|
||||
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);
|
||||
dout = adc_hal_read_self_cal(adc_n, channel);
|
||||
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);
|
||||
dout = adc_hal_read_self_cal(adc_n, channel);
|
||||
self_cal = read_cal_channel(adc_n, channel);
|
||||
}
|
||||
}
|
||||
code_list[rpt] = chk_code;
|
||||
@@ -244,12 +225,10 @@ uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atte
|
||||
}
|
||||
}
|
||||
chk_code = code_h + code_l;
|
||||
dout = ((code_sum - chk_code) % (ADC_HAL_CAL_TIMES - 2) < 4)
|
||||
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_set_calibration_param(adc_n, dout);
|
||||
adc_ll_calibration_finish(adc_n);
|
||||
s_adc_cali_param[adc_n][atten] = (uint16_t)dout;
|
||||
return dout;
|
||||
return ret;
|
||||
}
|
||||
|
@@ -232,21 +232,20 @@ void adc_hal_arbiter_config(adc_arbiter_t *config);
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Calibrate the ADC according to the parameters.
|
||||
* 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.
|
||||
* @param force_cal true: Do not use the results that have already been verified, and perform the verification again. It will take a long time.
|
||||
* false: Use the result of the last calibration.
|
||||
*
|
||||
* @return
|
||||
* - The calibration result (initial data) to ADC, use `adc_hal_set_calibration_param` to set.
|
||||
*/
|
||||
uint32_t adc_hal_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd, bool force_cal);
|
||||
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.
|
||||
|
Reference in New Issue
Block a user