From b282c244cb7d7df9323cebc85e74e01d17da581b Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 12 Jul 2023 17:01:39 +0800 Subject: [PATCH] DMA EOF may happens per multiple dma descriptors, instead of only one. Closes https://github.com/espressif/esp-idf/pull/11500 --- components/driver/adc.c | 12 +----------- components/hal/adc_hal.c | 25 ++++++++++++++----------- components/hal/include/hal/adc_hal.h | 11 ++--------- 3 files changed, 17 insertions(+), 31 deletions(-) diff --git a/components/driver/adc.c b/components/driver/adc.c index 3311d1c799..440328694b 100644 --- a/components/driver/adc.c +++ b/components/driver/adc.c @@ -114,7 +114,6 @@ static IRAM_ATTR bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx); #if SOC_GDMA_SUPPORTED 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); -static bool adc_dma_descr_err_callback(gdma_channel_handle_t dma_chan, void *user_data); #else static IRAM_ATTR void adc_dma_intr_handler(void *arg); #endif @@ -231,8 +230,7 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) gdma_apply_strategy(s_adc_digi_ctx->rx_dma_channel, &strategy_config); gdma_rx_event_callbacks_t cbs = { - .on_recv_eof = adc_dma_in_suc_eof_callback, - .on_descr_err = adc_dma_descr_err_callback + .on_recv_eof = adc_dma_in_suc_eof_callback }; gdma_register_rx_event_callbacks(s_adc_digi_ctx->rx_dma_channel, &cbs, s_adc_digi_ctx); @@ -314,13 +312,6 @@ static IRAM_ATTR bool adc_dma_in_suc_eof_callback(gdma_channel_handle_t dma_chan s_adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr; return s_adc_dma_intr(user_data); } - -static bool adc_dma_descr_err_callback(gdma_channel_handle_t dma_chan, void *user_data) -{ - ESP_EARLY_LOGE(ADC_TAG, "GDMA descriptor error occurred, probable ADC data loss, CPU load too high?"); - return false; -} - #else static IRAM_ATTR void adc_dma_intr_handler(void *arg) { @@ -358,7 +349,6 @@ static IRAM_ATTR bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx) } ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, finished_buffer, finished_size, &taskAwoken); - adc_hal_read_desc_finish (&adc_digi_ctx->hal); if (ret == pdFALSE) { //ringbuffer overflow adc_digi_ctx->ringbuf_overflow_flag = 1; diff --git a/components/hal/adc_hal.c b/components/hal/adc_hal.c index a9ea744f5d..614a3117a7 100644 --- a/components/hal/adc_hal.c +++ b/components/hal/adc_hal.c @@ -331,6 +331,7 @@ static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *d HAL_ASSERT(((uint32_t)data_buf % 4) == 0); HAL_ASSERT((per_eof_size % 4) == 0); uint32_t n = 0; + dma_descriptor_t *desc_head = desc; while (eof_num--) { uint32_t eof_size = per_eof_size; @@ -354,7 +355,7 @@ static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *d n++; } } - desc[n-1].next = desc; + desc[n-1].next = desc_head; } void adc_hal_digi_start(adc_hal_context_t *hal, uint8_t *data_buf) @@ -369,7 +370,7 @@ void adc_hal_digi_start(adc_hal_context_t *hal, uint8_t *data_buf) //reset the current descriptor address hal->cur_desc_ptr = &hal->desc_dummy_head; - adc_hal_digi_dma_link_descriptors(hal->rx_desc, data_buf, hal->eof_num * SOC_ADC_DIGI_DATA_BYTES_PER_CONV, hal->desc_max_num); + adc_hal_digi_dma_link_descriptors(hal->rx_desc, data_buf, hal->eof_num * SOC_ADC_DIGI_DATA_BYTES_PER_CONV, hal->eof_step, hal->eof_desc_num); //start DMA adc_dma_ll_rx_start(hal->dev, hal->dma_chan, (lldesc_t *)hal->rx_desc); @@ -391,7 +392,7 @@ bool adc_hal_check_event(adc_hal_context_t *hal, uint32_t mask) } #endif //#if !SOC_GDMA_SUPPORTED -adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_dma_ctx_t *hal, const intptr_t eof_desc_addr, uint8_t **buffer, uint32_t *len) +adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_context_t *hal, const intptr_t eof_desc_addr, uint8_t **buffer, uint32_t *len) { HAL_ASSERT(hal->cur_desc_ptr); @@ -403,24 +404,31 @@ adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_dma_ctx_t *hal, con return ADC_HAL_DMA_DESC_WAITING; } - hal->cur_desc_ptr = hal->cur_desc_ptr->next; - *cur_desc = hal->cur_desc_ptr; - uint8_t *buffer_start = NULL; uint32_t eof_len = 0; dma_descriptor_t *eof_desc = hal->cur_desc_ptr; //Find the eof list start eof_desc = eof_desc->next; + eof_desc->dw0.owner = 1; buffer_start = eof_desc->buffer; eof_len += eof_desc->dw0.length; + if ((intptr_t)eof_desc == eof_desc_addr) { + goto valid; + } //Find the eof list end for (int i = 1; i < hal->eof_step; i++) { eof_desc = eof_desc->next; + eof_desc->dw0.owner = 1; eof_len += eof_desc->dw0.length; + if ((intptr_t)eof_desc == eof_desc_addr) { + goto valid; + } } + +valid: hal->cur_desc_ptr = eof_desc; *buffer = buffer_start; *len = eof_len; @@ -428,11 +436,6 @@ adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_dma_ctx_t *hal, con return ADC_HAL_DMA_DESC_VALID; } -void adc_hal_read_desc_finish(adc_hal_dma_ctx_t *hal) { - // Allow DMA to re-use descriptor. - hal->cur_desc_ptr->dw0.owner = 1; -} - void adc_hal_digi_clr_intr(adc_hal_context_t *hal, uint32_t mask) { adc_dma_ll_rx_clear_intr(hal->dev, hal->dma_chan, mask); diff --git a/components/hal/include/hal/adc_hal.h b/components/hal/include/hal/adc_hal.h index 4708c52754..ab08a5dd47 100644 --- a/components/hal/include/hal/adc_hal.h +++ b/components/hal/include/hal/adc_hal.h @@ -215,7 +215,7 @@ bool adc_hal_check_event(adc_hal_context_t *hal, uint32_t mask); #endif /** - * @brief Get the ADC reading result. Call adc_hal_read_desc_finish after using the descriptor. + * @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 @@ -224,7 +224,7 @@ bool adc_hal_check_event(adc_hal_context_t *hal, uint32_t mask); * * @return See ``adc_hal_dma_desc_status_t`` */ -adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_dma_ctx_t *hal, const intptr_t eof_desc_addr, uint8_t **buffer, uint32_t *len); +adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_context_t *hal, const intptr_t eof_desc_addr, uint8_t **buffer, uint32_t *len); /** * @brief Clear interrupt @@ -375,10 +375,3 @@ uint32_t adc_hal_self_calibration(adc_ll_num_t adc_n, adc_channel_t channel, adc * @prarm adc_n ADC unit. */ #define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en) - -/** - * @brief Finishes reading the current descriptor and frees it for repeated usage by DMA. - * - * @param hal Context of the HAL - */ -void adc_hal_read_desc_finish(adc_hal_dma_ctx_t *hal);