mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 10:47:19 +02:00
DMA EOF may happens per multiple dma descriptors, instead of only one.
Closes https://github.com/espressif/esp-idf/pull/11500
This commit is contained in:
@ -114,7 +114,6 @@ static IRAM_ATTR bool s_adc_dma_intr(adc_digi_context_t *adc_digi_ctx);
|
|||||||
|
|
||||||
#if SOC_GDMA_SUPPORTED
|
#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 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
|
#else
|
||||||
static IRAM_ATTR void adc_dma_intr_handler(void *arg);
|
static IRAM_ATTR void adc_dma_intr_handler(void *arg);
|
||||||
#endif
|
#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_apply_strategy(s_adc_digi_ctx->rx_dma_channel, &strategy_config);
|
||||||
|
|
||||||
gdma_rx_event_callbacks_t cbs = {
|
gdma_rx_event_callbacks_t cbs = {
|
||||||
.on_recv_eof = adc_dma_in_suc_eof_callback,
|
.on_recv_eof = adc_dma_in_suc_eof_callback
|
||||||
.on_descr_err = adc_dma_descr_err_callback
|
|
||||||
};
|
};
|
||||||
gdma_register_rx_event_callbacks(s_adc_digi_ctx->rx_dma_channel, &cbs, s_adc_digi_ctx);
|
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;
|
s_adc_digi_ctx->rx_eof_desc_addr = event_data->rx_eof_desc_addr;
|
||||||
return s_adc_dma_intr(user_data);
|
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
|
#else
|
||||||
static IRAM_ATTR void adc_dma_intr_handler(void *arg)
|
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);
|
ret = xRingbufferSendFromISR(adc_digi_ctx->ringbuf_hdl, finished_buffer, finished_size, &taskAwoken);
|
||||||
adc_hal_read_desc_finish (&adc_digi_ctx->hal);
|
|
||||||
if (ret == pdFALSE) {
|
if (ret == pdFALSE) {
|
||||||
//ringbuffer overflow
|
//ringbuffer overflow
|
||||||
adc_digi_ctx->ringbuf_overflow_flag = 1;
|
adc_digi_ctx->ringbuf_overflow_flag = 1;
|
||||||
|
@ -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(((uint32_t)data_buf % 4) == 0);
|
||||||
HAL_ASSERT((per_eof_size % 4) == 0);
|
HAL_ASSERT((per_eof_size % 4) == 0);
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
|
dma_descriptor_t *desc_head = desc;
|
||||||
|
|
||||||
while (eof_num--) {
|
while (eof_num--) {
|
||||||
uint32_t eof_size = per_eof_size;
|
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++;
|
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)
|
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
|
//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->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
|
//start DMA
|
||||||
adc_dma_ll_rx_start(hal->dev, hal->dma_chan, (lldesc_t *)hal->rx_desc);
|
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
|
#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);
|
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;
|
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;
|
uint8_t *buffer_start = NULL;
|
||||||
uint32_t eof_len = 0;
|
uint32_t eof_len = 0;
|
||||||
dma_descriptor_t *eof_desc = hal->cur_desc_ptr;
|
dma_descriptor_t *eof_desc = hal->cur_desc_ptr;
|
||||||
|
|
||||||
//Find the eof list start
|
//Find the eof list start
|
||||||
eof_desc = eof_desc->next;
|
eof_desc = eof_desc->next;
|
||||||
|
eof_desc->dw0.owner = 1;
|
||||||
buffer_start = eof_desc->buffer;
|
buffer_start = eof_desc->buffer;
|
||||||
eof_len += eof_desc->dw0.length;
|
eof_len += eof_desc->dw0.length;
|
||||||
|
if ((intptr_t)eof_desc == eof_desc_addr) {
|
||||||
|
goto valid;
|
||||||
|
}
|
||||||
|
|
||||||
//Find the eof list end
|
//Find the eof list end
|
||||||
for (int i = 1; i < hal->eof_step; i++) {
|
for (int i = 1; i < hal->eof_step; i++) {
|
||||||
eof_desc = eof_desc->next;
|
eof_desc = eof_desc->next;
|
||||||
|
eof_desc->dw0.owner = 1;
|
||||||
eof_len += eof_desc->dw0.length;
|
eof_len += eof_desc->dw0.length;
|
||||||
|
if ((intptr_t)eof_desc == eof_desc_addr) {
|
||||||
|
goto valid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
valid:
|
||||||
hal->cur_desc_ptr = eof_desc;
|
hal->cur_desc_ptr = eof_desc;
|
||||||
*buffer = buffer_start;
|
*buffer = buffer_start;
|
||||||
*len = eof_len;
|
*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;
|
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)
|
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);
|
adc_dma_ll_rx_clear_intr(hal->dev, hal->dma_chan, mask);
|
||||||
|
@ -215,7 +215,7 @@ bool adc_hal_check_event(adc_hal_context_t *hal, uint32_t mask);
|
|||||||
#endif
|
#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 hal Context of the HAL
|
||||||
* @param eof_desc_addr The last descriptor that is finished by HW. Should be got from DMA
|
* @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``
|
* @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
|
* @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.
|
* @prarm adc_n ADC unit.
|
||||||
*/
|
*/
|
||||||
#define adc_hal_rtc_output_invert(adc_n, inv_en) adc_ll_rtc_output_invert(adc_n, inv_en)
|
#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);
|
|
||||||
|
Reference in New Issue
Block a user