Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adc: fix adc dma interrupt stops under heavy load (IDFGH-10863) #12065

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/esp_adc/adc_continuous.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi

gdma_strategy_config_t strategy_config = {
.auto_update_desc = true,
.owner_check = true
.owner_check = false
};
gdma_apply_strategy(adc_ctx->rx_dma_channel, &strategy_config);

Expand Down
60 changes: 25 additions & 35 deletions components/hal/adc_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@

void adc_hal_dma_ctx_config(adc_hal_dma_ctx_t *hal, const adc_hal_dma_config_t *config)
{
hal->desc_dummy_head.next = hal->rx_desc;
hal->desc_dummy_head = hal->rx_desc;
hal->dev = config->dev;
hal->eof_desc_num = config->eof_desc_num;
hal->eof_step = config->eof_step;
Expand Down Expand Up @@ -233,14 +233,14 @@ void adc_hal_digi_controller_config(adc_hal_dma_ctx_t *hal, const adc_hal_digi_c
adc_hal_digi_sample_freq_config(hal, cfg->sample_freq_hz);
}

static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *data_buf, uint32_t per_eof_size, uint32_t eof_step, uint32_t eof_num)
static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *data_buf, uint32_t per_eof_size, uint32_t eof_step, uint32_t eof_desc_num)
{
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--) {
while (eof_desc_num--) {
uint32_t eof_size = per_eof_size;

for (int i = 0; i < eof_step; i++) {
Expand All @@ -253,7 +253,7 @@ static void adc_hal_digi_dma_link_descriptors(dma_descriptor_t *desc, uint8_t *d
.dw0.size = this_len,
.dw0.length = 0,
.dw0.suc_eof = 0,
.dw0.owner = 1,
.dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA,
.buffer = data_buf,
.next = &desc[n+1]
};
Expand All @@ -276,7 +276,7 @@ void adc_hal_digi_start(adc_hal_dma_ctx_t *hal, uint8_t *data_buf)
adc_ll_digi_reset(hal->dev);

//reset the current descriptor address
hal->cur_desc_ptr = &hal->desc_dummy_head;
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->eof_step, hal->eof_desc_num);

//start DMA
Expand All @@ -303,43 +303,33 @@ adc_hal_dma_desc_status_t adc_hal_get_reading_result(adc_hal_dma_ctx_t *hal, con
{
HAL_ASSERT(hal->cur_desc_ptr);

if (!hal->cur_desc_ptr->next) {
return ADC_HAL_DMA_DESC_NULL;
}

if ((intptr_t)hal->cur_desc_ptr == eof_desc_addr) {
return ADC_HAL_DMA_DESC_WAITING;
}

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;
}
dma_descriptor_t *desc = hal->cur_desc_ptr;

for (int i = 0; i < hal->eof_step; i++) {
if ((intptr_t)hal->cur_desc_ptr == eof_desc_addr ||
desc->dw0.owner != DMA_DESCRIPTOR_BUFFER_OWNER_CPU)
break;

//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;
if (buffer_start == NULL) {
buffer_start = desc->buffer;
}
eof_len += desc->dw0.length;
desc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;

desc = desc->next;
}

valid:
hal->cur_desc_ptr = eof_desc;
*buffer = buffer_start;
*len = eof_len;
if (buffer_start != NULL) {
hal->cur_desc_ptr = desc;
*buffer = buffer_start;
*len = eof_len;

return ADC_HAL_DMA_DESC_VALID;
return ADC_HAL_DMA_DESC_VALID;
} else {
return ADC_HAL_DMA_DESC_WAITING;
}
}

void adc_hal_digi_clr_intr(adc_hal_dma_ctx_t *hal, uint32_t mask)
Expand Down
2 changes: 1 addition & 1 deletion components/hal/include/hal/adc_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ typedef struct adc_hal_dma_ctx_t {
dma_descriptor_t *rx_desc; ///< DMA descriptors

/**< these will be assigned by hal layer itself */
dma_descriptor_t desc_dummy_head; ///< Dummy DMA descriptor for ``cur_desc_ptr`` to start
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_dma_config_t` via driver layer*/
Expand Down