mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-22 09:01:08 +00:00
esp_adc: support h2 oneshot mode and continuous mode
This commit is contained in:
@@ -101,7 +101,9 @@ static esp_pm_lock_handle_t s_adc2_arbiter_lock;
|
||||
#endif //CONFIG_PM_ENABLE
|
||||
#endif // !CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
static esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, int *out_raw);
|
||||
static uint32_t clk_src_freq_hz;
|
||||
|
||||
static esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, uint32_t clk_src_freq_hz, int *out_raw);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
ADC Common
|
||||
@@ -276,6 +278,13 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
|
||||
ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_1), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel");
|
||||
ESP_RETURN_ON_FALSE(atten < SOC_ADC_ATTEN_NUM, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC Atten Err");
|
||||
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
if (!clk_src_freq_hz) {
|
||||
esp_err_t ret = clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
|
||||
adc_common_gpio_init(ADC_UNIT_1, channel);
|
||||
SARADC1_ENTER();
|
||||
adc_rtc_chan_init(ADC_UNIT_1);
|
||||
@@ -387,7 +396,7 @@ int adc1_get_raw(adc1_channel_t channel)
|
||||
#endif
|
||||
adc_ll_set_controller(ADC_UNIT_1, ADC_LL_CTRL_RTC); //Set controller
|
||||
adc_oneshot_ll_set_channel(ADC_UNIT_1, channel);
|
||||
adc_hal_convert(ADC_UNIT_1, channel, &adc_value); //Start conversion, For ADC1, the data always valid.
|
||||
adc_hal_convert(ADC_UNIT_1, channel, clk_src_freq_hz, &adc_value); //Start conversion, For ADC1, the data always valid.
|
||||
#if !CONFIG_IDF_TARGET_ESP32
|
||||
adc_ll_rtc_reset(); //Reset FSM of rtc controller
|
||||
#endif
|
||||
@@ -428,6 +437,12 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(ADC_UNIT_2), ESP_ERR_INVALID_ARG, ADC_TAG, "invalid channel");
|
||||
ESP_RETURN_ON_FALSE(atten <= SOC_ADC_ATTEN_NUM, ESP_ERR_INVALID_ARG, ADC_TAG, "ADC2 Atten Err");
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
if (!clk_src_freq_hz) {
|
||||
esp_err_t ret = clk_tree_src_get_freq_hz(ADC_DIGI_CLK_SRC_DEFAULT, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz);
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
|
||||
adc_common_gpio_init(ADC_UNIT_2, channel);
|
||||
|
||||
@@ -572,7 +587,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
adc_oneshot_ll_set_channel(ADC_UNIT_2, channel);
|
||||
ret = adc_hal_convert(ADC_UNIT_2, channel, &adc_value);
|
||||
ret = adc_hal_convert(ADC_UNIT_2, channel, clk_src_freq_hz, &adc_value);
|
||||
if (ret != ESP_OK) {
|
||||
adc_value = -1;
|
||||
}
|
||||
@@ -766,7 +781,7 @@ int adc1_get_raw(adc1_channel_t channel)
|
||||
|
||||
ADC_REG_LOCK_ENTER();
|
||||
adc_oneshot_ll_set_atten(ADC_UNIT_1, channel, atten);
|
||||
adc_hal_convert(ADC_UNIT_1, channel, &raw_out);
|
||||
adc_hal_convert(ADC_UNIT_1, channel, clk_src_freq_hz, &raw_out);
|
||||
ADC_REG_LOCK_EXIT();
|
||||
|
||||
sar_periph_ctrl_adc_oneshot_power_release();
|
||||
@@ -820,7 +835,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
||||
|
||||
ADC_REG_LOCK_ENTER();
|
||||
adc_oneshot_ll_set_atten(ADC_UNIT_2, channel, atten);
|
||||
ret = adc_hal_convert(ADC_UNIT_2, channel, raw_out);
|
||||
ret = adc_hal_convert(ADC_UNIT_2, channel, clk_src_freq_hz, raw_out);
|
||||
ADC_REG_LOCK_EXIT();
|
||||
|
||||
sar_periph_ctrl_adc_oneshot_power_release();
|
||||
@@ -833,7 +848,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *
|
||||
#endif //#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
|
||||
|
||||
static void adc_hal_onetime_start(adc_unit_t adc_n)
|
||||
static void adc_hal_onetime_start(adc_unit_t adc_n, uint32_t clk_src_freq_hz)
|
||||
{
|
||||
#if SOC_ADC_DIG_CTRL_SUPPORTED && !SOC_ADC_RTC_CTRL_SUPPORTED
|
||||
(void)adc_n;
|
||||
@@ -841,16 +856,13 @@ static void adc_hal_onetime_start(adc_unit_t adc_n)
|
||||
* There is a hardware limitation. If the APB clock frequency is high, the step of this reg signal: ``onetime_start`` may not be captured by the
|
||||
* ADC digital controller (when its clock frequency is too slow). A rough estimate for this step should be at least 3 ADC digital controller
|
||||
* clock cycle.
|
||||
*
|
||||
* This limitation will be removed in hardware future versions.
|
||||
*
|
||||
*/
|
||||
uint32_t digi_clk = APB_CLK_FREQ / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1);
|
||||
uint32_t digi_clk = clk_src_freq_hz / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1);
|
||||
//Convert frequency to time (us). Since decimals are removed by this division operation. Add 1 here in case of the fact that delay is not enough.
|
||||
uint32_t delay = (1000 * 1000) / digi_clk + 1;
|
||||
//3 ADC digital controller clock cycle
|
||||
delay = delay * 3;
|
||||
//This coefficient (8) is got from test. When digi_clk is not smaller than ``APB_CLK_FREQ/8``, no delay is needed.
|
||||
//This coefficient (8) is got from test, and verified from DT. When digi_clk is not smaller than ``APB_CLK_FREQ/8``, no delay is needed.
|
||||
if (digi_clk >= APB_CLK_FREQ/8) {
|
||||
delay = 0;
|
||||
}
|
||||
@@ -861,19 +873,21 @@ static void adc_hal_onetime_start(adc_unit_t adc_n)
|
||||
|
||||
//No need to delay here. Becuase if the start signal is not seen, there won't be a done intr.
|
||||
#else
|
||||
(void)clk_src_freq_hz;
|
||||
adc_oneshot_ll_start(adc_n);
|
||||
#endif
|
||||
}
|
||||
|
||||
static esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, int *out_raw)
|
||||
static esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, uint32_t clk_src_freq_hz, int *out_raw)
|
||||
{
|
||||
|
||||
uint32_t event = (adc_n == ADC_UNIT_1) ? ADC_LL_EVENT_ADC1_ONESHOT_DONE : ADC_LL_EVENT_ADC2_ONESHOT_DONE;
|
||||
adc_oneshot_ll_clear_event(event);
|
||||
adc_oneshot_ll_disable_all_unit();
|
||||
adc_oneshot_ll_enable(adc_n);
|
||||
adc_oneshot_ll_set_channel(adc_n, channel);
|
||||
|
||||
adc_hal_onetime_start(adc_n);
|
||||
adc_hal_onetime_start(adc_n, clk_src_freq_hz);
|
||||
|
||||
while (adc_oneshot_ll_get_event(event) != true) {
|
||||
;
|
||||
|
Reference in New Issue
Block a user