diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index 9fbcc3d720..05fc107f9a 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -97,7 +97,6 @@ typedef struct adc_digi_context_t { adc_digi_config_t digi_controller_config; //Digital Controller Configuration } adc_digi_context_t; -static const char* ADC_DMA_TAG = "ADC_DMA:"; static adc_digi_context_t *s_adc_digi_ctx = NULL; static uint32_t adc_get_calibration_offset(adc_ll_num_t adc_n, adc_channel_t chan, adc_atten_t atten); @@ -344,7 +343,7 @@ esp_err_t adc_digi_read_bytes(uint8_t *buf, uint32_t length_max, uint32_t *out_l data = xRingbufferReceiveUpTo(s_adc_digi_ctx->ringbuf_hdl, &size, ticks_to_wait, length_max); if (!data) { - ESP_LOGV(ADC_DMA_TAG, "No data, increase timeout or reduce conv_num_each_intr"); + ESP_LOGV(ADC_TAG, "No data, increase timeout or reduce conv_num_each_intr"); ret = ESP_ERR_TIMEOUT; *out_length = 0; return ret; @@ -428,11 +427,7 @@ int adc1_get_raw(adc1_channel_t channel) adc_digi_config_t dig_cfg = { .conv_limit_en = 0, .conv_limit_num = 250, - .interval = 40, - .dig_clk.use_apll = 0, - .dig_clk.div_num = 15, - .dig_clk.div_a = 0, - .dig_clk.div_b = 1, + .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, }; ADC_DIGI_LOCK_ACQUIRE(); @@ -489,11 +484,7 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * adc_digi_config_t dig_cfg = { .conv_limit_en = 0, .conv_limit_num = 250, - .interval = 40, - .dig_clk.use_apll = 0, - .dig_clk.div_num = 15, - .dig_clk.div_a = 0, - .dig_clk.div_b = 1, + .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, }; SAC_ADC2_LOCK_ACQUIRE(); @@ -540,32 +531,34 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config) if (!s_adc_digi_ctx) { return ESP_ERR_INVALID_STATE; } + ADC_CHECK(config->sample_freq_hz <= 83333 && config->sample_freq_hz >= 610, "ADC sampling frequency out of range", ESP_ERR_INVALID_ARG); s_adc_digi_ctx->digi_controller_config.conv_limit_en = config->conv_limit_en; s_adc_digi_ctx->digi_controller_config.conv_limit_num = config->conv_limit_num; s_adc_digi_ctx->digi_controller_config.adc_pattern_len = config->adc_pattern_len; - s_adc_digi_ctx->digi_controller_config.interval = config->interval; - s_adc_digi_ctx->digi_controller_config.dig_clk = config-> dig_clk; - s_adc_digi_ctx->digi_controller_config.dma_eof_num = config->dma_eof_num; + s_adc_digi_ctx->digi_controller_config.sample_freq_hz = config->sample_freq_hz; memcpy(s_adc_digi_ctx->digi_controller_config.adc_pattern, config->adc_pattern, config->adc_pattern_len * sizeof(adc_digi_pattern_table_t)); - //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver - s_adc_digi_ctx->adc1_atten = ADC_ATTEN_MAX; - s_adc_digi_ctx->adc2_atten = ADC_ATTEN_MAX; + const int atten_uninitialised = 999; + s_adc_digi_ctx->adc1_atten = atten_uninitialised; + s_adc_digi_ctx->adc2_atten = atten_uninitialised; s_adc_digi_ctx->use_adc1 = 0; s_adc_digi_ctx->use_adc2 = 0; for (int i = 0; i < config->adc_pattern_len; i++) { const adc_digi_pattern_table_t* pat = &config->adc_pattern[i]; if (pat->unit == ADC_NUM_1) { s_adc_digi_ctx->use_adc1 = 1; - if (s_adc_digi_ctx->adc1_atten == ADC_ATTEN_MAX) { + + if (s_adc_digi_ctx->adc1_atten == atten_uninitialised) { s_adc_digi_ctx->adc1_atten = pat->atten; } else if (s_adc_digi_ctx->adc1_atten != pat->atten) { return ESP_ERR_INVALID_ARG; } } else if (pat->unit == ADC_NUM_2) { + //See whether ADC2 will be used or not. If yes, the ``sar_adc2_mutex`` should be acquired in the continuous read driver s_adc_digi_ctx->use_adc2 = 1; - if (s_adc_digi_ctx->adc2_atten == ADC_ATTEN_MAX) { + + if (s_adc_digi_ctx->adc2_atten == atten_uninitialised) { s_adc_digi_ctx->adc2_atten = pat->atten; } else if (s_adc_digi_ctx->adc2_atten != pat->atten) { return ESP_ERR_INVALID_ARG; diff --git a/components/driver/include/driver/adc_common.h b/components/driver/include/driver/adc_common.h index 2ac5110c43..52b7d60c38 100644 --- a/components/driver/include/driver/adc_common.h +++ b/components/driver/include/driver/adc_common.h @@ -477,6 +477,7 @@ esp_err_t adc_digi_deinit(void); * * @return * - ESP_ERR_INVALID_STATE Driver state is invalid. + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. * - ESP_OK On success */ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config); diff --git a/components/driver/test/test_adc_dma.c b/components/driver/test/test_adc_dma.c index 04d2c4c57a..d9504cd6d4 100644 --- a/components/driver/test/test_adc_dma.c +++ b/components/driver/test/test_adc_dma.c @@ -132,11 +132,7 @@ static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask adc_digi_config_t dig_cfg = { .conv_limit_en = 0, .conv_limit_num = 250, - .interval = 40, - .dig_clk.use_apll = 0, - .dig_clk.div_num = 15, - .dig_clk.div_a = 0, - .dig_clk.div_b = 1, + .sample_freq_hz = 83333, }; dig_cfg.adc_pattern_len = channel_num; diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index a04f31d694..4cb8922a86 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -145,7 +145,7 @@ void adc_hal_onetime_start(adc_digi_config_t *adc_digi_config) * This limitation will be removed in hardware future versions. * */ - uint32_t digi_clk = APB_CLK_FREQ / (adc_digi_config->dig_clk.div_num + adc_digi_config->dig_clk.div_a / adc_digi_config->dig_clk.div_b + 1); + 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); //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 diff --git a/components/hal/esp32c3/adc_hal.c b/components/hal/esp32c3/adc_hal.c index 8f7b2678fd..105dff6490 100644 --- a/components/hal/esp32c3/adc_hal.c +++ b/components/hal/esp32c3/adc_hal.c @@ -18,6 +18,7 @@ #include "soc/soc_caps.h" #include "hal/adc_hal.h" #include "hal/adc_types.h" +#include "soc/soc.h" //Currently we don't have context for the ADC HAL. So HAL variables are temporarily put here. But //please don't follow this code. Create a context for your own HAL! @@ -67,24 +68,17 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg) adc_ll_digi_convert_limit_disable(); } - adc_ll_digi_set_trigger_interval(cfg->interval); - adc_hal_digi_clk_config(&cfg->dig_clk); + //clock + uint32_t interval = APB_CLK_FREQ / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_A_DEFAULT / ADC_LL_CLKM_DIV_B_DEFAULT + 1) / 2 / cfg->sample_freq_hz; + adc_ll_digi_set_trigger_interval(interval); + adc_hal_digi_clk_config(); } -/** - * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. - * Enable clock and select clock source for ADC digital controller. - * Expression: controller_clk = APLL/APB * (div_num + div_b / div_a). - * - * @note ADC and DAC digital controller share the same frequency divider. - * Please set a reasonable frequency division factor to meet the sampling frequency of the ADC and the output frequency of the DAC. - * - * @param clk Refer to ``adc_digi_clk_t``. - */ -void adc_hal_digi_clk_config(const adc_digi_clk_t *clk) +void adc_hal_digi_clk_config(void) { - adc_ll_digi_controller_clk_div(clk->div_num, clk->div_b, clk->div_a); - adc_ll_digi_controller_clk_enable(clk->use_apll); + //Here we set the clock divider factor to make the digital clock to 5M Hz + adc_ll_digi_controller_clk_div(ADC_LL_CLKM_DIV_NUM_DEFAULT, ADC_LL_CLKM_DIV_B_DEFAULT, ADC_LL_CLKM_DIV_A_DEFAULT); + adc_ll_digi_controller_clk_enable(0); } /** diff --git a/components/hal/esp32c3/include/hal/adc_hal.h b/components/hal/esp32c3/include/hal/adc_hal.h index 0b53e44f54..122d438d3e 100644 --- a/components/hal/esp32c3/include/hal/adc_hal.h +++ b/components/hal/esp32c3/include/hal/adc_hal.h @@ -75,11 +75,11 @@ void adc_hal_digi_disable(void); /** * Set ADC digital controller clock division factor. The clock divided from `APLL` or `APB` clock. * Enable clock and select clock source for ADC digital controller. - * Expression: controller_clk = APLL/APB * (div_num + div_b / div_a). + * Expression: controller_clk = APLL/APB * (div_num + div_a / div_b + 1). * * @param clk Refer to `adc_digi_clk_t`. */ -void adc_hal_digi_clk_config(const adc_digi_clk_t *clk); +void adc_hal_digi_clk_config(void); /** * Reset adc digital controller filter. diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index ee9da0a907..913b59ed35 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -29,7 +29,10 @@ extern "C" { #endif -#define ADC_LL_ADC2_CHANNEL_MAX 1 +#define ADC_LL_ADC2_CHANNEL_MAX 1 +#define ADC_LL_CLKM_DIV_NUM_DEFAULT 15 +#define ADC_LL_CLKM_DIV_B_DEFAULT 1 +#define ADC_LL_CLKM_DIV_A_DEFAULT 0 typedef enum { ADC_NUM_1 = 0, /*!< SAR ADC 1 */ @@ -180,8 +183,8 @@ static inline void adc_ll_digi_set_pattern_table(adc_ll_num_t adc_n, uint32_t pa uint8_t offset = (pattern_index % 4) * 6; tab = APB_SARADC.sar_patt_tab[index].sar_patt_tab1; // Read old register value - tab &= (~(0xFC0000 >> offset)); // clear old data - tab |= ((uint32_t)pattern.val << 18) >> offset; // Fill in the new data + tab &= (~(0xFC0000 >> offset)); // Clear old data + tab |= ((uint32_t)(pattern.val & 0x3F) << 18) >> offset; // Fill in the new data APB_SARADC.sar_patt_tab[index].sar_patt_tab1 = tab; // Write back } @@ -223,10 +226,11 @@ static inline void adc_ll_digi_output_invert(adc_ll_num_t adc_n, bool inv_en) } /** - * Sets the number of interval clock cycles for the digital controller to trigger the measurement. + * Set the interval clock cycle for the digital controller to trigger the measurement. + * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. * - * @note The trigger interval should not be less than the sampling time of the SAR ADC. - * @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095. + * @note The trigger interval should not be smaller than the sampling time of the SAR ADC. + * @param cycle The clock cycle (trigger interval) of the measurement. Range: 30 ~ 4095. */ static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle) { diff --git a/components/hal/esp32s2/include/hal/adc_ll.h b/components/hal/esp32s2/include/hal/adc_ll.h index 7eedf5b936..1d306db61a 100644 --- a/components/hal/esp32s2/include/hal/adc_ll.h +++ b/components/hal/esp32s2/include/hal/adc_ll.h @@ -268,11 +268,11 @@ static inline void adc_ll_digi_output_invert(adc_ll_num_t adc_n, bool inv_en) } /** - * Sets the number of interval clock cycles for the digital controller to trigger the measurement. - * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. Refer to ``adc_digi_clk_t``. + * Set the interval clock cycle for the digital controller to trigger the measurement. + * Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. * - * @note The trigger interval should not be less than the sampling time of the SAR ADC. - * @param cycle The number of clock cycles for the trigger interval. The unit is the divided clock. Range: 40 ~ 4095. + * @note The trigger interval should be larger than the sampling time of the SAR ADC. + * @param cycle The clock cycle (trigger interval) of the measurement. Range: 40 ~ 4095. */ static inline void adc_ll_digi_set_trigger_interval(uint32_t cycle) { diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index a35ff1959a..9d73c0de4b 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -275,7 +275,7 @@ typedef struct { pattern table one by one. For each controller the scan sequence has at most 16 different rules before repeating itself. */ adc_digi_pattern_table_t *adc_pattern; /*!