From 8fe99aff966070f88016276f5628944cd86428a4 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 25 Mar 2021 19:04:38 +0800 Subject: [PATCH] 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 3c4e20ce84..bfa6e69e96 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