From bee90f57f146d1a25e454ab20ec7e16019d2a719 Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 19 Feb 2021 19:58:45 +0800 Subject: [PATCH 01/10] adc: remove unused functions on esp32c3 --- components/driver/esp32c3/adc.c | 164 ------------------ .../driver/esp32c3/include/driver/adc.h | 91 ---------- components/hal/esp32c3/adc_hal.c | 37 ++-- components/hal/esp32c3/include/hal/adc_hal.h | 92 ---------- components/hal/esp32c3/include/hal/adc_ll.h | 14 +- 5 files changed, 16 insertions(+), 382 deletions(-) diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index 81b30860c9..4dbd4f7056 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -605,86 +605,6 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config) return ESP_OK; } -esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config) -{ - if (adc_unit & ADC_UNIT_1) { - return ESP_ERR_NOT_SUPPORTED; - } - ADC_ENTER_CRITICAL(); - adc_hal_arbiter_config(config); - ADC_EXIT_CRITICAL(); - return ESP_OK; -} - -/** - * @brief Set ADC module controller. - * There are five SAR ADC controllers: - * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes; - * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep; - * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2. - * - * @note Only ADC2 support arbiter to switch controllers automatically. Access to the ADC is based on the priority of the controller. - * @note For ADC1, Controller access is mutually exclusive. - * - * @param adc_unit ADC unit. - * @param ctrl ADC controller, Refer to `adc_controller_t`. - * - * @return - * - ESP_OK Success - */ -esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl) -{ - adc_arbiter_t config = {0}; - adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT(); - - if (adc_unit & ADC_UNIT_1) { - adc_hal_set_controller(ADC_NUM_1, ctrl); - } - if (adc_unit & ADC_UNIT_2) { - adc_hal_set_controller(ADC_NUM_2, ctrl); - switch (ctrl) { - case ADC2_CTRL_FORCE_PWDET: - config.pwdet_pri = 2; - config.mode = ADC_ARB_MODE_SHIELD; - adc_hal_arbiter_config(&config); - adc_hal_set_controller(ADC_NUM_2, ADC2_CTRL_PWDET); - break; - case ADC2_CTRL_FORCE_RTC: - config.rtc_pri = 2; - config.mode = ADC_ARB_MODE_SHIELD; - adc_hal_arbiter_config(&config); - adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC); - break; - case ADC2_CTRL_FORCE_DIG: - config.dig_pri = 2; - config.mode = ADC_ARB_MODE_SHIELD; - adc_hal_arbiter_config(&config); - adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_DIG); - break; - default: - adc_hal_arbiter_config(&cfg); - break; - } - } - return ESP_OK; -} - -/** - * @brief Reset FSM of adc digital controller. - * - * @return - * - ESP_OK Success - */ -esp_err_t adc_digi_reset(void) -{ - ADC_ENTER_CRITICAL(); - adc_hal_digi_reset(); - adc_hal_digi_clear_pattern_table(ADC_NUM_1); - adc_hal_digi_clear_pattern_table(ADC_NUM_2); - ADC_EXIT_CRITICAL(); - return ESP_OK; -} - /*************************************/ /* Digital controller filter setting */ /*************************************/ @@ -742,90 +662,6 @@ esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable) return ESP_OK; } -/**************************************/ -/* Digital controller intr setting */ -/**************************************/ - -esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask) -{ - ADC_ENTER_CRITICAL(); - if (adc_unit & ADC_UNIT_1) { - adc_hal_digi_intr_enable(ADC_NUM_1, intr_mask); - } - if (adc_unit & ADC_UNIT_2) { - adc_hal_digi_intr_enable(ADC_NUM_2, intr_mask); - } - ADC_EXIT_CRITICAL(); - return ESP_OK; -} - -esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask) -{ - ADC_ENTER_CRITICAL(); - if (adc_unit & ADC_UNIT_1) { - adc_hal_digi_intr_disable(ADC_NUM_1, intr_mask); - } - if (adc_unit & ADC_UNIT_2) { - adc_hal_digi_intr_disable(ADC_NUM_2, intr_mask); - } - ADC_EXIT_CRITICAL(); - return ESP_OK; -} - -esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask) -{ - ADC_ENTER_CRITICAL(); - if (adc_unit & ADC_UNIT_1) { - adc_hal_digi_intr_clear(ADC_NUM_1, intr_mask); - } - if (adc_unit & ADC_UNIT_2) { - adc_hal_digi_intr_clear(ADC_NUM_2, intr_mask); - } - ADC_EXIT_CRITICAL(); - return ESP_OK; -} - -uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit) -{ - uint32_t ret = 0; - ADC_ENTER_CRITICAL(); - if (adc_unit & ADC_UNIT_1) { - ret = adc_hal_digi_get_intr_status(ADC_NUM_1); - } - if (adc_unit & ADC_UNIT_2) { - ret = adc_hal_digi_get_intr_status(ADC_NUM_2); - } - ADC_EXIT_CRITICAL(); - return ret; -} - -static bool s_isr_registered = 0; -static intr_handle_t s_adc_isr_handle = NULL; - -esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags) -{ - ADC_CHECK((fn != NULL), "Parameter error", ESP_ERR_INVALID_ARG); - ADC_CHECK(s_isr_registered == 0, "ADC ISR have installed, can not install again", ESP_FAIL); - - esp_err_t ret = esp_intr_alloc(ETS_APB_ADC_INTR_SOURCE, intr_alloc_flags, fn, arg, &s_adc_isr_handle); - if (ret == ESP_OK) { - s_isr_registered = 1; - } - return ret; -} - -esp_err_t adc_digi_isr_deregister(void) -{ - esp_err_t ret = ESP_FAIL; - if (s_isr_registered) { - ret = esp_intr_free(s_adc_isr_handle); - if (ret == ESP_OK) { - s_isr_registered = 0; - } - } - return ret; -} - /*--------------------------------------------------------------- RTC controller setting ---------------------------------------------------------------*/ diff --git a/components/driver/esp32c3/include/driver/adc.h b/components/driver/esp32c3/include/driver/adc.h index 463778a3a9..2678a9e61e 100644 --- a/components/driver/esp32c3/include/driver/adc.h +++ b/components/driver/esp32c3/include/driver/adc.h @@ -22,25 +22,6 @@ extern "C" { /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ - -/** - * @brief Config ADC module arbiter. - * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, - * the low priority controller will read the invalid ADC2 data, and the validity of the data can be judged by the flag bit in the data. - * - * @note Only ADC2 support arbiter. - * @note Default priority: Wi-Fi > RTC > Digital; - * @note In normal use, there is no need to call this interface to config arbiter. - * - * @param adc_unit ADC unit. - * @param config Refer to `adc_arbiter_t`. - * - * @return - * - ESP_OK Success - * - ESP_ERR_NOT_SUPPORTED ADC unit not support arbiter. - */ -esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config); - /*************************************/ /* Digital controller filter setting */ /*************************************/ @@ -114,78 +95,6 @@ esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monit */ esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable); -/**************************************/ -/* Digital controller intr setting */ -/**************************************/ - -/** - * @brief Enable interrupt of adc digital controller by bitmask. - * - * @param adc_unit ADC unit. - * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. - * - * @return - * - ESP_OK Success - */ -esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); - -/** - * @brief Disable interrupt of adc digital controller by bitmask. - * - * @param adc_unit ADC unit. - * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. - * - * @return - * - ESP_OK Success - */ -esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); - -/** - * @brief Clear interrupt of adc digital controller by bitmask. - * - * @param adc_unit ADC unit. - * @param intr_mask Interrupt bitmask. See ``adc_digi_intr_t``. - * - * @return - * - ESP_OK Success - */ -esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask); - -/** - * @brief Get interrupt status mask of adc digital controller. - * - * @param adc_unit ADC unit. - * @return - * - intr Interrupt bitmask, See ``adc_digi_intr_t``. - */ -uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit); - -/** - * @brief Register ADC interrupt handler, the handler is an ISR. - * The handler will be attached to the same CPU core that this function is running on. - * - * @param fn Interrupt handler function. - * @param arg Parameter for handler function - * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) - * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. - * - * @return - * - ESP_OK Success - * - ESP_ERR_NOT_FOUND Can not find the interrupt that matches the flags. - * - ESP_ERR_INVALID_ARG Function pointer error. - */ -esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags); - -/** - * @brief Deregister ADC interrupt handler, the handler is an ISR. - * - * @return - * - ESP_OK Success - * - ESP_ERR_INVALID_ARG hander error. - * - ESP_FAIL ISR not be registered. - */ -esp_err_t adc_digi_isr_deregister(void); - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c3/adc_hal.c b/components/hal/esp32c3/adc_hal.c index 105dff6490..bec18db5fb 100644 --- a/components/hal/esp32c3/adc_hal.c +++ b/components/hal/esp32c3/adc_hal.c @@ -45,6 +45,18 @@ void adc_hal_digi_deinit(void) adc_hal_deinit(); } +/** + * - Set ADC digital controller clock division factor. The clock is divided from `APLL` or `APB` clock. + * Expression: controller_clk = APLL/APB * (div_num + div_a / div_b + 1). + * - Enable clock and select clock source for ADC digital controller. + */ +static void adc_hal_digi_clk_config(void) +{ + //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); +} + 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. @@ -74,31 +86,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg) adc_hal_digi_clk_config(); } -void adc_hal_digi_clk_config(void) -{ - //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); -} - -/** - * Enable digital controller to trigger the measurement. - */ -void adc_hal_digi_enable(void) -{ - adc_ll_digi_dma_enable(); - adc_ll_digi_trigger_enable(); -} - -/** - * Disable digital controller to trigger the measurement. - */ -void adc_hal_digi_disable(void) -{ - adc_ll_digi_trigger_disable(); - adc_ll_digi_dma_disable(); -} - static void filter_update(adc_digi_filter_idx_t idx) { //ESP32-C3 has no enable bit, the filter will be enabled when the filter channel is configured diff --git a/components/hal/esp32c3/include/hal/adc_hal.h b/components/hal/esp32c3/include/hal/adc_hal.h index 2f6fffeaad..9993f9e8d9 100644 --- a/components/hal/esp32c3/include/hal/adc_hal.h +++ b/components/hal/esp32c3/include/hal/adc_hal.h @@ -46,41 +46,6 @@ void adc_hal_digi_deinit(void); */ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg); -/** - * ADC Digital controller output data invert or not. - * - * @param adc_n ADC unit. - * @param inv_en data invert or not. - */ -#define adc_hal_digi_output_invert(adc_n, inv_en) adc_ll_digi_output_invert(adc_n, inv_en) - -/** - * Sets the number of interval clock cycles for the digital controller to trigger the measurement. - * - * @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. - */ -#define adc_hal_digi_set_trigger_interval(cycle) adc_ll_digi_set_trigger_interval(cycle) - -/** - * Enable digital controller to trigger the measurement. - */ -void adc_hal_digi_enable(void); - -/** - * Disable digital controller to trigger the measurement. - */ -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_a / div_b + 1). - * - * @param clk Refer to `adc_digi_clk_t`. - */ -void adc_hal_digi_clk_config(void); - /** * Reset adc digital controller filter. * @@ -132,63 +97,6 @@ void adc_hal_digi_monitor_config(adc_digi_monitor_idx_t mon_idx, adc_digi_monito */ void adc_hal_digi_monitor_enable(adc_digi_monitor_idx_t mon_idx, bool enable); -/** - * Enable interrupt of adc digital controller by bitmask. - * - * @param adc_n ADC unit. - * @param intr Interrupt bitmask. - */ -#define adc_hal_digi_intr_enable(adc_n, intr) adc_ll_digi_intr_enable(adc_n, intr) - -/** - * Disable interrupt of adc digital controller by bitmask. - * - * @param adc_n ADC unit. - * @param intr Interrupt bitmask. - */ -#define adc_hal_digi_intr_disable(adc_n, intr) adc_ll_digi_intr_disable(adc_n, intr) - -/** - * Clear interrupt of adc digital controller by bitmask. - * - * @param adc_n ADC unit. - * @param intr Interrupt bitmask. - */ -#define adc_hal_digi_intr_clear(adc_n, intr) adc_ll_digi_intr_clear(adc_n, intr) - -/** - * Get interrupt status mask of adc digital controller. - * - * @param adc_n ADC unit. - * @return - * - intr Interrupt bitmask. - */ -#define adc_hal_digi_get_intr_status(adc_n) adc_ll_digi_get_intr_status(adc_n) - - -/** - * Set DMA eof num of adc digital controller. - * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. - * - * @param num eof num of DMA. - */ -#define adc_hal_digi_dma_set_eof_num(num) adc_ll_digi_dma_set_eof_num(num) - -/** - * Enable output data to DMA from adc digital controller. - */ -#define adc_hal_digi_dma_enable() adc_ll_digi_dma_enable() - -/** - * Disable output data to DMA from adc digital controller. - */ -#define adc_hal_digi_dma_disable() adc_ll_digi_dma_disable() - -/** - * Reset adc digital controller. - */ -#define adc_hal_digi_reset() adc_ll_digi_reset() - /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index ecbface280..5ee33aed07 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -29,7 +29,6 @@ extern "C" { #endif -#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 @@ -74,7 +73,7 @@ typedef enum { ADC2_CTRL_FORCE_PWDET = 3, /*! Date: Mon, 22 Feb 2021 20:29:13 +0800 Subject: [PATCH 02/10] adc: seperate hal layer and driver layer --- components/driver/esp32c3/adc.c | 85 +++++++--------- components/hal/adc_hal.c | 106 ++++++++++++-------- components/hal/include/hal/adc_hal.h | 142 +++++++++++++++++++++------ 3 files changed, 211 insertions(+), 122 deletions(-) diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index 4dbd4f7056..97072c900d 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -83,13 +83,12 @@ static _lock_t sar_adc2_mutex; #define IN_SUC_EOF_BIT GDMA_LL_EVENT_RX_SUC_EOF typedef struct adc_digi_context_t { - intr_handle_t dma_intr_hdl; //MD interrupt handle uint32_t bytes_between_intr; //bytes between in suc eof intr uint8_t *rx_dma_buf; //dma buffer - adc_dma_hal_context_t hal_dma; //dma context (hal) - adc_dma_hal_config_t hal_dma_config; //dma config (hal) + adc_hal_context_t hal; //hal context gdma_channel_handle_t rx_dma_channel; //dma rx channel handle RingbufHandle_t ringbuf_hdl; //RX ringbuffer handler + intptr_t rx_eof_desc_addr; //eof descriptor address of RX channel bool ringbuf_overflow_flag; //1: ringbuffer overflow bool driver_start_flag; //1: driver is started; 0: driver is stoped bool use_adc1; //1: ADC unit1 will be used; 0: ADC unit1 won't be used. @@ -167,12 +166,11 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) } //malloc dma descriptor - s_adc_digi_ctx->hal_dma_config.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * INTERNAL_BUF_NUM, MALLOC_CAP_DMA); - if (!s_adc_digi_ctx->hal_dma_config.rx_desc) { + s_adc_digi_ctx->hal.rx_desc = heap_caps_calloc(1, (sizeof(dma_descriptor_t)) * INTERNAL_BUF_NUM, MALLOC_CAP_DMA); + if (!s_adc_digi_ctx->hal.rx_desc) { ret = ESP_ERR_NO_MEM; goto cleanup; } - s_adc_digi_ctx->hal_dma_config.desc_max_num = INTERNAL_BUF_NUM; //malloc pattern table s_adc_digi_ctx->digi_controller_config.adc_pattern = calloc(1, SOC_ADC_PATT_LEN_MAX * sizeof(adc_digi_pattern_table_t)); @@ -218,7 +216,13 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) int dma_chan; gdma_get_channel_id(s_adc_digi_ctx->rx_dma_channel, &dma_chan); - s_adc_digi_ctx->hal_dma_config.dma_chan = dma_chan; + + adc_hal_config_t config = { + .desc_max_num = INTERNAL_BUF_NUM, + .dma_chan = dma_chan, + .eof_num = s_adc_digi_ctx->bytes_between_intr / 4 + }; + adc_hal_context_config(&s_adc_digi_ctx->hal, &config); //enable SARADC module clock periph_module_enable(PERIPH_SARADC_MODULE); @@ -239,6 +243,7 @@ static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx); static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { adc_digi_context_t *adc_digi_ctx = (adc_digi_context_t *)user_data; + adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr; return adc_dma_intr(adc_digi_ctx); } @@ -246,33 +251,25 @@ static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx) { portBASE_TYPE taskAwoken = 0; BaseType_t ret; + adc_hal_dma_desc_status_t status = false; + dma_descriptor_t *current_desc = NULL; + + while (1) { + status = adc_hal_get_reading_result(&adc_digi_ctx->hal, adc_digi_ctx->rx_eof_desc_addr, ¤t_desc); + if (status != ADC_DMA_DESC_FINISH) { + break; + } - while (adc_digi_ctx->hal_dma_config.cur_desc_ptr->dw0.owner == 0) { - dma_descriptor_t *current_desc = adc_digi_ctx->hal_dma_config.cur_desc_ptr; ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, current_desc->buffer, current_desc->dw0.length, &taskAwoken); if (ret == pdFALSE) { //ringbuffer overflow adc_digi_ctx->ringbuf_overflow_flag = 1; } - - adc_digi_ctx->hal_dma_config.desc_cnt += 1; - //cycle the dma descriptor and buffers - adc_digi_ctx->hal_dma_config.cur_desc_ptr = adc_digi_ctx->hal_dma_config.cur_desc_ptr->next; - if (!adc_digi_ctx->hal_dma_config.cur_desc_ptr) { - break; - } } - if (!adc_digi_ctx->hal_dma_config.cur_desc_ptr) { - - assert(adc_digi_ctx->hal_dma_config.desc_cnt == adc_digi_ctx->hal_dma_config.desc_max_num); - //reset the current descriptor status - adc_digi_ctx->hal_dma_config.cur_desc_ptr = adc_digi_ctx->hal_dma_config.rx_desc; - adc_digi_ctx->hal_dma_config.desc_cnt = 0; - + if (status == ADC_DMA_DESC_NULL) { //start next turns of dma operation - adc_hal_digi_dma_multi_descriptor(&adc_digi_ctx->hal_dma_config, adc_digi_ctx->rx_dma_buf, adc_digi_ctx->bytes_between_intr, adc_digi_ctx->hal_dma_config.desc_max_num); - adc_hal_digi_rxdma_start(&adc_digi_ctx->hal_dma, &adc_digi_ctx->hal_dma_config); + adc_hal_digi_rxdma_start(&adc_digi_ctx->hal, adc_digi_ctx->rx_dma_buf, adc_digi_ctx->bytes_between_intr); } if(taskAwoken == pdTRUE) { @@ -309,26 +306,16 @@ esp_err_t adc_digi_start(void) } adc_hal_init(); - adc_hal_arbiter_config(&config); - adc_hal_digi_init(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config); + adc_hal_digi_init(&s_adc_digi_ctx->hal); adc_hal_digi_controller_config(&s_adc_digi_ctx->digi_controller_config); - //create dma descriptors - adc_hal_digi_dma_multi_descriptor(&s_adc_digi_ctx->hal_dma_config, s_adc_digi_ctx->rx_dma_buf, s_adc_digi_ctx->bytes_between_intr, s_adc_digi_ctx->hal_dma_config.desc_max_num); - adc_hal_digi_set_eof_num(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, (s_adc_digi_ctx->bytes_between_intr)/4); - //set the current descriptor pointer - s_adc_digi_ctx->hal_dma_config.cur_desc_ptr = s_adc_digi_ctx->hal_dma_config.rx_desc; - s_adc_digi_ctx->hal_dma_config.desc_cnt = 0; - - //enable in suc eof intr - adc_hal_digi_ena_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT); - - //start ADC - adc_hal_digi_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config); - + //reset ADC and DMA + adc_hal_fifo_reset(&s_adc_digi_ctx->hal); //start DMA - adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config); + adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal, s_adc_digi_ctx->rx_dma_buf, s_adc_digi_ctx->bytes_between_intr); + //start ADC + adc_hal_digi_start(&s_adc_digi_ctx->hal); return ESP_OK; } @@ -342,13 +329,13 @@ esp_err_t adc_digi_stop(void) s_adc_digi_ctx->driver_start_flag = 0; //disable the in suc eof intrrupt - adc_hal_digi_dis_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT); + adc_hal_digi_dis_intr(&s_adc_digi_ctx->hal, IN_SUC_EOF_BIT); //clear the in suc eof interrupt - adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config, IN_SUC_EOF_BIT); - //stop DMA - adc_hal_digi_rxdma_stop(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config); + adc_hal_digi_clr_intr(&s_adc_digi_ctx->hal, IN_SUC_EOF_BIT); //stop ADC - adc_hal_digi_stop(&s_adc_digi_ctx->hal_dma, &s_adc_digi_ctx->hal_dma_config); + adc_hal_digi_stop(&s_adc_digi_ctx->hal); + //stop DMA + adc_hal_digi_rxdma_stop(&s_adc_digi_ctx->hal); adc_hal_digi_deinit(); ADC_DIGI_LOCK_RELEASE(); @@ -403,17 +390,13 @@ esp_err_t adc_digi_deinitialize(void) return ESP_ERR_INVALID_STATE; } - if (s_adc_digi_ctx->dma_intr_hdl) { - esp_intr_free(s_adc_digi_ctx->dma_intr_hdl); - } - if(s_adc_digi_ctx->ringbuf_hdl) { vRingbufferDelete(s_adc_digi_ctx->ringbuf_hdl); s_adc_digi_ctx->ringbuf_hdl = NULL; } free(s_adc_digi_ctx->rx_dma_buf); - free(s_adc_digi_ctx->hal_dma_config.rx_desc); + free(s_adc_digi_ctx->hal.rx_desc); free(s_adc_digi_ctx->digi_controller_config.adc_pattern); gdma_disconnect(s_adc_digi_ctx->rx_dma_channel); gdma_del_channel(s_adc_digi_ctx->rx_dma_channel); diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 7ff8f984bd..7456911115 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -209,11 +209,34 @@ uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc /*--------------------------------------------------------------- DMA setting ---------------------------------------------------------------*/ -void adc_hal_digi_dma_multi_descriptor(adc_dma_hal_config_t *dma_config, uint8_t *data_buf, uint32_t size, uint32_t num) +void adc_hal_context_config(adc_hal_context_t *hal, const adc_hal_config_t *config) +{ + hal->dev = &GDMA; + hal->desc_dummy_head.next = hal->rx_desc; + hal->desc_max_num = config->desc_max_num; + hal->dma_chan = config->dma_chan; + hal->eof_num = config->eof_num; +} + +void adc_hal_digi_init(adc_hal_context_t *hal) +{ + gdma_ll_clear_interrupt_status(hal->dev, hal->dma_chan, UINT32_MAX); + gdma_ll_enable_interrupt(hal->dev, hal->dma_chan, GDMA_LL_EVENT_RX_SUC_EOF, true); + adc_ll_digi_dma_set_eof_num(hal->eof_num); + adc_ll_adc1_onetime_sample_enable(false); + adc_ll_adc2_onetime_sample_enable(false); +} + +void adc_hal_fifo_reset(adc_hal_context_t *hal) +{ + adc_ll_digi_reset(); + gdma_ll_rx_reset_channel(hal->dev, hal->dma_chan); +} + +static void adc_hal_digi_dma_multi_descriptor(dma_descriptor_t *desc, uint8_t *data_buf, uint32_t size, uint32_t num) { assert(((uint32_t)data_buf % 4) == 0); assert((size % 4) == 0); - dma_descriptor_t *desc = dma_config->rx_desc; uint32_t n = 0; while (num--) { @@ -228,49 +251,54 @@ void adc_hal_digi_dma_multi_descriptor(adc_dma_hal_config_t *dma_config, uint8_t desc[n-1].next = NULL; } -void adc_hal_digi_rxdma_start(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config) +void adc_hal_digi_rxdma_start(adc_hal_context_t *hal, uint8_t *data_buf, uint32_t size) { - gdma_ll_rx_reset_channel(adc_dma_ctx->dev, dma_config->dma_chan); - gdma_ll_rx_set_desc_addr(adc_dma_ctx->dev, dma_config->dma_chan, (uint32_t)dma_config->rx_desc); - gdma_ll_rx_start(adc_dma_ctx->dev, dma_config->dma_chan); + //reset the current descriptor address + hal->cur_desc_ptr = &hal->desc_dummy_head; + adc_hal_digi_dma_multi_descriptor(hal->rx_desc, data_buf, size, hal->desc_max_num); + gdma_ll_rx_set_desc_addr(hal->dev, hal->dma_chan, (uint32_t)hal->rx_desc); + gdma_ll_rx_start(hal->dev, hal->dma_chan); } -void adc_hal_digi_rxdma_stop(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config) -{ - gdma_ll_rx_stop(adc_dma_ctx->dev, dma_config->dma_chan); -} - -void adc_hal_digi_ena_intr(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t mask) -{ - gdma_ll_enable_interrupt(adc_dma_ctx->dev, dma_config->dma_chan, mask, true); -} - -void adc_hal_digi_clr_intr(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t mask) -{ - gdma_ll_clear_interrupt_status(adc_dma_ctx->dev, dma_config->dma_chan, mask); -} - -void adc_hal_digi_dis_intr(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t mask) -{ - gdma_ll_enable_interrupt(adc_dma_ctx->dev, dma_config->dma_chan, mask, false); -} - -void adc_hal_digi_set_eof_num(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t num) -{ - adc_ll_digi_dma_set_eof_num(num); -} - -void adc_hal_digi_start(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config) +void adc_hal_digi_start(adc_hal_context_t *hal) { //Set to 1: the ADC data will be sent to the DMA adc_ll_digi_dma_enable(); //enable sar adc timer adc_ll_digi_trigger_enable(); - //reset the adc state - adc_ll_digi_reset(); } -void adc_hal_digi_stop(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config) +adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_context_t *hal, const intptr_t eof_desc_addr, dma_descriptor_t **cur_desc) +{ + if (!hal->cur_desc_ptr->next) { + return ADC_DMA_DESC_NULL; + } + if ((intptr_t)hal->cur_desc_ptr == eof_desc_addr) { + return ADC_DMA_DESC_NOT_FINISH; + } + + hal->cur_desc_ptr = hal->cur_desc_ptr->next; + *cur_desc = hal->cur_desc_ptr; + + return ADC_DMA_DESC_FINISH; +} + +void adc_hal_digi_rxdma_stop(adc_hal_context_t *hal) +{ + gdma_ll_rx_stop(hal->dev, hal->dma_chan); +} + +void adc_hal_digi_clr_intr(adc_hal_context_t *hal, uint32_t mask) +{ + gdma_ll_clear_interrupt_status(hal->dev, hal->dma_chan, mask); +} + +void adc_hal_digi_dis_intr(adc_hal_context_t *hal, uint32_t mask) +{ + gdma_ll_enable_interrupt(hal->dev, hal->dma_chan, mask, false); +} + +void adc_hal_digi_stop(adc_hal_context_t *hal) { //Set to 0: the ADC data won't be sent to the DMA adc_ll_digi_dma_disable(); @@ -278,14 +306,6 @@ void adc_hal_digi_stop(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t adc_ll_digi_trigger_disable(); } -void adc_hal_digi_init(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config) -{ - adc_dma_ctx->dev = &GDMA; - gdma_ll_clear_interrupt_status(adc_dma_ctx->dev, dma_config->dma_chan, UINT32_MAX); - adc_ll_adc1_onetime_sample_enable(false); - adc_ll_adc2_onetime_sample_enable(false); -} - /*--------------------------------------------------------------- Single Read ---------------------------------------------------------------*/ diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index db7a1e3aa2..4754074154 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -4,6 +4,51 @@ #include "hal/adc_types.h" #include "hal/adc_ll.h" +#if CONFIG_IDF_TARGET_ESP32C3 +#include "soc/gdma_struct.h" +#include "hal/gdma_ll.h" +#include "hal/dma_types.h" +#include "hal/adc_ll.h" +#include "hal/dma_types.h" +#include "esp_err.h" + +/** + * @brief Enum for DMA descriptor status + */ +typedef enum adc_hal_dma_desc_status_t{ + ADC_DMA_DESC_FINISH = 0, ///< This DMA descriptor is written by HW already + ADC_DMA_DESC_NOT_FINISH = 1, ///< This DMA descriptor is not written by HW yet + ADC_DMA_DESC_NULL = 2 ///< This DMA descriptor is NULL +} adc_hal_dma_desc_status_t; + +/** + * @brief Configuration of the HAL + */ +typedef struct adc_hal_config_t { + uint32_t desc_max_num; ///< Number of the descriptors linked once + uint32_t dma_chan; ///< DMA channel to be used + uint32_t eof_num; ///< Bytes between 2 in_suc_eof interrupts +} adc_hal_config_t; + +/** + * @brief Context of the HAL + */ +typedef struct adc_hal_context_t { + /**< this needs to be malloced by the driver layer first */ + dma_descriptor_t *rx_desc; ///< DMA descriptors + + /**< these will be assigned by hal layer itself */ + gdma_dev_t *dev; ///< GDMA address + dma_descriptor_t desc_dummy_head; ///< Dummy DMA descriptor for ``cur_desc_ptr`` to start + dma_descriptor_t *cur_desc_ptr; ///< Pointer to the current descriptor + + /**< these need to be configured by `adc_hal_config_t` via driver layer*/ + uint32_t desc_max_num; ///< Number of the descriptors linked once + uint32_t dma_chan; ///< DMA channel to be used + uint32_t eof_num; ///< Bytes between 2 in_suc_eof interrupts +} adc_hal_context_t; +#endif + /*--------------------------------------------------------------- Common setting ---------------------------------------------------------------*/ @@ -252,44 +297,85 @@ uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc /*--------------------------------------------------------------- DMA setting ---------------------------------------------------------------*/ -#include "soc/gdma_struct.h" -#include "hal/gdma_ll.h" -#include "hal/dma_types.h" -#include "hal/adc_ll.h" -#include "hal/dma_types.h" -#include "esp_err.h" +/** + * @brief Initialize the hal context + * + * @param hal Context of the HAL + * @param config Configuration of the HAL + */ +void adc_hal_context_config(adc_hal_context_t *hal, const adc_hal_config_t *config); -typedef struct adc_dma_hal_context_t { - gdma_dev_t *dev; //address of the general DMA -} adc_dma_hal_context_t; +/** + * @brief Initialize the HW + * + * @param hal Context of the HAL + */ +void adc_hal_digi_init(adc_hal_context_t *hal); -typedef struct adc_dma_hal_config_t { - dma_descriptor_t *rx_desc; //dma descriptor - dma_descriptor_t *cur_desc_ptr; //pointer to the current descriptor - uint32_t desc_max_num; //number of the descriptors linked once - uint32_t desc_cnt; - uint32_t dma_chan; -} adc_dma_hal_config_t; +/** + * @brief Reset ADC / DMA fifo + * + * @param hal Context of the HAL + */ +void adc_hal_fifo_reset(adc_hal_context_t *hal); -void adc_hal_digi_dma_multi_descriptor(adc_dma_hal_config_t *dma_config, uint8_t *data_buf, uint32_t size, uint32_t num); +/** + * @brief Start DMA + * + * @param hal Context of the HAL + * @param data_buf Pointer to the data buffer + * @param size Size of the buffer + */ +void adc_hal_digi_rxdma_start(adc_hal_context_t *hal, uint8_t *data_buf, uint32_t size); -void adc_hal_digi_rxdma_start(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config); +/** + * @brief Start ADC + * + * @param hal Context of the HAL + */ +void adc_hal_digi_start(adc_hal_context_t *hal); -void adc_hal_digi_rxdma_stop(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config); +/** + * @brief Get the ADC reading result + * + * @param hal Context of the HAL + * @param eof_desc_addr The last descriptor that is finished by HW. Should be got from DMA + * @param[out] cur_desc The descriptor with ADC reading result (from the 1st one to the last one (``eof_desc_addr``)) + * + * @return See ``adc_hal_dma_desc_status_t`` + */ +adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_context_t *hal, const intptr_t eof_desc_addr, dma_descriptor_t **cur_desc); -void adc_hal_digi_ena_intr(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t mask); +/** + * @brief Stop DMA + * + * @param hal Context of the HAL + */ +void adc_hal_digi_rxdma_stop(adc_hal_context_t *hal); -void adc_hal_digi_clr_intr(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t mask); +/** + * @brief Clear interrupt + * + * @param hal Context of the HAL + * @param mask mask of the interrupt + */ +void adc_hal_digi_clr_intr(adc_hal_context_t *hal, uint32_t mask); -void adc_hal_digi_dis_intr(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t mask); +/** + * @brief Enable interrupt + * + * @param hal Context of the HAL + * @param mask mask of the interrupt + */ +void adc_hal_digi_dis_intr(adc_hal_context_t *hal, uint32_t mask); -void adc_hal_digi_set_eof_num(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config, uint32_t num); +/** + * @brief Stop ADC + * + * @param hal Context of the HAL + */ +void adc_hal_digi_stop(adc_hal_context_t *hal); -void adc_hal_digi_start(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config); - -void adc_hal_digi_stop(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config); - -void adc_hal_digi_init(adc_dma_hal_context_t *adc_dma_ctx, adc_dma_hal_config_t *dma_config); /*--------------------------------------------------------------- Single Read From 00a3f48bd806dcbf4a0f70053fda659a30b3d07c Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 23 Feb 2021 21:40:15 +0800 Subject: [PATCH 03/10] adc: refactor adc single read api on esp32c3 --- components/driver/adc_common.c | 12 +- components/driver/esp32c3/adc.c | 53 +--- components/hal/adc_hal.c | 160 ++++++------ components/hal/esp32c3/adc_hal.c | 1 - components/hal/esp32c3/include/hal/adc_ll.h | 164 +------------ components/hal/include/hal/adc_hal.h | 255 +++++++++----------- components/hal/include/hal/adc_types.h | 38 +-- 7 files changed, 232 insertions(+), 451 deletions(-) diff --git a/components/driver/adc_common.c b/components/driver/adc_common.c index 95a1028e99..81030a57cf 100644 --- a/components/driver/adc_common.c +++ b/components/driver/adc_common.c @@ -552,6 +552,7 @@ static inline void adc2_dac_disable( adc2_channel_t channel) */ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out) { + esp_err_t ret = ESP_OK; int adc_value = 0; ADC_CHECK(raw_out != NULL, "ADC out value err", ESP_ERR_INVALID_ARG); @@ -591,7 +592,9 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * #endif //CONFIG_PM_ENABLE #endif //CONFIG_IDF_TARGET_ESP32 - if (adc_hal_convert(ADC_NUM_2, channel, &adc_value)) { + ret = adc_hal_convert(ADC_NUM_2, channel, &adc_value); + if (ret != ESP_OK) { + ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." ); adc_value = -1; } @@ -608,13 +611,8 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * adc_power_release(); SARADC2_RELEASE(); - if (adc_value < 0) { - ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." ); - return ESP_ERR_INVALID_STATE; - } - *raw_out = adc_value; - return ESP_OK; + return ret; } esp_err_t adc2_vref_to_gpio(gpio_num_t gpio) diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index 97072c900d..b55e56e036 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -442,39 +442,20 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) int adc1_get_raw(adc1_channel_t channel) { int raw_out = 0; - adc_digi_config_t dig_cfg = { - .conv_limit_en = 0, - .conv_limit_num = 250, - .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, - }; ADC_DIGI_LOCK_ACQUIRE(); - periph_module_enable(PERIPH_SARADC_MODULE); adc_atten_t atten = s_atten1_single[channel]; uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, channel, atten); adc_hal_set_calibration_param(ADC_NUM_1, cal_val); - adc_hal_digi_controller_config(&dig_cfg); + adc_hal_set_power_manage(ADC_POWER_SW_ON); + adc_hal_set_atten(ADC_NUM_2, channel, atten); + adc_hal_convert(ADC_NUM_1, channel, &raw_out); - adc_hal_intr_clear(ADC_EVENT_ADC1_DONE); - - adc_hal_adc1_onetime_sample_enable(true); - adc_hal_onetime_channel(ADC_NUM_1, channel); - adc_hal_set_onetime_atten(atten); - - //Trigger single read. - adc_hal_onetime_start(&dig_cfg); - while (!adc_hal_intr_get_raw(ADC_EVENT_ADC1_DONE)); - adc_hal_single_read(ADC_NUM_1, &raw_out); - - adc_hal_intr_clear(ADC_EVENT_ADC1_DONE); - adc_hal_adc1_onetime_sample_enable(false); - - adc_hal_digi_deinit(); + adc_hal_set_power_manage(ADC_POWER_SW_OFF); periph_module_disable(PERIPH_SARADC_MODULE); - ADC_DIGI_LOCK_RELEASE(); return raw_out; @@ -502,11 +483,6 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * } esp_err_t ret = ESP_OK; - adc_digi_config_t dig_cfg = { - .conv_limit_en = 0, - .conv_limit_num = 250, - .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, - }; SAC_ADC2_LOCK_ACQUIRE(); ADC_DIGI_LOCK_ACQUIRE(); @@ -516,25 +492,12 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, channel, atten); adc_hal_set_calibration_param(ADC_NUM_2, cal_val); - adc_hal_digi_controller_config(&dig_cfg); + adc_hal_set_power_manage(ADC_POWER_SW_ON); + adc_hal_set_atten(ADC_NUM_2, channel, atten); + ret = adc_hal_convert(ADC_NUM_2, channel, raw_out); - adc_hal_intr_clear(ADC_EVENT_ADC2_DONE); - - adc_hal_adc2_onetime_sample_enable(true); - adc_hal_onetime_channel(ADC_NUM_2, channel); - adc_hal_set_onetime_atten(atten); - - //Trigger single read. - adc_hal_onetime_start(&dig_cfg); - while (!adc_hal_intr_get_raw(ADC_EVENT_ADC2_DONE)); - ret = adc_hal_single_read(ADC_NUM_2, raw_out); - - adc_hal_intr_clear(ADC_EVENT_ADC2_DONE); - adc_hal_adc2_onetime_sample_enable(false); - - adc_hal_digi_deinit(); + adc_hal_set_power_manage(ADC_POWER_SW_OFF); periph_module_disable(PERIPH_SARADC_MODULE); - ADC_DIGI_LOCK_RELEASE(); SAC_ADC2_LOCK_RELEASE(); diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 7456911115..70cd4772d5 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -23,6 +23,12 @@ #include "soc/gdma_channel.h" #include "soc/soc.h" #include "esp_rom_sys.h" + +typedef enum { + ADC_EVENT_ADC1_DONE = BIT(0), + ADC_EVENT_ADC2_DONE = BIT(1), +} adc_hal_event_t; + #endif void adc_hal_init(void) @@ -41,18 +47,6 @@ void adc_hal_deinit(void) { adc_ll_set_power_manage(ADC_POWER_SW_OFF); } - -#ifndef CONFIG_IDF_TARGET_ESP32C3 -int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value) -{ - adc_ll_rtc_enable_channel(adc_n, channel); - adc_ll_rtc_start_convert(adc_n, channel); - while (adc_ll_rtc_convert_is_done(adc_n) != true); - *value = adc_ll_rtc_get_convert_value(adc_n); - return (int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*value)); -} -#endif - /*--------------------------------------------------------------- ADC calibration setting ---------------------------------------------------------------*/ @@ -99,15 +93,9 @@ static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel) #elif CONFIG_IDF_TARGET_ESP32C3 static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t atten, bool internal_gnd) { - adc_hal_set_controller(adc_n, ADC_CTRL_DIG); //Set controller - - adc_digi_config_t dig_cfg = { - .conv_limit_en = 0, - .conv_limit_num = 250, - .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, - }; - adc_hal_digi_controller_config(&dig_cfg); - + adc_ll_onetime_sample_enable(ADC_NUM_1, false); + adc_ll_onetime_sample_enable(ADC_NUM_2, false); + adc_ll_set_power_manage(ADC_POWER_SW_ON); /* Enable/disable internal connect GND (for calibration). */ if (internal_gnd) { const int esp32c3_invalid_chan = (adc_n == ADC_NUM_1)? 0xF: 0x1; @@ -116,8 +104,7 @@ static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t att adc_ll_onetime_set_channel(adc_n, channel); } adc_ll_onetime_set_atten(atten); - adc_hal_adc1_onetime_sample_enable((adc_n == ADC_NUM_1)); - adc_hal_adc2_onetime_sample_enable((adc_n == ADC_NUM_2)); + adc_ll_onetime_sample_enable(adc_n, true); } static uint32_t read_cal_channel(adc_ll_num_t adc_n, int channel) @@ -223,8 +210,8 @@ void adc_hal_digi_init(adc_hal_context_t *hal) gdma_ll_clear_interrupt_status(hal->dev, hal->dma_chan, UINT32_MAX); gdma_ll_enable_interrupt(hal->dev, hal->dma_chan, GDMA_LL_EVENT_RX_SUC_EOF, true); adc_ll_digi_dma_set_eof_num(hal->eof_num); - adc_ll_adc1_onetime_sample_enable(false); - adc_ll_adc2_onetime_sample_enable(false); + adc_ll_onetime_sample_enable(ADC_NUM_1, false); + adc_ll_onetime_sample_enable(ADC_NUM_2, false); } void adc_hal_fifo_reset(adc_hal_context_t *hal) @@ -309,7 +296,32 @@ void adc_hal_digi_stop(adc_hal_context_t *hal) /*--------------------------------------------------------------- Single Read ---------------------------------------------------------------*/ -void adc_hal_onetime_start(adc_digi_config_t *adc_digi_config) + +//--------------------INTR-------------------------------// +static adc_ll_intr_t get_event_intr(adc_hal_event_t event) +{ + adc_ll_intr_t intr_mask = 0; + if (event & ADC_EVENT_ADC1_DONE) { + intr_mask |= ADC_LL_INTR_ADC1_DONE; + } + if (event & ADC_EVENT_ADC2_DONE) { + intr_mask |= ADC_LL_INTR_ADC2_DONE; + } + return intr_mask; +} + +static void adc_hal_intr_clear(adc_hal_event_t event) +{ + adc_ll_intr_clear(get_event_intr(event)); +} + +static bool adc_hal_intr_get_raw(adc_hal_event_t event) +{ + return adc_ll_intr_get_raw(get_event_intr(event)); +} + +//--------------------Single Read-------------------------------// +static void adc_hal_onetime_start(void) { /** * 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 @@ -335,74 +347,54 @@ void adc_hal_onetime_start(adc_digi_config_t *adc_digi_config) //No need to delay here. Becuase if the start signal is not seen, there won't be a done intr. } -void adc_hal_adc1_onetime_sample_enable(bool enable) +static esp_err_t adc_hal_single_read(adc_ll_num_t adc_n, int *out_raw) { - adc_ll_adc1_onetime_sample_enable(enable); -} - -void adc_hal_adc2_onetime_sample_enable(bool enable) -{ - adc_ll_adc2_onetime_sample_enable(enable); -} - -void adc_hal_onetime_channel(adc_ll_num_t unit, adc_channel_t channel) -{ - adc_ll_onetime_set_channel(unit, channel); -} - -void adc_hal_set_onetime_atten(adc_atten_t atten) -{ - adc_ll_onetime_set_atten(atten); -} - -esp_err_t adc_hal_single_read(adc_ll_num_t unit, int *out_raw) -{ - if (unit == ADC_NUM_1) { + if (adc_n == ADC_NUM_1) { *out_raw = adc_ll_adc1_read(); - } else if (unit == ADC_NUM_2) { + } else if (adc_n == ADC_NUM_2) { *out_raw = adc_ll_adc2_read(); - if (adc_ll_analysis_raw_data(unit, *out_raw)) { + if (adc_ll_analysis_raw_data(adc_n, *out_raw)) { return ESP_ERR_INVALID_STATE; } } return ESP_OK; } -//--------------------INTR------------------------------- -static adc_ll_intr_t get_event_intr(adc_event_t event) +esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw) { - adc_ll_intr_t intr_mask = 0; - if (event & ADC_EVENT_ADC1_DONE) { - intr_mask |= ADC_LL_INTR_ADC1_DONE; + esp_err_t ret; + adc_hal_event_t event; + + if (adc_n == ADC_NUM_1) { + event = ADC_EVENT_ADC1_DONE; + } else { + event = ADC_EVENT_ADC2_DONE; } - if (event & ADC_EVENT_ADC2_DONE) { - intr_mask |= ADC_LL_INTR_ADC2_DONE; + + adc_hal_intr_clear(event); + adc_ll_onetime_sample_enable(adc_n, true); + adc_ll_onetime_set_channel(adc_n, channel); + + //Trigger single read. + adc_hal_onetime_start(); + while (!adc_hal_intr_get_raw(event)); + ret = adc_hal_single_read(adc_n, out_raw); + adc_ll_onetime_sample_enable(adc_n, false); + + return ret; +} +#else // !CONFIG_IDF_TARGET_ESP32C3 +esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw) +{ + adc_ll_rtc_enable_channel(adc_n, channel); + adc_ll_rtc_start_convert(adc_n, channel); + while (adc_ll_rtc_convert_is_done(adc_n) != true); + *out_raw = adc_ll_rtc_get_convert_value(adc_n); + + if ((int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*out_raw))) { + return ESP_ERR_INVALID_STATE; + } else { + return ESP_OK; } - return intr_mask; } - -void adc_hal_intr_enable(adc_event_t event) -{ - adc_ll_intr_enable(get_event_intr(event)); -} - -void adc_hal_intr_disable(adc_event_t event) -{ - adc_ll_intr_disable(get_event_intr(event)); -} - -void adc_hal_intr_clear(adc_event_t event) -{ - adc_ll_intr_clear(get_event_intr(event)); -} - -bool adc_hal_intr_get_raw(adc_event_t event) -{ - return adc_ll_intr_get_raw(get_event_intr(event)); -} - -bool adc_hal_intr_get_status(adc_event_t event) -{ - return adc_ll_intr_get_status(get_event_intr(event)); -} -#endif +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 diff --git a/components/hal/esp32c3/adc_hal.c b/components/hal/esp32c3/adc_hal.c index bec18db5fb..62ee07959c 100644 --- a/components/hal/esp32c3/adc_hal.c +++ b/components/hal/esp32c3/adc_hal.c @@ -72,7 +72,6 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg) } } - adc_ll_set_controller(pattern_both, ADC_CTRL_DIG); if (cfg->conv_limit_en) { adc_ll_digi_set_convert_limit_num(cfg->conv_limit_num); adc_ll_digi_convert_limit_enable(); diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 5ee33aed07..325380bf7d 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -54,8 +54,12 @@ typedef enum { } adc_ll_rtc_raw_data_t; typedef enum { - ADC_LL_INTR_ADC2_DONE = BIT(30), - ADC_LL_INTR_ADC1_DONE = BIT(31), + ADC_LL_INTR_THRES1_LOW = BIT(26), + ADC_LL_INTR_THRES0_LOW = BIT(27), + ADC_LL_INTR_THRES1_HIGH = BIT(28), + ADC_LL_INTR_THRES0_HIGH = BIT(29), + ADC_LL_INTR_ADC2_DONE = BIT(30), + ADC_LL_INTR_ADC1_DONE = BIT(31), } adc_ll_intr_t; FLAG_ATTR(adc_ll_intr_t) @@ -391,136 +395,6 @@ static inline void adc_ll_digi_monitor_disable(adc_digi_monitor_idx_t idx) } } -/** - * Enable interrupt of adc digital controller by bitmask. - * - * @param adc_n ADC unit. - * @param intr Interrupt bitmask. - */ -static inline void adc_ll_digi_intr_enable(adc_ll_num_t adc_n, adc_digi_intr_t intr) -{ - if (adc_n == ADC_NUM_1) { - if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { - APB_SARADC.int_ena.adc1_done = 1; - } - } else { // adc_n == ADC_NUM_2 - if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { - APB_SARADC.int_ena.adc2_done = 1; - } - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR0_HIGH) { - APB_SARADC.int_ena.thres0_high = 1; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR0_LOW) { - APB_SARADC.int_ena.thres0_low = 1; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR1_HIGH) { - APB_SARADC.int_ena.thres1_high = 1; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR1_LOW) { - APB_SARADC.int_ena.thres1_low = 1; - } -} - -/** - * Disable interrupt of adc digital controller by bitmask. - * - * @param adc_n ADC unit. - * @param intr Interrupt bitmask. - */ -static inline void adc_ll_digi_intr_disable(adc_ll_num_t adc_n, adc_digi_intr_t intr) -{ - if (adc_n == ADC_NUM_1) { - if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { - APB_SARADC.int_ena.adc1_done = 0; - } - } else { // adc_n == ADC_NUM_2 - if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { - APB_SARADC.int_ena.adc2_done = 0; - } - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR0_HIGH) { - APB_SARADC.int_ena.thres0_high = 0; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR0_LOW) { - APB_SARADC.int_ena.thres0_low = 0; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR1_HIGH) { - APB_SARADC.int_ena.thres1_high = 0; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR1_LOW) { - APB_SARADC.int_ena.thres1_low = 0; - } -} - -/** - * Clear interrupt of adc digital controller by bitmask. - * - * @param adc_n ADC unit. - * @param intr Interrupt bitmask. - */ -static inline void adc_ll_digi_intr_clear(adc_ll_num_t adc_n, adc_digi_intr_t intr) -{ - if (adc_n == ADC_NUM_1) { - if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { - APB_SARADC.int_clr.adc1_done = 1; - } - } else { // adc_n == ADC_NUM_2 - if (intr & ADC_DIGI_INTR_MASK_MEAS_DONE) { - APB_SARADC.int_clr.adc2_done = 1; - } - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR0_HIGH) { - APB_SARADC.int_clr.thres0_high = 1; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR0_LOW) { - APB_SARADC.int_clr.thres0_low = 1; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR1_HIGH) { - APB_SARADC.int_clr.thres1_high = 1; - } - if (intr & ADC_DIGI_INTR_MASK_MONITOR1_LOW) { - APB_SARADC.int_clr.thres1_low = 1; - } -} - -/** - * Get interrupt status mask of adc digital controller. - * - * @param adc_n ADC unit. - * @return - * - intr Interrupt bitmask. - */ -static inline uint32_t adc_ll_digi_get_intr_status(adc_ll_num_t adc_n) -{ - uint32_t int_st = APB_SARADC.int_st.val; - uint32_t ret_msk = 0; - - if (adc_n == ADC_NUM_1) { - if (int_st & APB_SARADC_ADC1_DONE_INT_ST_M) { - ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE; - } - } else { // adc_n == ADC_NUM_2 - if (int_st & APB_SARADC_ADC2_DONE_INT_ST_M) { - ret_msk |= ADC_DIGI_INTR_MASK_MEAS_DONE; - } - } - if (int_st & APB_SARADC_THRES0_HIGH_INT_ST) { - ret_msk |= ADC_DIGI_INTR_MASK_MONITOR0_HIGH; - } - if (int_st & APB_SARADC_THRES0_LOW_INT_ST_M) { - ret_msk |= ADC_DIGI_INTR_MASK_MONITOR0_LOW; - } - if (int_st & APB_SARADC_THRES1_HIGH_INT_ST_M) { - ret_msk |= ADC_DIGI_INTR_MASK_MONITOR1_HIGH; - } - if (int_st & APB_SARADC_THRES1_LOW_INT_ST_M) { - ret_msk |= ADC_DIGI_INTR_MASK_MONITOR1_LOW; - } - - return ret_msk; -} - /** * Set DMA eof num of adc digital controller. * If the number of measurements reaches `dma_eof_num`, then `dma_in_suc_eof` signal is generated. @@ -653,17 +527,6 @@ static inline adc_ll_power_t adc_ll_get_power_manage(void) return manage; } -/** - * Set ADC module controller. - * @param adc_n ADC unit. - * @param ctrl ADC controller. - */ -static inline void adc_ll_set_controller(adc_ll_num_t adc_n, adc_ll_controller_t ctrl) -{ - //This is for chip version compability. On esp32c3, the ADC1 is only controlled by digital controller, whereas ADC2 controller is - //auto-selected by arbiter according to the priority. -} - /** * Set ADC2 module arbiter work mode. * The arbiter is to improve the use efficiency of ADC2. After the control right is robbed by the high priority, @@ -911,10 +774,13 @@ static inline bool adc_ll_intr_get_status(adc_ll_intr_t mask) return (APB_SARADC.int_st.val & mask); } -//--------------------------------adc1------------------------------// -static inline void adc_ll_adc1_onetime_sample_enable(bool enable) +static inline void adc_ll_onetime_sample_enable(adc_ll_num_t adc_n, bool enable) { - APB_SARADC.onetime_sample.adc1_onetime_sample = enable; + if (adc_n == ADC_NUM_1) { + APB_SARADC.onetime_sample.adc1_onetime_sample = enable; + } else { + APB_SARADC.onetime_sample.adc2_onetime_sample = enable; + } } static inline uint32_t adc_ll_adc1_read(void) @@ -923,12 +789,6 @@ static inline uint32_t adc_ll_adc1_read(void) return (APB_SARADC.apb_saradc1_data_status.adc1_data & 0xfff); } -//--------------------------------adc2------------------------------// -static inline void adc_ll_adc2_onetime_sample_enable(bool enable) -{ - APB_SARADC.onetime_sample.adc2_onetime_sample = enable; -} - static inline uint32_t adc_ll_adc2_read(void) { //On ESP32C3, valid data width is 12-bit diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index 4754074154..badf7fdb0a 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -3,6 +3,7 @@ #include "soc/soc_caps.h" #include "hal/adc_types.h" #include "hal/adc_ll.h" +#include "esp_err.h" #if CONFIG_IDF_TARGET_ESP32C3 #include "soc/gdma_struct.h" @@ -62,14 +63,6 @@ void adc_hal_init(void); */ void adc_hal_deinit(void); -/** - * Set adc sample cycle. - * - * @note Normally, please use default value. - * @param sample_cycle The number of ADC sampling cycles. Range: 1 ~ 7. - */ -#define adc_hal_set_sample_cycle(sample_cycle) adc_ll_set_sample_cycle(sample_cycle) - /** * Set ADC module power management. * @@ -77,14 +70,6 @@ void adc_hal_deinit(void); */ #define adc_hal_set_power_manage(manage) adc_ll_set_power_manage(manage) -/** - * Get ADC module power management. - * - * @return - * - ADC power status. - */ -#define adc_hal_get_power_manage() adc_ll_get_power_manage() - /** * ADC module clock division factor setting. ADC clock devided from APB clock. * @@ -92,6 +77,7 @@ void adc_hal_deinit(void); */ #define adc_hal_digi_set_clk_div(div) adc_ll_digi_set_clk_div(div) +#if !CONFIG_IDF_TARGET_ESP32C3 /** * ADC SAR clock division factor setting. ADC SAR clock devided from `RTC_FAST_CLK`. * @@ -110,7 +96,106 @@ void adc_hal_deinit(void); * @prarm ctrl ADC controller. */ #define adc_hal_set_controller(adc_n, ctrl) adc_ll_set_controller(adc_n, ctrl) +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +/** + * Get the attenuation of a particular channel on ADCn. + * + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @return atten The attenuation option. + */ +#define adc_hal_get_atten(adc_n, channel) adc_ll_get_atten(adc_n, channel) +#endif + +#if CONFIG_IDF_TARGET_ESP32 +/** + * Close ADC AMP module if don't use it for power save. + */ +#define adc_hal_amp_disable() adc_ll_amp_disable() +#endif + +/*--------------------------------------------------------------- + PWDET(Power detect) controller setting +---------------------------------------------------------------*/ + +/** + * Set adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @prarm cct Range: 0 ~ 7. + */ +#define adc_hal_pwdet_set_cct(cct) adc_ll_pwdet_set_cct(cct) + +/** + * Get adc cct for PWDET controller. + * + * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. + * @return cct Range: 0 ~ 7. + */ +#define adc_hal_pwdet_get_cct() adc_ll_pwdet_get_cct() + +/*--------------------------------------------------------------- + RTC controller setting +---------------------------------------------------------------*/ +#if !CONFIG_IDF_TARGET_ESP32C3 +/** + * Set adc output data format for RTC controller. + * + * @prarm adc_n ADC unit. + * @prarm bits Output data bits width option. + */ +#define adc_hal_rtc_set_output_format(adc_n, bits) adc_ll_rtc_set_output_format(adc_n, bits) + +/** + * ADC module output data invert or not. + * + * @prarm adc_n ADC unit. + */ +#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en) + +/** + * Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels. + * + * This function routes the internal reference voltage of ADCn to one of + * ADC2's channels. This reference voltage can then be manually measured + * for calibration purposes. + * + * @note ESP32 only supports output of ADC2's internal reference voltage. + * @param[in] adc ADC unit select + * @param[in] channel ADC2 channel number + * @param[in] en Enable/disable the reference voltage output + */ +#define adc_hal_vref_output(adc, channel, en) adc_ll_vref_output(adc, channel, en) +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 + +/*--------------------------------------------------------------- + Digital controller setting +---------------------------------------------------------------*/ +/** + * Digital controller deinitialization. + */ +void adc_hal_digi_deinit(void); + +/** + * Setting the digital controller. + * + * @param cfg Pointer to digital controller paramter. + */ +void adc_hal_digi_controller_config(const adc_digi_config_t *cfg); + +/** + * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. + * + * @param adc_n ADC unit. + */ +#define adc_hal_digi_clear_pattern_table(adc_n) adc_ll_digi_clear_pattern_table(adc_n) + +/*--------------------------------------------------------------- + ADC Single Read +---------------------------------------------------------------*/ +#if !CONFIG_IDF_TARGET_ESP32C3 /** * Set the attenuation of a particular channel on ADCn. * @@ -140,117 +225,39 @@ void adc_hal_deinit(void); * * For maximum accuracy, use the ADC calibration APIs and measure voltages within these recommended ranges. * - * @prarm adc_n ADC unit. - * @prarm channel ADCn channel number. - * @prarm atten The attenuation option. + * @param adc_n ADC unit. + * @param channel ADCn channel number. + * @param atten ADC attenuation. See ``adc_atten_t`` */ #define adc_hal_set_atten(adc_n, channel, atten) adc_ll_set_atten(adc_n, channel, atten) +#else // CONFIG_IDF_TARGET_ESP32C3 /** - * Get the attenuation of a particular channel on ADCn. + * Set the attenuation for ADC to single read * - * @param adc_n ADC unit. - * @param channel ADCn channel number. - * @return atten The attenuation option. - */ -#define adc_hal_get_atten(adc_n, channel) adc_ll_get_atten(adc_n, channel) - -/** - * Close ADC AMP module if don't use it for power save. - */ -#define adc_hal_amp_disable() adc_ll_amp_disable() - -/*--------------------------------------------------------------- - PWDET(Power detect) controller setting ----------------------------------------------------------------*/ - -/** - * Set adc cct for PWDET controller. + * @note All ADC units and channels will share the setting. So PLEASE DO save your attenuations and reset them by calling this API again in your driver * - * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. - * @prarm cct Range: 0 ~ 7. + * @param adc_n Not used, leave here for chip version compatibility + * @param channel Not used, leave here for chip version compatibility + * @param atten ADC attenuation. See ``adc_atten_t`` */ -#define adc_hal_pwdet_set_cct(cct) adc_ll_pwdet_set_cct(cct) - -/** - * Get adc cct for PWDET controller. - * - * @note Capacitor tuning of the PA power monitor. cct set to the same value with PHY. - * @return cct Range: 0 ~ 7. - */ -#define adc_hal_pwdet_get_cct() adc_ll_pwdet_get_cct() - -#ifndef CONFIG_IDF_TARGET_ESP32C3 -/*--------------------------------------------------------------- - RTC controller setting ----------------------------------------------------------------*/ +#define adc_hal_set_atten(adc_n, channel, atten) adc_ll_onetime_set_atten(atten) +#endif /** * Get the converted value for each ADCn for RTC controller. * * @note It may be block to wait conversion finish. * - * @prarm adc_n ADC unit. - * @param channel adc channel number. - * @param value Pointer for touch value. + * @param adc_n ADC unit. + * @param channel ADC channel number. + * @param[out] out_raw ADC converted result * * @return - * - 0: The value is valid. - * - ~0: The value is invalid. + * - ESP_OK: The value is valid. + * - ESP_ERR_INVALID_STATE: The value is invalid. */ -int adc_hal_convert(adc_ll_num_t adc_n, int channel, int *value); - -/** - * Set adc output data format for RTC controller. - * - * @prarm adc_n ADC unit. - * @prarm bits Output data bits width option. - */ -#define adc_hal_rtc_set_output_format(adc_n, bits) adc_ll_rtc_set_output_format(adc_n, bits) - -/** - * ADC module output data invert or not. - * - * @prarm adc_n ADC unit. - */ -#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en) -#endif - -/** - * Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels. - * - * This function routes the internal reference voltage of ADCn to one of - * ADC2's channels. This reference voltage can then be manually measured - * for calibration purposes. - * - * @note ESP32 only supports output of ADC2's internal reference voltage. - * @param[in] adc ADC unit select - * @param[in] channel ADC2 channel number - * @param[in] en Enable/disable the reference voltage output - */ -#define adc_hal_vref_output(adc, channel, en) adc_ll_vref_output(adc, channel, en) - -/*--------------------------------------------------------------- - Digital controller setting ----------------------------------------------------------------*/ -/** - * Digital controller deinitialization. - */ -void adc_hal_digi_deinit(void); - -/** - * Setting the digital controller. - * - * @param cfg Pointer to digital controller paramter. - */ -void adc_hal_digi_controller_config(const adc_digi_config_t *cfg); - -/** - * Reset the pattern table pointer, then take the measurement rule from table header in next measurement. - * - * @param adc_n ADC unit. - */ -#define adc_hal_digi_clear_pattern_table(adc_n) adc_ll_digi_clear_pattern_table(adc_n) +esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw); /*--------------------------------------------------------------- ADC calibration setting @@ -376,30 +383,4 @@ void adc_hal_digi_dis_intr(adc_hal_context_t *hal, uint32_t mask); */ void adc_hal_digi_stop(adc_hal_context_t *hal); - -/*--------------------------------------------------------------- - Single Read ----------------------------------------------------------------*/ -void adc_hal_onetime_start(adc_digi_config_t *adc_digi_config); - -void adc_hal_adc1_onetime_sample_enable(bool enable); - -void adc_hal_adc2_onetime_sample_enable(bool enable); - -void adc_hal_onetime_channel(adc_ll_num_t unit, adc_channel_t channel); - -void adc_hal_set_onetime_atten(adc_atten_t atten); - -esp_err_t adc_hal_single_read(adc_ll_num_t unit, int *out_raw); - -void adc_hal_intr_enable(adc_event_t event); - -void adc_hal_intr_disable(adc_event_t event); - -void adc_hal_intr_clear(adc_event_t event); - -bool adc_hal_intr_get_raw(adc_event_t event); - -bool adc_hal_intr_get_status(adc_event_t event); - #endif //#if CONFIG_IDF_TARGET_ESP32C3 diff --git a/components/hal/include/hal/adc_types.h b/components/hal/include/hal/adc_types.h index feb1fde0b6..be0f3c67c8 100644 --- a/components/hal/include/hal/adc_types.h +++ b/components/hal/include/hal/adc_types.h @@ -223,6 +223,7 @@ typedef struct { } adc_digi_clk_t; #endif //!CONFIG_IDF_TARGET_ESP32 + /** * @brief ADC digital controller (DMA mode) configuration parameters. * @@ -294,6 +295,18 @@ typedef struct { #endif } adc_digi_config_t; +#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 +/** + * @brief ADC digital controller (DMA mode) interrupt type options. + */ +typedef enum { + ADC_DIGI_INTR_MASK_MONITOR = 0x1, + ADC_DIGI_INTR_MASK_MEAS_DONE = 0x2, + ADC_DIGI_INTR_MASK_ALL = 0x3, +} adc_digi_intr_t; +FLAG_ATTR(adc_digi_intr_t) +#endif + #if !CONFIG_IDF_TARGET_ESP32 /** @@ -332,24 +345,6 @@ typedef struct { .pwdet_pri = 2, \ } -/** - * @brief ADC digital controller (DMA mode) interrupt type options. - */ -typedef enum { -#if CONFIG_IDF_TARGET_ESP32C3 - ADC_DIGI_INTR_MASK_MONITOR0_HIGH = BIT(0), - ADC_DIGI_INTR_MASK_MONITOR0_LOW = BIT(1), - ADC_DIGI_INTR_MASK_MONITOR1_HIGH = BIT(2), - ADC_DIGI_INTR_MASK_MONITOR1_LOW = BIT(3), - ADC_DIGI_INTR_MASK_MEAS_DONE = BIT(4), -#else - ADC_DIGI_INTR_MASK_MONITOR = 0x1, - ADC_DIGI_INTR_MASK_MEAS_DONE = 0x2, - ADC_DIGI_INTR_MASK_ALL = 0x3, -#endif -} adc_digi_intr_t; -FLAG_ATTR(adc_digi_intr_t) - /** * @brief ADC digital controller (DMA mode) filter index options. * @@ -444,10 +439,3 @@ typedef struct { } adc_digi_monitor_t; #endif // CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 - -#if CONFIG_IDF_TARGET_ESP32C3 -typedef enum { - ADC_EVENT_ADC1_DONE = BIT(0), - ADC_EVENT_ADC2_DONE = BIT(1), -} adc_event_t; -#endif From a5295af829974c798359f9f4f8da557f56d69286 Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 23 Feb 2021 21:40:47 +0800 Subject: [PATCH 04/10] adc: update adc header files on c3 --- components/driver/include/driver/adc_common.h | 10 ++++- components/soc/esp32c3/adc_periph.c | 6 +-- .../soc/esp32c3/include/soc/adc_channel.h | 44 +------------------ components/soc/esp32c3/include/soc/soc_caps.h | 13 +----- 4 files changed, 12 insertions(+), 61 deletions(-) diff --git a/components/driver/include/driver/adc_common.h b/components/driver/include/driver/adc_common.h index 66b34a47b7..d2a13b6073 100644 --- a/components/driver/include/driver/adc_common.h +++ b/components/driver/include/driver/adc_common.h @@ -60,7 +60,7 @@ typedef enum { ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO1 */ ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO2 */ ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO3 */ - ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO34 */ + ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO4 */ ADC1_CHANNEL_MAX, } adc1_channel_t; #endif // CONFIG_IDF_TARGET_* @@ -186,9 +186,10 @@ void adc_power_release(void); esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel); /*--------------------------------------------------------------- - RTC controller setting + ADC Single Read Setting ---------------------------------------------------------------*/ +#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Get the GPIO number of a specific ADC1 channel. * @@ -200,6 +201,7 @@ esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel); * - ESP_ERR_INVALID_ARG if channel not valid */ esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num); +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Set the attenuation of a particular channel on ADC1, and configure its associated GPIO pin mux. @@ -283,6 +285,7 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit); */ int adc1_get_raw(adc1_channel_t channel); +#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Set ADC data invert * @param adc_unit ADC unit index @@ -336,6 +339,7 @@ void adc1_ulp_enable(void); * - ESP_ERR_INVALID_ARG if channel not valid */ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num); +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Configure the ADC2 channel, including setting attenuation. @@ -416,6 +420,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten); */ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out); +#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Output ADC1 or ADC2's reference voltage to ``adc2_channe_t``'s IO. * @@ -449,6 +454,7 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio); * - ESP_ERR_INVALID_ARG: Unsupported GPIO */ esp_err_t adc2_vref_to_gpio(gpio_num_t gpio) __attribute__((deprecated)); +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /*--------------------------------------------------------------- Digital controller setting ---------------------------------------------------------------*/ diff --git a/components/soc/esp32c3/adc_periph.c b/components/soc/esp32c3/adc_periph.c index 68a6bfa4dd..06a835d233 100644 --- a/components/soc/esp32c3/adc_periph.c +++ b/components/soc/esp32c3/adc_periph.c @@ -18,12 +18,10 @@ const int adc_channel_io_map[SOC_ADC_PERIPH_NUM][SOC_ADC_MAX_CHANNEL_NUM] = { /* ADC1 */ { - ADC1_CHANNEL_0_GPIO_NUM, ADC1_CHANNEL_1_GPIO_NUM, ADC1_CHANNEL_2_GPIO_NUM, ADC1_CHANNEL_3_GPIO_NUM, ADC1_CHANNEL_4_GPIO_NUM, - ADC1_CHANNEL_5_GPIO_NUM, ADC1_CHANNEL_6_GPIO_NUM, ADC1_CHANNEL_7_GPIO_NUM, -1, -1 + ADC1_CHANNEL_0_GPIO_NUM, ADC1_CHANNEL_1_GPIO_NUM, ADC1_CHANNEL_2_GPIO_NUM, ADC1_CHANNEL_3_GPIO_NUM, ADC1_CHANNEL_4_GPIO_NUM }, /* ADC2 */ { - ADC2_CHANNEL_0_GPIO_NUM, ADC2_CHANNEL_1_GPIO_NUM, ADC2_CHANNEL_2_GPIO_NUM, ADC2_CHANNEL_3_GPIO_NUM, ADC2_CHANNEL_4_GPIO_NUM, - ADC2_CHANNEL_5_GPIO_NUM, ADC2_CHANNEL_6_GPIO_NUM, ADC2_CHANNEL_7_GPIO_NUM, ADC2_CHANNEL_8_GPIO_NUM, ADC2_CHANNEL_9_GPIO_NUM + ADC2_CHANNEL_0_GPIO_NUM, -1, -1, -1, -1 } }; diff --git a/components/soc/esp32c3/include/soc/adc_channel.h b/components/soc/esp32c3/include/soc/adc_channel.h index 59cfeb6039..9a645006c4 100644 --- a/components/soc/esp32c3/include/soc/adc_channel.h +++ b/components/soc/esp32c3/include/soc/adc_channel.h @@ -30,49 +30,7 @@ #define ADC1_GPIO5_CHANNEL ADC1_CHANNEL_4 #define ADC1_CHANNEL_4_GPIO_NUM 4 -#define ADC1_GPIO6_CHANNEL ADC1_CHANNEL_5 -#define ADC1_CHANNEL_5_GPIO_NUM 5 - -#define ADC1_GPIO7_CHANNEL ADC1_CHANNEL_6 -#define ADC1_CHANNEL_6_GPIO_NUM 7 - -#define ADC1_GPIO8_CHANNEL ADC1_CHANNEL_7 -#define ADC1_CHANNEL_7_GPIO_NUM 8 - -#define ADC1_GPIO9_CHANNEL ADC1_CHANNEL_8 -#define ADC1_CHANNEL_8_GPIO_NUM 9 - -#define ADC1_GPIO10_CHANNEL ADC1_CHANNEL_9 -#define ADC1_CHANNEL_9_GPIO_NUM 10 - -#define ADC2_GPIO11_CHANNEL ADC2_CHANNEL_0 +#define ADC2_GPIO5_CHANNEL ADC2_CHANNEL_0 #define ADC2_CHANNEL_0_GPIO_NUM 5 -#define ADC2_GPIO12_CHANNEL ADC2_CHANNEL_1 -#define ADC2_CHANNEL_1_GPIO_NUM 6 - -#define ADC2_GPIO13_CHANNEL ADC2_CHANNEL_2 -#define ADC2_CHANNEL_2_GPIO_NUM 13 - -#define ADC2_GPIO14_CHANNEL ADC2_CHANNEL_3 -#define ADC2_CHANNEL_3_GPIO_NUM 14 - -#define ADC2_GPIO15_CHANNEL ADC2_CHANNEL_4 -#define ADC2_CHANNEL_4_GPIO_NUM 15 - -#define ADC2_GPIO16_CHANNEL ADC2_CHANNEL_5 -#define ADC2_CHANNEL_5_GPIO_NUM 16 - -#define ADC2_GPIO17_CHANNEL ADC2_CHANNEL_6 -#define ADC2_CHANNEL_6_GPIO_NUM 17 - -#define ADC2_GPIO18_CHANNEL ADC2_CHANNEL_7 -#define ADC2_CHANNEL_7_GPIO_NUM 18 - -#define ADC2_GPIO19_CHANNEL ADC2_CHANNEL_8 -#define ADC2_CHANNEL_8_GPIO_NUM 19 - -#define ADC2_GPIO20_CHANNEL ADC2_CHANNEL_9 -#define ADC2_CHANNEL_9_GPIO_NUM 20 - #endif diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index f85e20bed1..dbbf451393 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -45,17 +45,6 @@ #define SOC_TWAI_BRP_MIN 2 #define SOC_TWAI_BRP_MAX 32768 -#define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 5 : 1) -#define SOC_ADC_MAX_CHANNEL_NUM (10) - -/** - * Check if adc support digital controller (DMA) mode. - * @value - * - 1 : support; - * - 0 : not support; - */ -#define SOC_ADC_SUPPORT_DMA_MODE(PERIPH_NUM) 1 - /*--------------------------- SHA CAPS ---------------------------------------*/ /* Max amount of bytes in a single DMA operation is 4095, @@ -113,7 +102,7 @@ #define SOC_ADC_PERIPH_NUM (2) #define SOC_ADC_PATT_LEN_MAX (16) #define SOC_ADC_CHANNEL_NUM(PERIPH_NUM) ((PERIPH_NUM==0)? 5 : 1) -#define SOC_ADC_MAX_CHANNEL_NUM (10) +#define SOC_ADC_MAX_CHANNEL_NUM (5) #define SOC_ADC_MAX_BITWIDTH (12) #define SOC_ADC_DIGI_FILTER_NUM (2) #define SOC_ADC_DIGI_MONITOR_NUM (2) From e9995fe1659cc63612008e0858c52851b2e8ae44 Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 10 Mar 2021 12:01:00 +0800 Subject: [PATCH 05/10] adc: add pm_lock to adc driver on esp32c3 --- components/driver/esp32c3/adc.c | 31 +++++++++++++++++-- components/driver/include/driver/adc_common.h | 2 +- components/hal/adc_hal.c | 4 +-- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index b55e56e036..e2e236f664 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -19,6 +19,7 @@ #include "sdkconfig.h" #include "esp_intr_alloc.h" #include "esp_log.h" +#include "esp_pm.h" #include "sys/lock.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" @@ -96,6 +97,7 @@ typedef struct adc_digi_context_t { adc_atten_t adc1_atten; //Attenuation for ADC1. On this chip each ADC can only support one attenuation. adc_atten_t adc2_atten; //Attenuation for ADC2. On this chip each ADC can only support one attenuation. adc_digi_config_t digi_controller_config; //Digital Controller Configuration + esp_pm_lock_handle_t pm_lock; //For power management } adc_digi_context_t; static adc_digi_context_t *s_adc_digi_ctx = NULL; @@ -179,6 +181,13 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) goto cleanup; } +#if CONFIG_PM_ENABLE + ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_ctx->pm_lock); + if (ret != ESP_OK) { + goto cleanup; + } +#endif //CONFIG_PM_ENABLE + //init gpio pins if (init_config->adc1_chan_mask) { ret = adc_digi_gpio_init(ADC_NUM_1, init_config->adc1_chan_mask); @@ -272,7 +281,7 @@ static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx) adc_hal_digi_rxdma_start(&adc_digi_ctx->hal, adc_digi_ctx->rx_dma_buf, adc_digi_ctx->bytes_between_intr); } - if(taskAwoken == pdTRUE) { + if (taskAwoken == pdTRUE) { return true; } else { return false; @@ -295,6 +304,11 @@ esp_err_t adc_digi_start(void) } ADC_DIGI_LOCK_ACQUIRE(); +#if CONFIG_PM_ENABLE + // Lock APB frequency while ADC driver is in use + esp_pm_lock_acquire(s_adc_digi_ctx->pm_lock); +#endif + adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT(); if (s_adc_digi_ctx->use_adc1) { uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, ADC_CHANNEL_MAX, s_adc_digi_ctx->adc1_atten); @@ -337,6 +351,11 @@ esp_err_t adc_digi_stop(void) //stop DMA adc_hal_digi_rxdma_stop(&s_adc_digi_ctx->hal); adc_hal_digi_deinit(); +#if CONFIG_PM_ENABLE + if (s_adc_digi_ctx->pm_lock) { + esp_pm_lock_release(s_adc_digi_ctx->pm_lock); + } +#endif //CONFIG_PM_ENABLE ADC_DIGI_LOCK_RELEASE(); //When using SARADC2 module, this task needs to be protected from WIFI @@ -390,11 +409,17 @@ esp_err_t adc_digi_deinitialize(void) return ESP_ERR_INVALID_STATE; } - if(s_adc_digi_ctx->ringbuf_hdl) { + if (s_adc_digi_ctx->ringbuf_hdl) { vRingbufferDelete(s_adc_digi_ctx->ringbuf_hdl); s_adc_digi_ctx->ringbuf_hdl = NULL; } +#if CONFIG_PM_ENABLE + if (s_adc_digi_ctx->pm_lock) { + esp_pm_lock_delete(s_adc_digi_ctx->pm_lock); + } +#endif //CONFIG_PM_ENABLE + free(s_adc_digi_ctx->rx_dma_buf); free(s_adc_digi_ctx->hal.rx_desc); free(s_adc_digi_ctx->digi_controller_config.adc_pattern); @@ -527,7 +552,7 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config) 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]; + const adc_digi_pattern_table_t *pat = &config->adc_pattern[i]; if (pat->unit == ADC_NUM_1) { s_adc_digi_ctx->use_adc1 = 1; diff --git a/components/driver/include/driver/adc_common.h b/components/driver/include/driver/adc_common.h index d2a13b6073..b50dd9f21f 100644 --- a/components/driver/include/driver/adc_common.h +++ b/components/driver/include/driver/adc_common.h @@ -495,7 +495,7 @@ esp_err_t adc_digi_controller_config(const adc_digi_config_t *config); /** * @brief Initialize the Digital ADC. * - * @param init_config Pointer to Digital ADC initilisation config. Refer to ``adc_digi_init_config_t``. + * @param init_config Pointer to Digital ADC initilization config. Refer to ``adc_digi_init_config_t``. * * @return * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid. diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 70cd4772d5..9dc5e87fff 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -393,8 +393,8 @@ esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw) if ((int)adc_ll_rtc_analysis_raw_data(adc_n, (uint16_t)(*out_raw))) { return ESP_ERR_INVALID_STATE; - } else { - return ESP_OK; } + + return ESP_OK; } #endif //#if !CONFIG_IDF_TARGET_ESP32C3 From 0030179642ad033254e29150d80bc0aa4bc45e02 Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 10 Mar 2021 12:03:16 +0800 Subject: [PATCH 06/10] adc: rename adc related examples --- examples/peripherals/adc/{ => esp32_esp32s2}/adc/CMakeLists.txt | 0 examples/peripherals/adc/{ => esp32_esp32s2}/adc/Makefile | 0 examples/peripherals/adc/{ => esp32_esp32s2}/adc/README.md | 0 .../peripherals/adc/{ => esp32_esp32s2}/adc/main/CMakeLists.txt | 0 .../adc/{ => esp32_esp32s2}/adc/main/adc1_example_main.c | 0 .../peripherals/adc/{ => esp32_esp32s2}/adc/main/component.mk | 0 examples/peripherals/adc/{ => esp32_esp32s2}/adc2/CMakeLists.txt | 0 examples/peripherals/adc/{ => esp32_esp32s2}/adc2/Makefile | 0 examples/peripherals/adc/{ => esp32_esp32s2}/adc2/README.md | 0 .../peripherals/adc/{ => esp32_esp32s2}/adc2/main/CMakeLists.txt | 0 .../adc/{ => esp32_esp32s2}/adc2/main/Kconfig.projbuild | 0 .../adc/{ => esp32_esp32s2}/adc2/main/adc2_example_main.c | 0 .../peripherals/adc/{ => esp32_esp32s2}/adc2/main/component.mk | 0 examples/peripherals/adc/{ => esp32c3}/adc_dma/CMakeLists.txt | 0 examples/peripherals/adc/{ => esp32c3}/adc_dma/README.md | 0 .../peripherals/adc/{ => esp32c3}/adc_dma/main/CMakeLists.txt | 0 .../adc/{ => esp32c3}/adc_dma/main/adc_dma_example_main.c | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc/CMakeLists.txt (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc/Makefile (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc/README.md (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc/main/CMakeLists.txt (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc/main/adc1_example_main.c (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc/main/component.mk (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc2/CMakeLists.txt (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc2/Makefile (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc2/README.md (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc2/main/CMakeLists.txt (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc2/main/Kconfig.projbuild (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc2/main/adc2_example_main.c (100%) rename examples/peripherals/adc/{ => esp32_esp32s2}/adc2/main/component.mk (100%) rename examples/peripherals/adc/{ => esp32c3}/adc_dma/CMakeLists.txt (100%) rename examples/peripherals/adc/{ => esp32c3}/adc_dma/README.md (100%) rename examples/peripherals/adc/{ => esp32c3}/adc_dma/main/CMakeLists.txt (100%) rename examples/peripherals/adc/{ => esp32c3}/adc_dma/main/adc_dma_example_main.c (100%) diff --git a/examples/peripherals/adc/adc/CMakeLists.txt b/examples/peripherals/adc/esp32_esp32s2/adc/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/adc/CMakeLists.txt rename to examples/peripherals/adc/esp32_esp32s2/adc/CMakeLists.txt diff --git a/examples/peripherals/adc/adc/Makefile b/examples/peripherals/adc/esp32_esp32s2/adc/Makefile similarity index 100% rename from examples/peripherals/adc/adc/Makefile rename to examples/peripherals/adc/esp32_esp32s2/adc/Makefile diff --git a/examples/peripherals/adc/adc/README.md b/examples/peripherals/adc/esp32_esp32s2/adc/README.md similarity index 100% rename from examples/peripherals/adc/adc/README.md rename to examples/peripherals/adc/esp32_esp32s2/adc/README.md diff --git a/examples/peripherals/adc/adc/main/CMakeLists.txt b/examples/peripherals/adc/esp32_esp32s2/adc/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/adc/main/CMakeLists.txt rename to examples/peripherals/adc/esp32_esp32s2/adc/main/CMakeLists.txt diff --git a/examples/peripherals/adc/adc/main/adc1_example_main.c b/examples/peripherals/adc/esp32_esp32s2/adc/main/adc1_example_main.c similarity index 100% rename from examples/peripherals/adc/adc/main/adc1_example_main.c rename to examples/peripherals/adc/esp32_esp32s2/adc/main/adc1_example_main.c diff --git a/examples/peripherals/adc/adc/main/component.mk b/examples/peripherals/adc/esp32_esp32s2/adc/main/component.mk similarity index 100% rename from examples/peripherals/adc/adc/main/component.mk rename to examples/peripherals/adc/esp32_esp32s2/adc/main/component.mk diff --git a/examples/peripherals/adc/adc2/CMakeLists.txt b/examples/peripherals/adc/esp32_esp32s2/adc2/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/adc2/CMakeLists.txt rename to examples/peripherals/adc/esp32_esp32s2/adc2/CMakeLists.txt diff --git a/examples/peripherals/adc/adc2/Makefile b/examples/peripherals/adc/esp32_esp32s2/adc2/Makefile similarity index 100% rename from examples/peripherals/adc/adc2/Makefile rename to examples/peripherals/adc/esp32_esp32s2/adc2/Makefile diff --git a/examples/peripherals/adc/adc2/README.md b/examples/peripherals/adc/esp32_esp32s2/adc2/README.md similarity index 100% rename from examples/peripherals/adc/adc2/README.md rename to examples/peripherals/adc/esp32_esp32s2/adc2/README.md diff --git a/examples/peripherals/adc/adc2/main/CMakeLists.txt b/examples/peripherals/adc/esp32_esp32s2/adc2/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/adc2/main/CMakeLists.txt rename to examples/peripherals/adc/esp32_esp32s2/adc2/main/CMakeLists.txt diff --git a/examples/peripherals/adc/adc2/main/Kconfig.projbuild b/examples/peripherals/adc/esp32_esp32s2/adc2/main/Kconfig.projbuild similarity index 100% rename from examples/peripherals/adc/adc2/main/Kconfig.projbuild rename to examples/peripherals/adc/esp32_esp32s2/adc2/main/Kconfig.projbuild diff --git a/examples/peripherals/adc/adc2/main/adc2_example_main.c b/examples/peripherals/adc/esp32_esp32s2/adc2/main/adc2_example_main.c similarity index 100% rename from examples/peripherals/adc/adc2/main/adc2_example_main.c rename to examples/peripherals/adc/esp32_esp32s2/adc2/main/adc2_example_main.c diff --git a/examples/peripherals/adc/adc2/main/component.mk b/examples/peripherals/adc/esp32_esp32s2/adc2/main/component.mk similarity index 100% rename from examples/peripherals/adc/adc2/main/component.mk rename to examples/peripherals/adc/esp32_esp32s2/adc2/main/component.mk diff --git a/examples/peripherals/adc/adc_dma/CMakeLists.txt b/examples/peripherals/adc/esp32c3/adc_dma/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/adc_dma/CMakeLists.txt rename to examples/peripherals/adc/esp32c3/adc_dma/CMakeLists.txt diff --git a/examples/peripherals/adc/adc_dma/README.md b/examples/peripherals/adc/esp32c3/adc_dma/README.md similarity index 100% rename from examples/peripherals/adc/adc_dma/README.md rename to examples/peripherals/adc/esp32c3/adc_dma/README.md diff --git a/examples/peripherals/adc/adc_dma/main/CMakeLists.txt b/examples/peripherals/adc/esp32c3/adc_dma/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/adc_dma/main/CMakeLists.txt rename to examples/peripherals/adc/esp32c3/adc_dma/main/CMakeLists.txt diff --git a/examples/peripherals/adc/adc_dma/main/adc_dma_example_main.c b/examples/peripherals/adc/esp32c3/adc_dma/main/adc_dma_example_main.c similarity index 100% rename from examples/peripherals/adc/adc_dma/main/adc_dma_example_main.c rename to examples/peripherals/adc/esp32c3/adc_dma/main/adc_dma_example_main.c From 6f4d992ac7865665da9fc885bfd7a780e865e389 Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 15 Mar 2021 16:12:08 +0800 Subject: [PATCH 07/10] adc: update lock scope on esp32c3 --- components/driver/esp32c3/adc.c | 74 +++++++++++++++++---------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index e2e236f664..5b3497a0c1 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -59,30 +59,28 @@ extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate posi #define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock) #define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock) -/*--------------------------------------------------------------- - Digital Controller Context ----------------------------------------------------------------*/ /** - * 1. adc_digi_mutex: this mutex lock is used for ADC digital controller. On ESP32-C3, the ADC single read APIs (unit1 & unit2) - * and ADC DMA continuous read APIs share the ``apb_saradc_struct.h`` regs. - * - * 2. sar_adc_mutex: this mutex lock is used for SARADC2 module. On ESP32C-C3, the ADC single read APIs (unit2), ADC DMA - * continuous read APIs and WIFI share the SARADC2 analog IP. - * - * Sequence: - * Acquire: 1. sar_adc_mutex; 2. adc_digi_mutex; - * Release: 1. adc_digi_mutex; 2. sar_adc_mutex; + * 1. sar_adc1_lock: this mutex lock is to protect the SARADC1 module. + * 2. sar_adc2_lock: this mutex lock is to protect the SARADC2 module. On C3, it is controlled by the digital controller + * and PWDET controller. + * 3. adc_reg_lock: this spin lock is to protect the shared registers used by ADC1 / ADC2 single read mode. */ -static _lock_t adc_digi_mutex; -#define ADC_DIGI_LOCK_ACQUIRE() _lock_acquire(&adc_digi_mutex) -#define ADC_DIGI_LOCK_RELEASE() _lock_release(&adc_digi_mutex) -static _lock_t sar_adc2_mutex; -#define SAC_ADC2_LOCK_ACQUIRE() _lock_acquire(&sar_adc2_mutex) -#define SAC_ADC2_LOCK_RELEASE() _lock_release(&sar_adc2_mutex) +static _lock_t sar_adc1_lock; +#define SAR_ADC1_LOCK_ACQUIRE() _lock_acquire(&sar_adc1_lock) +#define SAR_ADC1_LOCK_RELEASE() _lock_release(&sar_adc1_lock) +static _lock_t sar_adc2_lock; +#define SAR_ADC2_LOCK_ACQUIRE() _lock_acquire(&sar_adc2_lock) +#define SAR_ADC2_LOCK_RELEASE() _lock_release(&sar_adc2_lock) +portMUX_TYPE adc_reg_lock = portMUX_INITIALIZER_UNLOCKED; +#define ADC_REG_LOCK_ENTER() portENTER_CRITICAL(&adc_reg_lock) +#define ADC_REG_LOCK_EXIT() portEXIT_CRITICAL(&adc_reg_lock) #define INTERNAL_BUF_NUM 5 #define IN_SUC_EOF_BIT GDMA_LL_EVENT_RX_SUC_EOF +/*--------------------------------------------------------------- + Digital Controller Context +---------------------------------------------------------------*/ typedef struct adc_digi_context_t { uint32_t bytes_between_intr; //bytes between in suc eof intr uint8_t *rx_dma_buf; //dma buffer @@ -298,11 +296,14 @@ esp_err_t adc_digi_start(void) s_adc_digi_ctx->ringbuf_overflow_flag = 0; s_adc_digi_ctx->driver_start_flag = 1; - //When using SARADC2 module, this task needs to be protected from WIFI - if (s_adc_digi_ctx->use_adc2) { - SAC_ADC2_LOCK_ACQUIRE(); + esp_rom_printf("adc start\n"); + + if (s_adc_digi_ctx->use_adc1) { + SAR_ADC1_LOCK_ACQUIRE(); + } + if (s_adc_digi_ctx->use_adc2) { + SAR_ADC2_LOCK_ACQUIRE(); } - ADC_DIGI_LOCK_ACQUIRE(); #if CONFIG_PM_ENABLE // Lock APB frequency while ADC driver is in use @@ -357,10 +358,11 @@ esp_err_t adc_digi_stop(void) } #endif //CONFIG_PM_ENABLE - ADC_DIGI_LOCK_RELEASE(); - //When using SARADC2 module, this task needs to be protected from WIFI + if (s_adc_digi_ctx->use_adc1) { + SAR_ADC1_LOCK_RELEASE(); + } if (s_adc_digi_ctx->use_adc2) { - SAC_ADC2_LOCK_RELEASE(); + SAR_ADC2_LOCK_RELEASE(); } return ESP_OK; @@ -468,20 +470,22 @@ int adc1_get_raw(adc1_channel_t channel) { int raw_out = 0; - ADC_DIGI_LOCK_ACQUIRE(); + SAR_ADC1_LOCK_ACQUIRE(); periph_module_enable(PERIPH_SARADC_MODULE); adc_atten_t atten = s_atten1_single[channel]; uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, channel, atten); - adc_hal_set_calibration_param(ADC_NUM_1, cal_val); + ADC_REG_LOCK_ENTER(); + adc_hal_set_calibration_param(ADC_NUM_1, cal_val); adc_hal_set_power_manage(ADC_POWER_SW_ON); adc_hal_set_atten(ADC_NUM_2, channel, atten); adc_hal_convert(ADC_NUM_1, channel, &raw_out); + adc_hal_set_power_manage(ADC_POWER_BY_FSM); + ADC_REG_LOCK_EXIT(); - adc_hal_set_power_manage(ADC_POWER_SW_OFF); periph_module_disable(PERIPH_SARADC_MODULE); - ADC_DIGI_LOCK_RELEASE(); + SAR_ADC1_LOCK_RELEASE(); return raw_out; } @@ -509,22 +513,22 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * esp_err_t ret = ESP_OK; - SAC_ADC2_LOCK_ACQUIRE(); - ADC_DIGI_LOCK_ACQUIRE(); + SAR_ADC2_LOCK_ACQUIRE(); periph_module_enable(PERIPH_SARADC_MODULE); adc_atten_t atten = s_atten2_single[channel]; uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, channel, atten); - adc_hal_set_calibration_param(ADC_NUM_2, cal_val); + ADC_REG_LOCK_ENTER(); + adc_hal_set_calibration_param(ADC_NUM_2, cal_val); adc_hal_set_power_manage(ADC_POWER_SW_ON); adc_hal_set_atten(ADC_NUM_2, channel, atten); ret = adc_hal_convert(ADC_NUM_2, channel, raw_out); + adc_hal_set_power_manage(ADC_POWER_BY_FSM); + ADC_REG_LOCK_EXIT(); - adc_hal_set_power_manage(ADC_POWER_SW_OFF); periph_module_disable(PERIPH_SARADC_MODULE); - ADC_DIGI_LOCK_RELEASE(); - SAC_ADC2_LOCK_RELEASE(); + SAR_ADC2_LOCK_RELEASE(); return ret; } From 2bb9bd5fb27bbec7fdc25e015223428a0cf5c0db Mon Sep 17 00:00:00 2001 From: Armando Date: Fri, 19 Mar 2021 15:19:41 +0800 Subject: [PATCH 08/10] adc: update adc programming guide to avoid build fail --- docs/en/api-reference/peripherals/adc.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/api-reference/peripherals/adc.rst b/docs/en/api-reference/peripherals/adc.rst index abba6594dc..10cd395302 100644 --- a/docs/en/api-reference/peripherals/adc.rst +++ b/docs/en/api-reference/peripherals/adc.rst @@ -76,7 +76,7 @@ Reading voltage on ADC1 channel 0 ({IDF_TARGET_ADC1_CH0}):: int val = adc1_get_raw(ADC1_CHANNEL_0); The input voltage in the above example is from 0 to 1.1 V (0 dB attenuation). The input range can be extended by setting a higher attenuation, see :cpp:type:`adc_atten_t`. -An example of using the ADC driver including calibration (discussed below) is available at esp-idf: :example:`peripherals/adc/adc` +An example of using the ADC driver including calibration (discussed below) is available at esp-idf: :example:`peripherals/adc` Reading voltage on ADC2 channel 7 ({IDF_TARGET_ADC2_CH7}):: @@ -95,7 +95,7 @@ Reading voltage on ADC2 channel 7 ({IDF_TARGET_ADC2_CH7}):: } The reading may fail due to collision with Wi-Fi, should check it. -An example using the ADC2 driver to read the output of DAC is available in esp-idf: :example:`peripherals/adc/adc2` +An example using the ADC2 driver to read the output of DAC is available in esp-idf: :example:`peripherals/adc` .. only:: esp32 From 0e0baee25a567f2d45c867fa14e0aca7c4d3ac37 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 25 Mar 2021 19:04:38 +0800 Subject: [PATCH 09/10] adc: add implementation of missed public API Added ``adc1_pad_get_io_num``, ``adc2_pad_get_io_num`` and ``adc_vref_to_gpio``. --- components/driver/adc_common.c | 56 +++++++-------- components/driver/esp32c3/adc.c | 72 +++++++++++++------ components/driver/include/driver/adc_common.h | 10 ++- components/hal/adc_hal.c | 19 ++--- components/hal/esp32c3/include/hal/adc_ll.h | 1 + components/hal/include/hal/adc_hal.h | 22 +++--- 6 files changed, 104 insertions(+), 76 deletions(-) diff --git a/components/driver/adc_common.c b/components/driver/adc_common.c index 81030a57cf..eb5a9ab673 100644 --- a/components/driver/adc_common.c +++ b/components/driver/adc_common.c @@ -202,6 +202,33 @@ void adc_power_off(void) ADC_POWER_EXIT(); } +esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num) +{ + ADC_CHANNEL_CHECK(ADC_NUM_1, channel); + + int io = ADC_GET_IO_NUM(ADC_NUM_1, channel); + if (io < 0) { + return ESP_ERR_INVALID_ARG; + } else { + *gpio_num = (gpio_num_t)io; + } + + return ESP_OK; +} + +esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num) +{ + ADC_CHANNEL_CHECK(ADC_NUM_2, channel); + + int io = ADC_GET_IO_NUM(ADC_NUM_2, channel); + if (io < 0) { + return ESP_ERR_INVALID_ARG; + } else { + *gpio_num = (gpio_num_t)io; + } + + return ESP_OK; +} #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 esp_err_t adc_set_clk_div(uint8_t clk_div) @@ -313,20 +340,6 @@ esp_err_t adc_rtc_reset(void) /*------------------------------------------------------------------------------------- * ADC1 *------------------------------------------------------------------------------------*/ -esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num) -{ - ADC_CHANNEL_CHECK(ADC_NUM_1, channel); - - int io = ADC_GET_IO_NUM(ADC_NUM_1, channel); - if (io < 0) { - return ESP_ERR_INVALID_ARG; - } else { - *gpio_num = (gpio_num_t)io; - } - - return ESP_OK; -} - esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) { ADC_CHANNEL_CHECK(ADC_NUM_1, channel); @@ -456,20 +469,6 @@ void adc1_ulp_enable(void) /*--------------------------------------------------------------- ADC2 ---------------------------------------------------------------*/ -esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num) -{ - ADC_CHANNEL_CHECK(ADC_NUM_2, channel); - - int io = ADC_GET_IO_NUM(ADC_NUM_2, channel); - if (io < 0) { - return ESP_ERR_INVALID_ARG; - } else { - *gpio_num = (gpio_num_t)io; - } - - return ESP_OK; -} - /** For ESP32S2 the ADC2 The right to use ADC2 is controlled by the arbiter, and there is no need to set a lock.*/ esp_err_t adc2_wifi_acquire(void) { @@ -594,7 +593,6 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * ret = adc_hal_convert(ADC_NUM_2, channel, &adc_value); if (ret != ESP_OK) { - ESP_LOGD( ADC_TAG, "ADC2 ARB: Return data is invalid." ); adc_value = -1; } diff --git a/components/driver/esp32c3/adc.c b/components/driver/esp32c3/adc.c index 5b3497a0c1..7a52a1d4bf 100644 --- a/components/driver/esp32c3/adc.c +++ b/components/driver/esp32c3/adc.c @@ -82,7 +82,6 @@ portMUX_TYPE adc_reg_lock = portMUX_INITIALIZER_UNLOCKED; Digital Controller Context ---------------------------------------------------------------*/ typedef struct adc_digi_context_t { - uint32_t bytes_between_intr; //bytes between in suc eof intr uint8_t *rx_dma_buf; //dma buffer adc_hal_context_t hal; //hal context gdma_channel_handle_t rx_dma_channel; //dma rx channel handle @@ -158,8 +157,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) } //malloc internal buffer used by DMA - s_adc_digi_ctx->bytes_between_intr = init_config->conv_num_each_intr; - s_adc_digi_ctx->rx_dma_buf = heap_caps_calloc(1, s_adc_digi_ctx->bytes_between_intr * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL); + s_adc_digi_ctx->rx_dma_buf = heap_caps_calloc(1, init_config->conv_num_each_intr * INTERNAL_BUF_NUM, MALLOC_CAP_INTERNAL); if (!s_adc_digi_ctx->rx_dma_buf) { ret = ESP_ERR_NO_MEM; goto cleanup; @@ -227,7 +225,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) adc_hal_config_t config = { .desc_max_num = INTERNAL_BUF_NUM, .dma_chan = dma_chan, - .eof_num = s_adc_digi_ctx->bytes_between_intr / 4 + .eof_num = init_config->conv_num_each_intr / ADC_HAL_DATA_LEN_PER_CONV }; adc_hal_context_config(&s_adc_digi_ctx->hal, &config); @@ -249,6 +247,7 @@ static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx); static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) { + assert(event_data); adc_digi_context_t *adc_digi_ctx = (adc_digi_context_t *)user_data; adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr; return adc_dma_intr(adc_digi_ctx); @@ -263,7 +262,7 @@ static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx) while (1) { status = adc_hal_get_reading_result(&adc_digi_ctx->hal, adc_digi_ctx->rx_eof_desc_addr, ¤t_desc); - if (status != ADC_DMA_DESC_FINISH) { + if (status != ADC_HAL_DMA_DESC_VALID) { break; } @@ -274,16 +273,12 @@ static IRAM_ATTR bool adc_dma_intr(adc_digi_context_t *adc_digi_ctx) } } - if (status == ADC_DMA_DESC_NULL) { + if (status == ADC_HAL_DMA_DESC_NULL) { //start next turns of dma operation - adc_hal_digi_rxdma_start(&adc_digi_ctx->hal, adc_digi_ctx->rx_dma_buf, adc_digi_ctx->bytes_between_intr); + adc_hal_digi_rxdma_start(&adc_digi_ctx->hal, adc_digi_ctx->rx_dma_buf); } - if (taskAwoken == pdTRUE) { - return true; - } else { - return false; - } + return (taskAwoken == pdTRUE); } esp_err_t adc_digi_start(void) @@ -295,9 +290,6 @@ esp_err_t adc_digi_start(void) //reset flags s_adc_digi_ctx->ringbuf_overflow_flag = 0; s_adc_digi_ctx->driver_start_flag = 1; - - esp_rom_printf("adc start\n"); - if (s_adc_digi_ctx->use_adc1) { SAR_ADC1_LOCK_ACQUIRE(); } @@ -328,7 +320,7 @@ esp_err_t adc_digi_start(void) //reset ADC and DMA adc_hal_fifo_reset(&s_adc_digi_ctx->hal); //start DMA - adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal, s_adc_digi_ctx->rx_dma_buf, s_adc_digi_ctx->bytes_between_intr); + adc_hal_digi_rxdma_start(&s_adc_digi_ctx->hal, s_adc_digi_ctx->rx_dma_buf); //start ADC adc_hal_digi_start(&s_adc_digi_ctx->hal); @@ -442,6 +434,38 @@ esp_err_t adc_digi_deinitialize(void) static adc_atten_t s_atten1_single[ADC1_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC1, used by single read API static adc_atten_t s_atten2_single[ADC2_CHANNEL_MAX]; //Array saving attenuate of each channel of ADC2, used by single read API +esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio) +{ + esp_err_t ret; + uint32_t channel = ADC2_CHANNEL_MAX; + if (adc_unit == ADC_UNIT_2) { + for (int i = 0; i < ADC2_CHANNEL_MAX; i++) { + if (gpio == ADC_GET_IO_NUM(ADC_NUM_2, i)) { + channel = i; + break; + } + } + if (channel == ADC2_CHANNEL_MAX) { + return ESP_ERR_INVALID_ARG; + } + } + + adc_hal_set_power_manage(ADC_POWER_SW_ON); + if (adc_unit & ADC_UNIT_1) { + ADC_ENTER_CRITICAL(); + adc_hal_vref_output(ADC_NUM_1, channel, true); + ADC_EXIT_CRITICAL() + } else if (adc_unit & ADC_UNIT_2) { + ADC_ENTER_CRITICAL(); + adc_hal_vref_output(ADC_NUM_2, channel, true); + ADC_EXIT_CRITICAL() + } + + ret = adc_digi_gpio_init(ADC_NUM_2, BIT(channel)); + + return ret; +} + esp_err_t adc1_config_width(adc_bits_width_t width_bit) { //On ESP32C3, the data width is always 12-bits. @@ -470,23 +494,25 @@ int adc1_get_raw(adc1_channel_t channel) { int raw_out = 0; - SAR_ADC1_LOCK_ACQUIRE(); periph_module_enable(PERIPH_SARADC_MODULE); + SAR_ADC1_LOCK_ACQUIRE(); + adc_atten_t atten = s_atten1_single[channel]; uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_1, channel, atten); + adc_hal_set_calibration_param(ADC_NUM_1, cal_val); ADC_REG_LOCK_ENTER(); - adc_hal_set_calibration_param(ADC_NUM_1, cal_val); adc_hal_set_power_manage(ADC_POWER_SW_ON); adc_hal_set_atten(ADC_NUM_2, channel, atten); adc_hal_convert(ADC_NUM_1, channel, &raw_out); adc_hal_set_power_manage(ADC_POWER_BY_FSM); ADC_REG_LOCK_EXIT(); - periph_module_disable(PERIPH_SARADC_MODULE); SAR_ADC1_LOCK_RELEASE(); + periph_module_disable(PERIPH_SARADC_MODULE); + return raw_out; } @@ -513,23 +539,25 @@ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int * esp_err_t ret = ESP_OK; - SAR_ADC2_LOCK_ACQUIRE(); periph_module_enable(PERIPH_SARADC_MODULE); + SAR_ADC2_LOCK_ACQUIRE(); + adc_atten_t atten = s_atten2_single[channel]; uint32_t cal_val = adc_get_calibration_offset(ADC_NUM_2, channel, atten); + adc_hal_set_calibration_param(ADC_NUM_2, cal_val); ADC_REG_LOCK_ENTER(); - adc_hal_set_calibration_param(ADC_NUM_2, cal_val); adc_hal_set_power_manage(ADC_POWER_SW_ON); adc_hal_set_atten(ADC_NUM_2, channel, atten); ret = adc_hal_convert(ADC_NUM_2, channel, raw_out); adc_hal_set_power_manage(ADC_POWER_BY_FSM); ADC_REG_LOCK_EXIT(); - periph_module_disable(PERIPH_SARADC_MODULE); SAR_ADC2_LOCK_RELEASE(); + periph_module_disable(PERIPH_SARADC_MODULE); + return ret; } diff --git a/components/driver/include/driver/adc_common.h b/components/driver/include/driver/adc_common.h index b50dd9f21f..e38da915c7 100644 --- a/components/driver/include/driver/adc_common.h +++ b/components/driver/include/driver/adc_common.h @@ -175,6 +175,7 @@ void adc_power_acquire(void); */ void adc_power_release(void); +#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Initialize ADC pad * @param adc_unit ADC unit index @@ -184,12 +185,11 @@ void adc_power_release(void); * - ESP_ERR_INVALID_ARG Parameter error */ esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel); +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /*--------------------------------------------------------------- ADC Single Read Setting ---------------------------------------------------------------*/ - -#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Get the GPIO number of a specific ADC1 channel. * @@ -201,7 +201,6 @@ esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel); * - ESP_ERR_INVALID_ARG if channel not valid */ esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num); -#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Set the attenuation of a particular channel on ADC1, and configure its associated GPIO pin mux. @@ -326,6 +325,7 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit); * to be called to configure ADC1 channels, before ADC1 is used by the ULP. */ void adc1_ulp_enable(void); +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Get the GPIO number of a specific ADC2 channel. @@ -339,7 +339,6 @@ void adc1_ulp_enable(void); * - ESP_ERR_INVALID_ARG if channel not valid */ esp_err_t adc2_pad_get_io_num(adc2_channel_t channel, gpio_num_t *gpio_num); -#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Configure the ADC2 channel, including setting attenuation. @@ -420,7 +419,6 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten); */ esp_err_t adc2_get_raw(adc2_channel_t channel, adc_bits_width_t width_bit, int *raw_out); -#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief Output ADC1 or ADC2's reference voltage to ``adc2_channe_t``'s IO. * @@ -454,7 +452,7 @@ esp_err_t adc_vref_to_gpio(adc_unit_t adc_unit, gpio_num_t gpio); * - ESP_ERR_INVALID_ARG: Unsupported GPIO */ esp_err_t adc2_vref_to_gpio(gpio_num_t gpio) __attribute__((deprecated)); -#endif //#if !CONFIG_IDF_TARGET_ESP32C3 + /*--------------------------------------------------------------- Digital controller setting ---------------------------------------------------------------*/ diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index 9dc5e87fff..089cbc5f44 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -95,7 +95,6 @@ static void cal_setup(adc_ll_num_t adc_n, adc_channel_t channel, adc_atten_t att { adc_ll_onetime_sample_enable(ADC_NUM_1, false); adc_ll_onetime_sample_enable(ADC_NUM_2, false); - adc_ll_set_power_manage(ADC_POWER_SW_ON); /* Enable/disable internal connect GND (for calibration). */ if (internal_gnd) { const int esp32c3_invalid_chan = (adc_n == ADC_NUM_1)? 0xF: 0x1; @@ -220,7 +219,7 @@ void adc_hal_fifo_reset(adc_hal_context_t *hal) gdma_ll_rx_reset_channel(hal->dev, hal->dma_chan); } -static void adc_hal_digi_dma_multi_descriptor(dma_descriptor_t *desc, uint8_t *data_buf, uint32_t size, uint32_t num) +static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *data_buf, uint32_t size, uint32_t num) { assert(((uint32_t)data_buf % 4) == 0); assert((size % 4) == 0); @@ -238,18 +237,18 @@ static void adc_hal_digi_dma_multi_descriptor(dma_descriptor_t *desc, uint8_t *d desc[n-1].next = NULL; } -void adc_hal_digi_rxdma_start(adc_hal_context_t *hal, uint8_t *data_buf, uint32_t size) +void adc_hal_digi_rxdma_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_multi_descriptor(hal->rx_desc, data_buf, size, hal->desc_max_num); + adc_hal_digi_dma_link_descriptors(hal->rx_desc, data_buf, hal->eof_num * ADC_HAL_DATA_LEN_PER_CONV, hal->desc_max_num); gdma_ll_rx_set_desc_addr(hal->dev, hal->dma_chan, (uint32_t)hal->rx_desc); gdma_ll_rx_start(hal->dev, hal->dma_chan); } void adc_hal_digi_start(adc_hal_context_t *hal) { - //Set to 1: the ADC data will be sent to the DMA + //the ADC data will be sent to the DMA adc_ll_digi_dma_enable(); //enable sar adc timer adc_ll_digi_trigger_enable(); @@ -257,17 +256,18 @@ void adc_hal_digi_start(adc_hal_context_t *hal) adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_context_t *hal, const intptr_t eof_desc_addr, dma_descriptor_t **cur_desc) { + assert(hal->cur_desc_ptr); if (!hal->cur_desc_ptr->next) { - return ADC_DMA_DESC_NULL; + return ADC_HAL_DMA_DESC_NULL; } if ((intptr_t)hal->cur_desc_ptr == eof_desc_addr) { - return ADC_DMA_DESC_NOT_FINISH; + return ADC_HAL_DMA_DESC_WAITING; } hal->cur_desc_ptr = hal->cur_desc_ptr->next; *cur_desc = hal->cur_desc_ptr; - return ADC_DMA_DESC_FINISH; + return ADC_HAL_DMA_DESC_VALID; } void adc_hal_digi_rxdma_stop(adc_hal_context_t *hal) @@ -372,6 +372,8 @@ esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw) } adc_hal_intr_clear(event); + adc_ll_onetime_sample_enable(ADC_NUM_1, false); + adc_ll_onetime_sample_enable(ADC_NUM_2, false); adc_ll_onetime_sample_enable(adc_n, true); adc_ll_onetime_set_channel(adc_n, channel); @@ -379,7 +381,6 @@ esp_err_t adc_hal_convert(adc_ll_num_t adc_n, int channel, int *out_raw) adc_hal_onetime_start(); while (!adc_hal_intr_get_raw(event)); ret = adc_hal_single_read(adc_n, out_raw); - adc_ll_onetime_sample_enable(adc_n, false); return ret; } diff --git a/components/hal/esp32c3/include/hal/adc_ll.h b/components/hal/esp32c3/include/hal/adc_ll.h index 325380bf7d..a2fd21f2b5 100644 --- a/components/hal/esp32c3/include/hal/adc_ll.h +++ b/components/hal/esp32c3/include/hal/adc_ll.h @@ -53,6 +53,7 @@ typedef enum { ADC_RTC_DATA_FAIL = -1, } adc_ll_rtc_raw_data_t; +//These values should be set according to the HW typedef enum { ADC_LL_INTR_THRES1_LOW = BIT(26), ADC_LL_INTR_THRES0_LOW = BIT(27), diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index badf7fdb0a..7c6366cf30 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -13,13 +13,16 @@ #include "hal/dma_types.h" #include "esp_err.h" +//For ADC module, each conversion contains 4 bytes +#define ADC_HAL_DATA_LEN_PER_CONV 4 + /** * @brief Enum for DMA descriptor status */ -typedef enum adc_hal_dma_desc_status_t{ - ADC_DMA_DESC_FINISH = 0, ///< This DMA descriptor is written by HW already - ADC_DMA_DESC_NOT_FINISH = 1, ///< This DMA descriptor is not written by HW yet - ADC_DMA_DESC_NULL = 2 ///< This DMA descriptor is NULL +typedef enum adc_hal_dma_desc_status_t { + ADC_HAL_DMA_DESC_VALID = 0, ///< This DMA descriptor is written by HW already + ADC_HAL_DMA_DESC_WAITING = 1, ///< This DMA descriptor is not written by HW yet + ADC_HAL_DMA_DESC_NULL = 2 ///< This DMA descriptor is NULL } adc_hal_dma_desc_status_t; /** @@ -46,7 +49,7 @@ typedef struct adc_hal_context_t { /**< these need to be configured by `adc_hal_config_t` via driver layer*/ uint32_t desc_max_num; ///< Number of the descriptors linked once uint32_t dma_chan; ///< DMA channel to be used - uint32_t eof_num; ///< Bytes between 2 in_suc_eof interrupts + uint32_t eof_num; ///< Words between 2 in_suc_eof interrupts } adc_hal_context_t; #endif @@ -154,6 +157,7 @@ void adc_hal_deinit(void); * @prarm adc_n ADC unit. */ #define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en) +#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /** * Enable/disable the output of ADCn's internal reference voltage to one of ADC2's channels. @@ -168,7 +172,6 @@ void adc_hal_deinit(void); * @param[in] en Enable/disable the reference voltage output */ #define adc_hal_vref_output(adc, channel, en) adc_ll_vref_output(adc, channel, en) -#endif //#if !CONFIG_IDF_TARGET_ESP32C3 /*--------------------------------------------------------------- Digital controller setting @@ -245,7 +248,7 @@ void adc_hal_digi_controller_config(const adc_digi_config_t *cfg); #endif /** - * Get the converted value for each ADCn for RTC controller. + * Start an ADC conversion and get the converted value. * * @note It may be block to wait conversion finish. * @@ -330,10 +333,9 @@ void adc_hal_fifo_reset(adc_hal_context_t *hal); * @brief Start DMA * * @param hal Context of the HAL - * @param data_buf Pointer to the data buffer - * @param size Size of the buffer + * @param data_buf Pointer to the data buffer, the length should be multiple of ``desc_max_num`` and ``eof_num`` in ``adc_hal_context_t`` */ -void adc_hal_digi_rxdma_start(adc_hal_context_t *hal, uint8_t *data_buf, uint32_t size); +void adc_hal_digi_rxdma_start(adc_hal_context_t *hal, uint8_t *data_buf); /** * @brief Start ADC From 37e3b79b89464767aaa162dda5b5dc879c7cfb93 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 25 Mar 2021 19:41:04 +0800 Subject: [PATCH 10/10] adc: rename adc examples according to hw feature and usage --- .../adc => esp32c3_dma_and_single_read/adc_dma}/CMakeLists.txt | 0 .../{esp32c3 => esp32c3_dma_and_single_read}/adc_dma/README.md | 0 .../adc_dma/main/CMakeLists.txt | 0 .../adc_dma/main/adc_dma_example_main.c | 0 .../adc/{esp32c3/adc_dma => single_read/adc}/CMakeLists.txt | 0 .../peripherals/adc/{esp32_esp32s2 => single_read}/adc/Makefile | 0 .../peripherals/adc/{esp32_esp32s2 => single_read}/adc/README.md | 0 .../adc/{esp32_esp32s2 => single_read}/adc/main/CMakeLists.txt | 0 .../{esp32_esp32s2 => single_read}/adc/main/adc1_example_main.c | 0 .../adc/{esp32_esp32s2 => single_read}/adc/main/component.mk | 0 .../adc/{esp32_esp32s2 => single_read}/adc2/CMakeLists.txt | 0 .../peripherals/adc/{esp32_esp32s2 => single_read}/adc2/Makefile | 0 .../peripherals/adc/{esp32_esp32s2 => single_read}/adc2/README.md | 0 .../adc/{esp32_esp32s2 => single_read}/adc2/main/CMakeLists.txt | 0 .../{esp32_esp32s2 => single_read}/adc2/main/Kconfig.projbuild | 0 .../{esp32_esp32s2 => single_read}/adc2/main/adc2_example_main.c | 0 .../adc/{esp32_esp32s2 => single_read}/adc2/main/component.mk | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename examples/peripherals/adc/{esp32_esp32s2/adc => esp32c3_dma_and_single_read/adc_dma}/CMakeLists.txt (100%) rename examples/peripherals/adc/{esp32c3 => esp32c3_dma_and_single_read}/adc_dma/README.md (100%) rename examples/peripherals/adc/{esp32c3 => esp32c3_dma_and_single_read}/adc_dma/main/CMakeLists.txt (100%) rename examples/peripherals/adc/{esp32c3 => esp32c3_dma_and_single_read}/adc_dma/main/adc_dma_example_main.c (100%) rename examples/peripherals/adc/{esp32c3/adc_dma => single_read/adc}/CMakeLists.txt (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc/Makefile (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc/README.md (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc/main/CMakeLists.txt (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc/main/adc1_example_main.c (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc/main/component.mk (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc2/CMakeLists.txt (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc2/Makefile (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc2/README.md (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc2/main/CMakeLists.txt (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc2/main/Kconfig.projbuild (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc2/main/adc2_example_main.c (100%) rename examples/peripherals/adc/{esp32_esp32s2 => single_read}/adc2/main/component.mk (100%) diff --git a/examples/peripherals/adc/esp32_esp32s2/adc/CMakeLists.txt b/examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc/CMakeLists.txt rename to examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/CMakeLists.txt diff --git a/examples/peripherals/adc/esp32c3/adc_dma/README.md b/examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/README.md similarity index 100% rename from examples/peripherals/adc/esp32c3/adc_dma/README.md rename to examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/README.md diff --git a/examples/peripherals/adc/esp32c3/adc_dma/main/CMakeLists.txt b/examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/esp32c3/adc_dma/main/CMakeLists.txt rename to examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/main/CMakeLists.txt diff --git a/examples/peripherals/adc/esp32c3/adc_dma/main/adc_dma_example_main.c b/examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/main/adc_dma_example_main.c similarity index 100% rename from examples/peripherals/adc/esp32c3/adc_dma/main/adc_dma_example_main.c rename to examples/peripherals/adc/esp32c3_dma_and_single_read/adc_dma/main/adc_dma_example_main.c diff --git a/examples/peripherals/adc/esp32c3/adc_dma/CMakeLists.txt b/examples/peripherals/adc/single_read/adc/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/esp32c3/adc_dma/CMakeLists.txt rename to examples/peripherals/adc/single_read/adc/CMakeLists.txt diff --git a/examples/peripherals/adc/esp32_esp32s2/adc/Makefile b/examples/peripherals/adc/single_read/adc/Makefile similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc/Makefile rename to examples/peripherals/adc/single_read/adc/Makefile diff --git a/examples/peripherals/adc/esp32_esp32s2/adc/README.md b/examples/peripherals/adc/single_read/adc/README.md similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc/README.md rename to examples/peripherals/adc/single_read/adc/README.md diff --git a/examples/peripherals/adc/esp32_esp32s2/adc/main/CMakeLists.txt b/examples/peripherals/adc/single_read/adc/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc/main/CMakeLists.txt rename to examples/peripherals/adc/single_read/adc/main/CMakeLists.txt diff --git a/examples/peripherals/adc/esp32_esp32s2/adc/main/adc1_example_main.c b/examples/peripherals/adc/single_read/adc/main/adc1_example_main.c similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc/main/adc1_example_main.c rename to examples/peripherals/adc/single_read/adc/main/adc1_example_main.c diff --git a/examples/peripherals/adc/esp32_esp32s2/adc/main/component.mk b/examples/peripherals/adc/single_read/adc/main/component.mk similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc/main/component.mk rename to examples/peripherals/adc/single_read/adc/main/component.mk diff --git a/examples/peripherals/adc/esp32_esp32s2/adc2/CMakeLists.txt b/examples/peripherals/adc/single_read/adc2/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc2/CMakeLists.txt rename to examples/peripherals/adc/single_read/adc2/CMakeLists.txt diff --git a/examples/peripherals/adc/esp32_esp32s2/adc2/Makefile b/examples/peripherals/adc/single_read/adc2/Makefile similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc2/Makefile rename to examples/peripherals/adc/single_read/adc2/Makefile diff --git a/examples/peripherals/adc/esp32_esp32s2/adc2/README.md b/examples/peripherals/adc/single_read/adc2/README.md similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc2/README.md rename to examples/peripherals/adc/single_read/adc2/README.md diff --git a/examples/peripherals/adc/esp32_esp32s2/adc2/main/CMakeLists.txt b/examples/peripherals/adc/single_read/adc2/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc2/main/CMakeLists.txt rename to examples/peripherals/adc/single_read/adc2/main/CMakeLists.txt diff --git a/examples/peripherals/adc/esp32_esp32s2/adc2/main/Kconfig.projbuild b/examples/peripherals/adc/single_read/adc2/main/Kconfig.projbuild similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc2/main/Kconfig.projbuild rename to examples/peripherals/adc/single_read/adc2/main/Kconfig.projbuild diff --git a/examples/peripherals/adc/esp32_esp32s2/adc2/main/adc2_example_main.c b/examples/peripherals/adc/single_read/adc2/main/adc2_example_main.c similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc2/main/adc2_example_main.c rename to examples/peripherals/adc/single_read/adc2/main/adc2_example_main.c diff --git a/examples/peripherals/adc/esp32_esp32s2/adc2/main/component.mk b/examples/peripherals/adc/single_read/adc2/main/component.mk similarity index 100% rename from examples/peripherals/adc/esp32_esp32s2/adc2/main/component.mk rename to examples/peripherals/adc/single_read/adc2/main/component.mk