From ce465c057474f9cde50d46bb0fbb668bd88b5495 Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 20 Jul 2022 14:49:35 +0800 Subject: [PATCH 1/3] adc: fix esp32s3 continuous mode output bits issue Prior to this change, esp32s3 ADC continuous mode output resolution is 13 bits. This commit correct the `adc_digi_output_data_t` on esp32s3. Correct output bits should be 12 bits. Corresponding definition in `soc_caps.h` is also updated. --- components/hal/include/hal/adc_types.h | 3 ++- components/soc/esp32c3/include/soc/adc_channel.h | 10 +++++----- components/soc/esp32s3/include/soc/soc_caps.h | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index f5efb1d427..3019cd116c 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -161,7 +161,8 @@ typedef struct { typedef struct { union { struct { - uint32_t data: 13; /*! ADC_CHANNEL_MAX), The data is invalid. */ diff --git a/components/soc/esp32c3/include/soc/adc_channel.h b/components/soc/esp32c3/include/soc/adc_channel.h index 9a645006c4..49f3ca9cb7 100644 --- a/components/soc/esp32c3/include/soc/adc_channel.h +++ b/components/soc/esp32c3/include/soc/adc_channel.h @@ -15,19 +15,19 @@ #ifndef _SOC_ADC_CHANNEL_H #define _SOC_ADC_CHANNEL_H -#define ADC1_GPIO1_CHANNEL ADC1_CHANNEL_0 +#define ADC1_GPIO0_CHANNEL ADC1_CHANNEL_0 #define ADC1_CHANNEL_0_GPIO_NUM 0 -#define ADC1_GPIO2_CHANNEL ADC1_CHANNEL_1 +#define ADC1_GPIO1_CHANNEL ADC1_CHANNEL_1 #define ADC1_CHANNEL_1_GPIO_NUM 1 -#define ADC1_GPIO3_CHANNEL ADC1_CHANNEL_2 +#define ADC1_GPIO2_CHANNEL ADC1_CHANNEL_2 #define ADC1_CHANNEL_2_GPIO_NUM 2 -#define ADC1_GPIO4_CHANNEL ADC1_CHANNEL_3 +#define ADC1_GPIO3_CHANNEL ADC1_CHANNEL_3 #define ADC1_CHANNEL_3_GPIO_NUM 3 -#define ADC1_GPIO5_CHANNEL ADC1_CHANNEL_4 +#define ADC1_GPIO4_CHANNEL ADC1_CHANNEL_4 #define ADC1_CHANNEL_4_GPIO_NUM 4 #define ADC2_GPIO5_CHANNEL ADC2_CHANNEL_0 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index ac63ebc643..53d385e067 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -56,7 +56,7 @@ /*!< Digital */ #define SOC_ADC_DIGI_CONTROLLER_NUM (2) #define SOC_ADC_PATT_LEN_MAX (24) //Two pattern table, each contains 12 items. Each item takes 1 byte -#define SOC_ADC_DIGI_MAX_BITWIDTH (13) +#define SOC_ADC_DIGI_MAX_BITWIDTH (12) /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */ #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH 83333 #define SOC_ADC_SAMPLE_FREQ_THRES_LOW 611 From ad8862fa19bcd6e0d7643213adaf52a37c4bddfd Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 20 Jul 2022 15:01:31 +0800 Subject: [PATCH 2/3] adc: fix esp32s2 continuous mode converted bytes issue When working in continuous mode, hardware will continuously trigger ADC to do conversions. On esp32s2, 2 bytes will be generated per conversion. Prior to this commit, driver assumes 4 bytes per conversion (on s2). This commit fixed this issue. --- components/driver/adc.c | 2 +- components/hal/adc_hal.c | 2 +- components/hal/include/hal/adc_hal.h | 3 --- components/soc/esp32/include/soc/soc_caps.h | 2 ++ components/soc/esp32c3/include/soc/soc_caps.h | 2 ++ components/soc/esp32h2/include/soc/soc_caps.h | 2 ++ components/soc/esp32s2/include/soc/soc_caps.h | 2 ++ components/soc/esp32s3/include/soc/soc_caps.h | 2 ++ 8 files changed, 12 insertions(+), 5 deletions(-) diff --git a/components/driver/adc.c b/components/driver/adc.c index d16bdc7e1f..b28b9d919a 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -280,7 +280,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) #endif .desc_max_num = INTERNAL_BUF_NUM, .dma_chan = dma_chan, - .eof_num = init_config->conv_num_each_intr / ADC_HAL_DATA_LEN_PER_CONV + .eof_num = init_config->conv_num_each_intr / SOC_ADC_DIGI_DATA_BYTES_PER_CONV }; adc_hal_context_config(&s_adc_digi_ctx->hal, &config); diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 0994202714..42855524ca 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -350,7 +350,7 @@ void adc_hal_digi_start(adc_hal_context_t *hal, uint8_t *data_buf) //reset the current descriptor address hal->cur_desc_ptr = &hal->desc_dummy_head; - adc_hal_digi_dma_link_descriptors(hal->rx_desc, data_buf, hal->eof_num * ADC_HAL_DATA_LEN_PER_CONV, hal->desc_max_num); + adc_hal_digi_dma_link_descriptors(hal->rx_desc, data_buf, hal->eof_num * SOC_ADC_DIGI_DATA_BYTES_PER_CONV, hal->desc_max_num); //start DMA adc_dma_ll_rx_start(hal->dev, hal->dma_chan, (lldesc_t *)hal->rx_desc); diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index b8455e27ec..787e50246e 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -36,9 +36,6 @@ #define ADC_HAL_DMA_INTR_MASK BIT(9) #endif -//For ADC module, each conversion contains 4 bytes -#define ADC_HAL_DATA_LEN_PER_CONV 4 - typedef enum adc_hal_work_mode_t { ADC_HAL_ULP_MODE, ADC_HAL_SINGLE_READ_MODE, diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 15ca029b3c..1225d9a1ea 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -90,6 +90,8 @@ #define SOC_ADC_PATT_LEN_MAX (16) //Two pattern table, each contains 16 items. Each item takes 1 byte. But only support ADC1 using DMA mode #define SOC_ADC_DIGI_MIN_BITWIDTH (9) #define SOC_ADC_DIGI_MAX_BITWIDTH (12) +#define SOC_ADC_DIGI_RESULT_BYTES (2) +#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (4) /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */ #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH (2*1000*1000) #define SOC_ADC_SAMPLE_FREQ_THRES_LOW (2000) diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index a564972a56..24a8ebe11b 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -55,6 +55,8 @@ #define SOC_ADC_DIGI_CONTROLLER_NUM (1U) #define SOC_ADC_PATT_LEN_MAX (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */ #define SOC_ADC_DIGI_MAX_BITWIDTH (12) +#define SOC_ADC_DIGI_RESULT_BYTES (4) +#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (4) #define SOC_ADC_DIGI_FILTER_NUM (2) #define SOC_ADC_DIGI_MONITOR_NUM (2) /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */ diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 629834b868..94761eb81b 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -45,6 +45,8 @@ #define SOC_ADC_DIGI_CONTROLLER_NUM (1U) #define SOC_ADC_PATT_LEN_MAX (8) /*!< One pattern table, each contains 8 items. Each item takes 1 byte */ #define SOC_ADC_DIGI_MAX_BITWIDTH (12) +#define SOC_ADC_DIGI_RESULT_BYTES (4) +#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (4) #define SOC_ADC_DIGI_FILTER_NUM (2) #define SOC_ADC_DIGI_MONITOR_NUM (2) /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */ diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 8bb13f3936..c75571aae0 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -69,6 +69,8 @@ #define SOC_ADC_DIGI_CONTROLLER_NUM (2) #define SOC_ADC_PATT_LEN_MAX (32) /*!< Two pattern table, each contains 16 items. Each item takes 1 byte */ #define SOC_ADC_DIGI_MAX_BITWIDTH (12) +#define SOC_ADC_DIGI_RESULT_BYTES (2) +#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (2) /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */ #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH 83333 #define SOC_ADC_SAMPLE_FREQ_THRES_LOW 611 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 53d385e067..583ba949e9 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -57,6 +57,8 @@ #define SOC_ADC_DIGI_CONTROLLER_NUM (2) #define SOC_ADC_PATT_LEN_MAX (24) //Two pattern table, each contains 12 items. Each item takes 1 byte #define SOC_ADC_DIGI_MAX_BITWIDTH (12) +#define SOC_ADC_DIGI_RESULT_BYTES (4) +#define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (4) /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */ #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH 83333 #define SOC_ADC_SAMPLE_FREQ_THRES_LOW 611 From cb62457f6dcb3077b38a74cfaffe19f5f23e4a00 Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 20 Jul 2022 16:15:39 +0800 Subject: [PATCH 3/3] adc: fix esp32 continuous mode sampling freq issue --- components/hal/adc_hal.c | 22 +++++++++++++------ components/hal/i2s_hal.c | 2 +- components/hal/include/hal/i2s_hal.h | 10 +++++++++ components/soc/esp32/include/soc/soc_caps.h | 2 +- .../adc/dma_read/main/adc_dma_example_main.c | 2 +- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 42855524ca..3eeeae828b 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -14,6 +14,7 @@ #if CONFIG_IDF_TARGET_ESP32 //ADC utilises I2S0 DMA on ESP32 +#include "hal/i2s_hal.h" #include "hal/i2s_ll.h" #include "hal/i2s_types.h" #include "soc/i2s_struct.h" @@ -232,14 +233,21 @@ static void adc_hal_digi_sample_freq_config(adc_hal_context_t *hal, uint32_t fre adc_ll_digi_clk_sel(0); //use APB #else i2s_ll_rx_clk_set_src(hal->dev, I2S_CLK_D2CLK); /*!< Clock from PLL_D2_CLK(160M)*/ - uint32_t bck = I2S_BASE_CLK / (ADC_LL_CLKM_DIV_NUM_DEFAULT + ADC_LL_CLKM_DIV_B_DEFAULT / ADC_LL_CLKM_DIV_A_DEFAULT) / 2 / freq; - i2s_ll_mclk_div_t clk = { - .mclk_div = ADC_LL_CLKM_DIV_NUM_DEFAULT, - .a = ADC_LL_CLKM_DIV_A_DEFAULT, - .b = ADC_LL_CLKM_DIV_B_DEFAULT, + uint32_t bclk_div = 16; + uint32_t bclk = freq * 2; + uint32_t mclk = bclk * bclk_div; + uint32_t mclk_div = I2S_BASE_CLK / mclk; + i2s_hal_clock_cfg_t i2s_hal_clk_cfg = { + .sclk = I2S_BASE_CLK, + .bclk = bclk, + .bclk_div = bclk_div, + .mclk = mclk , + .mclk_div = mclk_div, }; - i2s_ll_rx_set_clk(hal->dev, &clk); - i2s_ll_rx_set_bck_div_num(hal->dev, bck); + i2s_ll_mclk_div_t mclk_set = {}; + i2s_hal_mclk_div_decimal_cal(&i2s_hal_clk_cfg, &mclk_set); + i2s_ll_rx_set_clk(hal->dev, &mclk_set); + i2s_ll_rx_set_bck_div_num(hal->dev, i2s_hal_clk_cfg.bclk_div); #endif } diff --git a/components/hal/i2s_hal.c b/components/hal/i2s_hal.c index 142971993d..2faf735690 100644 --- a/components/hal/i2s_hal.c +++ b/components/hal/i2s_hal.c @@ -19,7 +19,7 @@ * @param clk_cfg I2S clock configuration(input) * @param cal Point to `i2s_ll_mclk_div_t` structure(output). */ -static void i2s_hal_mclk_div_decimal_cal(i2s_hal_clock_cfg_t *clk_cfg, i2s_ll_mclk_div_t *cal) +void i2s_hal_mclk_div_decimal_cal(i2s_hal_clock_cfg_t *clk_cfg, i2s_ll_mclk_div_t *cal) { int ma = 0; int mb = 0; diff --git a/components/hal/include/hal/i2s_hal.h b/components/hal/include/hal/i2s_hal.h index 037970fa2b..0e75b80143 100644 --- a/components/hal/include/hal/i2s_hal.h +++ b/components/hal/include/hal/i2s_hal.h @@ -125,6 +125,16 @@ void i2s_hal_init(i2s_hal_context_t *hal, int i2s_num); */ void i2s_hal_set_clock_src(i2s_hal_context_t *hal, i2s_clock_src_t sel); +/** + * @brief Calculate the closest sample rate clock configuration. + * clock relationship: + * Fmclk = bck_div*fbck = fsclk/(mclk_div+b/a) + * + * @param clk_cfg I2S clock configuration(input) + * @param cal Point to `i2s_ll_mclk_div_t` structure(output). + */ +void i2s_hal_mclk_div_decimal_cal(i2s_hal_clock_cfg_t *clk_cfg, i2s_ll_mclk_div_t *cal); + /** * @brief Set Tx channel style * diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 1225d9a1ea..b151a00984 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -94,7 +94,7 @@ #define SOC_ADC_DIGI_DATA_BYTES_PER_CONV (4) /*!< F_sample = F_digi_con / 2 / interval. F_digi_con = 5M for now. 30 <= interva <= 4095 */ #define SOC_ADC_SAMPLE_FREQ_THRES_HIGH (2*1000*1000) -#define SOC_ADC_SAMPLE_FREQ_THRES_LOW (2000) +#define SOC_ADC_SAMPLE_FREQ_THRES_LOW (20*1000) /*!< RTC */ #define SOC_ADC_MAX_BITWIDTH (12) diff --git a/examples/peripherals/adc/dma_read/main/adc_dma_example_main.c b/examples/peripherals/adc/dma_read/main/adc_dma_example_main.c index 6704fa70c7..f73095ff1e 100644 --- a/examples/peripherals/adc/dma_read/main/adc_dma_example_main.c +++ b/examples/peripherals/adc/dma_read/main/adc_dma_example_main.c @@ -69,7 +69,7 @@ static void continuous_adc_init(uint16_t adc1_chan_mask, uint16_t adc2_chan_mask adc_digi_configuration_t dig_cfg = { .conv_limit_en = ADC_CONV_LIMIT_EN, .conv_limit_num = 250, - .sample_freq_hz = 10 * 1000, + .sample_freq_hz = 20 * 1000, .conv_mode = ADC_CONV_MODE, .format = ADC_OUTPUT_TYPE, };