mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
Merge branch 'bugfix/adc_power_issue' into 'master'
adc: fix adc power issue Closes IDF-2954, WIFI-3453, WIFI-3462, IDFGH-4439, and IDFGH-4887 See merge request espressif/esp-idf!12757
This commit is contained in:
commit
99aaebb5e4
@ -177,7 +177,11 @@ void adc_power_on(void)
|
|||||||
|
|
||||||
static void adc_power_off_internal(void)
|
static void adc_power_off_internal(void)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
adc_hal_set_power_manage(ADC_POWER_SW_OFF);
|
adc_hal_set_power_manage(ADC_POWER_SW_OFF);
|
||||||
|
#else
|
||||||
|
adc_hal_set_power_manage(ADC_POWER_BY_FSM);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_power_release(void)
|
void adc_power_release(void)
|
||||||
|
@ -135,6 +135,7 @@ esp_err_t adc_digi_init(void)
|
|||||||
|
|
||||||
esp_err_t adc_digi_deinit(void)
|
esp_err_t adc_digi_deinit(void)
|
||||||
{
|
{
|
||||||
|
adc_power_release();
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
adc_hal_digi_deinit();
|
adc_hal_digi_deinit();
|
||||||
ADC_EXIT_CRITICAL();
|
ADC_EXIT_CRITICAL();
|
||||||
@ -143,6 +144,8 @@ esp_err_t adc_digi_deinit(void)
|
|||||||
|
|
||||||
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
|
esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
|
||||||
{
|
{
|
||||||
|
/* If enable digital controller, adc xpd should always on. */
|
||||||
|
adc_power_acquire();
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
adc_hal_digi_controller_config(config);
|
adc_hal_digi_controller_config(config);
|
||||||
ADC_EXIT_CRITICAL();
|
ADC_EXIT_CRITICAL();
|
||||||
|
@ -287,6 +287,7 @@ esp_err_t adc_digi_start(void)
|
|||||||
ESP_LOGE(ADC_TAG, "The driver is already started");
|
ESP_LOGE(ADC_TAG, "The driver is already started");
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
adc_power_acquire();
|
||||||
//reset flags
|
//reset flags
|
||||||
s_adc_digi_ctx->ringbuf_overflow_flag = 0;
|
s_adc_digi_ctx->ringbuf_overflow_flag = 0;
|
||||||
s_adc_digi_ctx->driver_start_flag = 1;
|
s_adc_digi_ctx->driver_start_flag = 1;
|
||||||
@ -356,6 +357,7 @@ esp_err_t adc_digi_stop(void)
|
|||||||
if (s_adc_digi_ctx->use_adc2) {
|
if (s_adc_digi_ctx->use_adc2) {
|
||||||
SAR_ADC2_LOCK_RELEASE();
|
SAR_ADC2_LOCK_RELEASE();
|
||||||
}
|
}
|
||||||
|
adc_power_release();
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -450,7 +452,7 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
adc_power_acquire();
|
||||||
if (adc_unit & ADC_UNIT_1) {
|
if (adc_unit & ADC_UNIT_1) {
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
adc_hal_vref_output(ADC_NUM_1, channel, true);
|
adc_hal_vref_output(ADC_NUM_1, channel, true);
|
||||||
@ -495,6 +497,7 @@ int adc1_get_raw(adc1_channel_t channel)
|
|||||||
int raw_out = 0;
|
int raw_out = 0;
|
||||||
|
|
||||||
periph_module_enable(PERIPH_SARADC_MODULE);
|
periph_module_enable(PERIPH_SARADC_MODULE);
|
||||||
|
adc_power_acquire();
|
||||||
|
|
||||||
SAR_ADC1_LOCK_ACQUIRE();
|
SAR_ADC1_LOCK_ACQUIRE();
|
||||||
|
|
||||||
@ -503,14 +506,13 @@ int adc1_get_raw(adc1_channel_t channel)
|
|||||||
adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
|
adc_hal_set_calibration_param(ADC_NUM_1, cal_val);
|
||||||
|
|
||||||
ADC_REG_LOCK_ENTER();
|
ADC_REG_LOCK_ENTER();
|
||||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
|
||||||
adc_hal_set_atten(ADC_NUM_2, channel, atten);
|
adc_hal_set_atten(ADC_NUM_2, channel, atten);
|
||||||
adc_hal_convert(ADC_NUM_1, channel, &raw_out);
|
adc_hal_convert(ADC_NUM_1, channel, &raw_out);
|
||||||
adc_hal_set_power_manage(ADC_POWER_BY_FSM);
|
|
||||||
ADC_REG_LOCK_EXIT();
|
ADC_REG_LOCK_EXIT();
|
||||||
|
|
||||||
SAR_ADC1_LOCK_RELEASE();
|
SAR_ADC1_LOCK_RELEASE();
|
||||||
|
|
||||||
|
adc_power_release();
|
||||||
periph_module_disable(PERIPH_SARADC_MODULE);
|
periph_module_disable(PERIPH_SARADC_MODULE);
|
||||||
|
|
||||||
return raw_out;
|
return raw_out;
|
||||||
@ -540,6 +542,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
|||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
periph_module_enable(PERIPH_SARADC_MODULE);
|
periph_module_enable(PERIPH_SARADC_MODULE);
|
||||||
|
adc_power_acquire();
|
||||||
|
|
||||||
SAR_ADC2_LOCK_ACQUIRE();
|
SAR_ADC2_LOCK_ACQUIRE();
|
||||||
|
|
||||||
@ -548,14 +551,13 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
|||||||
adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
|
adc_hal_set_calibration_param(ADC_NUM_2, cal_val);
|
||||||
|
|
||||||
ADC_REG_LOCK_ENTER();
|
ADC_REG_LOCK_ENTER();
|
||||||
adc_hal_set_power_manage(ADC_POWER_SW_ON);
|
|
||||||
adc_hal_set_atten(ADC_NUM_2, channel, atten);
|
adc_hal_set_atten(ADC_NUM_2, channel, atten);
|
||||||
ret = adc_hal_convert(ADC_NUM_2, channel, raw_out);
|
ret = adc_hal_convert(ADC_NUM_2, channel, raw_out);
|
||||||
adc_hal_set_power_manage(ADC_POWER_BY_FSM);
|
|
||||||
ADC_REG_LOCK_EXIT();
|
ADC_REG_LOCK_EXIT();
|
||||||
|
|
||||||
SAR_ADC2_LOCK_RELEASE();
|
SAR_ADC2_LOCK_RELEASE();
|
||||||
|
|
||||||
|
adc_power_release();
|
||||||
periph_module_disable(PERIPH_SARADC_MODULE);
|
periph_module_disable(PERIPH_SARADC_MODULE);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -89,6 +89,7 @@ esp_err_t adc_digi_deinit(void)
|
|||||||
s_adc_digi_arbiter_lock = NULL;
|
s_adc_digi_arbiter_lock = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
adc_power_release();
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
adc_hal_digi_deinit();
|
adc_hal_digi_deinit();
|
||||||
ADC_EXIT_CRITICAL();
|
ADC_EXIT_CRITICAL();
|
||||||
@ -124,6 +125,8 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If enable digtal controller, adc xpd should always on. */
|
||||||
|
adc_power_acquire();
|
||||||
ADC_ENTER_CRITICAL();
|
ADC_ENTER_CRITICAL();
|
||||||
adc_hal_digi_controller_config(config);
|
adc_hal_digi_controller_config(config);
|
||||||
ADC_EXIT_CRITICAL();
|
ADC_EXIT_CRITICAL();
|
||||||
|
@ -43,10 +43,6 @@ void adc_hal_init(void)
|
|||||||
adc_ll_digi_set_clk_div(SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT);
|
adc_ll_digi_set_clk_div(SOC_ADC_DIGI_SAR_CLK_DIV_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_hal_deinit(void)
|
|
||||||
{
|
|
||||||
adc_ll_set_power_manage(ADC_POWER_SW_OFF);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
ADC calibration setting
|
ADC calibration setting
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
@ -381,6 +377,8 @@ esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw)
|
|||||||
adc_hal_onetime_start();
|
adc_hal_onetime_start();
|
||||||
while (!adc_hal_intr_get_raw(event));
|
while (!adc_hal_intr_get_raw(event));
|
||||||
ret = adc_hal_single_read(adc_n, out_raw);
|
ret = adc_hal_single_read(adc_n, out_raw);
|
||||||
|
//HW workaround: when enabling periph clock, this should be false
|
||||||
|
adc_ll_onetime_sample_enable(adc_n, false);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,10 @@ void adc_hal_digi_deinit(void)
|
|||||||
{
|
{
|
||||||
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
adc_ll_digi_clear_pattern_table(ADC_NUM_1);
|
||||||
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
adc_ll_digi_clear_pattern_table(ADC_NUM_2);
|
||||||
adc_hal_deinit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
||||||
{
|
{
|
||||||
/* If enable digital controller, adc xpd should always on. */
|
|
||||||
adc_ll_set_power_manage(ADC_POWER_SW_ON);
|
|
||||||
/* Single channel mode or multi channel mode. */
|
/* Single channel mode or multi channel mode. */
|
||||||
adc_ll_digi_set_convert_mode(cfg->conv_mode);
|
adc_ll_digi_set_convert_mode(cfg->conv_mode);
|
||||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
||||||
|
@ -42,7 +42,6 @@ void adc_hal_digi_deinit(void)
|
|||||||
adc_ll_digi_filter_reset(ADC_NUM_2);
|
adc_ll_digi_filter_reset(ADC_NUM_2);
|
||||||
adc_ll_digi_reset();
|
adc_ll_digi_reset();
|
||||||
adc_ll_digi_controller_clk_disable();
|
adc_ll_digi_controller_clk_disable();
|
||||||
adc_hal_deinit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,8 +61,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
|||||||
//only one pattern table is supported on C3, but LL still needs one argument.
|
//only one pattern table is supported on C3, but LL still needs one argument.
|
||||||
const int pattern_both = 0;
|
const int pattern_both = 0;
|
||||||
|
|
||||||
/* If enable digtal controller, adc xpd should always on. */
|
|
||||||
adc_ll_set_power_manage(ADC_POWER_SW_ON);
|
|
||||||
if (cfg->adc_pattern_len) {
|
if (cfg->adc_pattern_len) {
|
||||||
adc_ll_digi_clear_pattern_table(pattern_both);
|
adc_ll_digi_clear_pattern_table(pattern_both);
|
||||||
adc_ll_digi_set_pattern_table_len(pattern_both, cfg->adc_pattern_len);
|
adc_ll_digi_set_pattern_table_len(pattern_both, cfg->adc_pattern_len);
|
||||||
|
@ -33,13 +33,10 @@ void adc_hal_digi_deinit(void)
|
|||||||
adc_ll_digi_filter_reset(ADC_NUM_2);
|
adc_ll_digi_filter_reset(ADC_NUM_2);
|
||||||
adc_ll_digi_reset();
|
adc_ll_digi_reset();
|
||||||
adc_ll_digi_controller_clk_disable();
|
adc_ll_digi_controller_clk_disable();
|
||||||
adc_hal_deinit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
void adc_hal_digi_controller_config(const adc_digi_config_t *cfg)
|
||||||
{
|
{
|
||||||
/* If enable digtal controller, adc xpd should always on. */
|
|
||||||
adc_ll_set_power_manage(ADC_POWER_SW_ON);
|
|
||||||
/* Single channel mode or multi channel mode. */
|
/* Single channel mode or multi channel mode. */
|
||||||
adc_ll_digi_set_convert_mode(cfg->conv_mode);
|
adc_ll_digi_set_convert_mode(cfg->conv_mode);
|
||||||
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
if (cfg->conv_mode & ADC_CONV_SINGLE_UNIT_1) {
|
||||||
|
@ -61,11 +61,6 @@ typedef struct adc_hal_context_t {
|
|||||||
*/
|
*/
|
||||||
void adc_hal_init(void);
|
void adc_hal_init(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* ADC module deinitialization.
|
|
||||||
*/
|
|
||||||
void adc_hal_deinit(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set ADC module power management.
|
* Set ADC module power management.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user