ソースを参照

adc_digi: update_adc_api_for_5M_freq_limit

The ``adc_digi_config_t`` struct is modified on esp32c3: configuration
of clock divider factors are not provided anymore. The SARADC sampling
frequency is provided instead. In this way, we can handle the frequency
limit better.
Armando 5 年 前
コミット
d8a4b247b9

+ 13 - 20
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;

+ 1 - 0
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);

+ 1 - 5
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;

+ 1 - 1
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

+ 9 - 15
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);
 }
 
 /**

+ 2 - 2
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.

+ 10 - 6
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)
 {

+ 4 - 4
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)
 {

+ 8 - 1
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;   /*!<Pointer to pattern table for digital controller. The table size defined by `adc_pattern_len`. */
 #endif
-#if !CONFIG_IDF_TARGET_ESP32
+#if CONFIG_IDF_TARGET_ESP32S2
     uint32_t interval;                       /*!<The number of interval clock cycles for the digital controller to trigger the measurement.
                                                  The unit is the divided clock. Range: 40 ~ 4095.
                                                  Expression: `trigger_meas_freq` = `controller_clk` / 2 / interval. Refer to ``adc_digi_clk_t``.
@@ -285,6 +285,13 @@ typedef struct {
     uint32_t dma_eof_num;                    /*!<DMA eof num of adc digital controller.
                                                  If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated in DMA.
                                                  Note: The converted data in the DMA in link buffer will be multiple of two bytes. */
+#elif CONFIG_IDF_TARGET_ESP32C3
+    uint32_t sample_freq_hz;  /*!< The expected ADC sampling frequency in Hz. Range: 610Hz ~ 83333Hz
+                                   Fs: sampling frequency;
+                                   Fd: digital controller frequency
+                                   interval: interval between 2 measurement trigger signal
+                                   Fs = Fd / interval / 2
+                                   Range: the smallest interval should not be smaller than the ADC measurement period. The largest interval should not be larger than 4095. */
 #endif
 } adc_digi_config_t;
 

+ 1 - 5
examples/peripherals/adc/adc_dma/main/adc_dma_example_main.c

@@ -28,11 +28,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;