From be7c656f6e86c9c0170354c3bb3e49bd9ae29b25 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Tue, 11 Oct 2022 16:51:32 +0800 Subject: [PATCH] i2s: fix tx incomplete auto clear Closes: https://github.com/espressif/esp-idf/issues/9882 --- components/driver/deprecated/i2s_legacy.c | 18 +++++++++--------- components/driver/i2s/i2s_common.c | 5 ++--- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/components/driver/deprecated/i2s_legacy.c b/components/driver/deprecated/i2s_legacy.c index 701a713c9f8..6d619ad5c6a 100644 --- a/components/driver/deprecated/i2s_legacy.c +++ b/components/driver/deprecated/i2s_legacy.c @@ -200,9 +200,6 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e if (xQueueIsQueueFullFromISR(p_i2s->tx->queue)) { xQueueReceiveFromISR(p_i2s->tx->queue, &dummy, &tmp); need_awoke |= tmp; - if (p_i2s->tx_desc_auto_clear) { - memset((void *) dummy, 0, p_i2s->tx->buf_size); - } if (p_i2s->i2s_queue) { i2s_event.type = I2S_EVENT_TX_Q_OVF; i2s_event.size = p_i2s->tx->buf_size; @@ -210,6 +207,9 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e need_awoke |= tmp; } } + if (p_i2s->tx_desc_auto_clear) { + memset((void *) (((lldesc_t *)finish_desc)->buf), 0, p_i2s->tx->buf_size); + } xQueueSendFromISR(p_i2s->tx->queue, &(((lldesc_t *)finish_desc)->buf), &tmp); need_awoke |= tmp; if (p_i2s->i2s_queue) { @@ -256,18 +256,18 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) if (xQueueIsQueueFullFromISR(p_i2s->tx->queue)) { xQueueReceiveFromISR(p_i2s->tx->queue, &dummy, &tmp); need_awoke |= tmp; - // See if tx descriptor needs to be auto cleared: - // This will avoid any kind of noise that may get introduced due to transmission - // of previous data from tx descriptor on I2S line. - if (p_i2s->tx_desc_auto_clear == true) { - memset((void *) dummy, 0, p_i2s->tx->buf_size); - } if (p_i2s->i2s_queue) { i2s_event.type = I2S_EVENT_TX_Q_OVF; xQueueSendFromISR(p_i2s->i2s_queue, (void * )&i2s_event, &tmp); need_awoke |= tmp; } } + // See if tx descriptor needs to be auto cleared: + // This will avoid any kind of noise that may get introduced due to transmission + // of previous data from tx descriptor on I2S line. + if (p_i2s->tx_desc_auto_clear == true) { + memset((void *)(((lldesc_t *)finish_desc)->buf), 0, p_i2s->tx->buf_size); + } xQueueSendFromISR(p_i2s->tx->queue, &(((lldesc_t *)finish_desc)->buf), &tmp); need_awoke |= tmp; if (p_i2s->i2s_queue) { diff --git a/components/driver/i2s/i2s_common.c b/components/driver/i2s/i2s_common.c index a985698adc7..552368c1b3f 100644 --- a/components/driver/i2s/i2s_common.c +++ b/components/driver/i2s/i2s_common.c @@ -547,12 +547,11 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e user_need_yield |= handle->callbacks.on_send_q_ovf(handle, &evt, handle->user_data); } } - xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); - if (handle->dma.auto_clear) { uint8_t *sent_buf = (uint8_t *)finish_desc->buf; memset(sent_buf, 0, handle->dma.buf_size); } + xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); return need_yield1 | need_yield2 | user_need_yield; } @@ -627,12 +626,12 @@ static void IRAM_ATTR i2s_dma_tx_callback(void *arg) user_need_yield |= handle->callbacks.on_send_q_ovf(handle, &evt, handle->user_data); } } - xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); // Auto clear the dma buffer after data sent if (handle->dma.auto_clear) { uint8_t *buff = (uint8_t *)finish_desc->buf; memset(buff, 0, handle->dma.buf_size); } + xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2); } if (need_yield1 || need_yield2 || user_need_yield) {