diff --git a/components/driver/i2s.c b/components/driver/i2s.c index 65b83c9e7..480cd98ef 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -86,6 +86,7 @@ typedef struct { i2s_mode_t mode; /*!< I2S Working mode*/ uint32_t sample_rate; /*!< I2S sample rate */ bool use_apll; /*!< I2S use APLL clock */ + bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor on underflow */ int fixed_mclk; /*!< I2S fixed MLCK clock */ } i2s_obj_t; @@ -502,6 +503,12 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) // All buffers are empty. This means we have an underflow on our hands. if (xQueueIsQueueFullFromISR(p_i2s->tx->queue)) { xQueueReceiveFromISR(p_i2s->tx->queue, &dummy, &high_priority_task_awoken); + // 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); + } } xQueueSendFromISR(p_i2s->tx->queue, (void*)(&finish_desc->buf), &high_priority_task_awoken); if (p_i2s->i2s_queue) { @@ -991,6 +998,7 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co } p_i2s_obj[i2s_num]->use_apll = i2s_config->use_apll; + p_i2s_obj[i2s_num]->tx_desc_auto_clear = i2s_config->tx_desc_auto_clear; p_i2s_obj[i2s_num]->fixed_mclk = i2s_config->fixed_mclk; return ESP_OK; } diff --git a/components/driver/include/driver/i2s.h b/components/driver/include/driver/i2s.h index 1cd454796..1f73e1f55 100644 --- a/components/driver/include/driver/i2s.h +++ b/components/driver/include/driver/i2s.h @@ -139,6 +139,7 @@ typedef struct { int dma_buf_count; /*!< I2S DMA Buffer Count */ int dma_buf_len; /*!< I2S DMA Buffer Length */ bool use_apll; /*!< I2S using APLL as main I2S clock, enable it to get accurate clock */ + bool tx_desc_auto_clear; /*!< I2S auto clear tx descriptor if there is underflow condition (helps in avoiding noise in case of data unavailability) */ int fixed_mclk; /*!< I2S using fixed MCLK output. If use_apll = true and fixed_mclk > 0, then the clock output for i2s is fixed and equal to the fixed_mclk value.*/ } i2s_config_t; diff --git a/examples/bluetooth/a2dp_gatts_coex/main/main.c b/examples/bluetooth/a2dp_gatts_coex/main/main.c index cf5117045..3b042714a 100644 --- a/examples/bluetooth/a2dp_gatts_coex/main/main.c +++ b/examples/bluetooth/a2dp_gatts_coex/main/main.c @@ -650,8 +650,9 @@ void app_main() .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB, .dma_buf_count = 6, - .dma_buf_len = 60, // - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1 + .dma_buf_len = 60, + .intr_alloc_flags = 0, //Default interrupt priority + .tx_desc_auto_clear = true //Auto clear tx descriptor on underflow }; diff --git a/examples/bluetooth/a2dp_sink/main/main.c b/examples/bluetooth/a2dp_sink/main/main.c index 66850d30d..830afe45e 100644 --- a/examples/bluetooth/a2dp_sink/main/main.c +++ b/examples/bluetooth/a2dp_sink/main/main.c @@ -63,8 +63,9 @@ void app_main() .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //2-channels .communication_format = I2S_COMM_FORMAT_I2S_MSB, .dma_buf_count = 6, - .dma_buf_len = 60, // - .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1 //Interrupt level 1 + .dma_buf_len = 60, + .intr_alloc_flags = 0, //Default interrupt priority + .tx_desc_auto_clear = true //Auto clear tx descriptor on underflow };