From 9f6f510ce24b4561a4b4f0a9e273fa0b967947c2 Mon Sep 17 00:00:00 2001 From: houwenxiang Date: Mon, 13 Jul 2020 11:54:34 +0800 Subject: [PATCH] driver(I2S): Fix I2S reset issue for release/v4.1 `i2s_start` reseting I2S in incorrect order causeing the word-order error. --- components/driver/i2s.c | 19 +++++++++---------- components/soc/include/hal/i2s_hal.h | 8 +------- components/soc/src/hal/i2s_hal.c | 13 ++++++------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/components/driver/i2s.c b/components/driver/i2s.c index cf80ff80a8..ab189f0127 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -101,14 +101,6 @@ static int _i2s_adc_channel = -1; static i2s_dma_t *i2s_create_dma_queue(i2s_port_t i2s_num, int dma_buf_count, int dma_buf_len); static esp_err_t i2s_destroy_dma_queue(i2s_port_t i2s_num, i2s_dma_t *dma); -static esp_err_t i2s_reset_fifo(i2s_port_t i2s_num) -{ - I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG); - I2S_ENTER_CRITICAL(); - i2s_hal_reset_fifo(&(p_i2s_obj[i2s_num]->hal)); - I2S_EXIT_CRITICAL(); - return ESP_OK; -} inline static void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv) { @@ -461,6 +453,15 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b rate, real_rate, bits, clkmInteger, bck, (double)I2S_BASE_CLK / mclk, real_rate*bits*channel, 64, clkmDecimals); } + if (p_i2s_obj[i2s_num]->mode & I2S_MODE_TX) { + p_i2s_obj[i2s_num]->tx->curr_ptr = NULL; + p_i2s_obj[i2s_num]->tx->rw_pos = 0; + } + if (p_i2s_obj[i2s_num]->mode & I2S_MODE_RX) { + p_i2s_obj[i2s_num]->rx->curr_ptr = NULL; + p_i2s_obj[i2s_num]->rx->rw_pos = 0; + } + i2s_hal_set_tx_bits_mod(&(p_i2s_obj[i2s_num]->hal), bits); i2s_hal_set_rx_bits_mod(&(p_i2s_obj[i2s_num]->hal), bits); @@ -646,7 +647,6 @@ esp_err_t i2s_start(i2s_port_t i2s_num) I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG); //start DMA link I2S_ENTER_CRITICAL(); - i2s_reset_fifo(i2s_num); i2s_hal_reset(&(p_i2s_obj[i2s_num]->hal)); @@ -831,7 +831,6 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co adc_power_always_on(); } // configure I2S data port interface. - i2s_reset_fifo(i2s_num); i2s_hal_config_param(&(p_i2s_obj[i2s_num]->hal), i2s_config); if ((p_i2s_obj[i2s_num]->mode & I2S_MODE_RX) && (p_i2s_obj[i2s_num]->mode & I2S_MODE_TX)) { i2s_hal_enable_sig_loopback(&(p_i2s_obj[i2s_num]->hal)); diff --git a/components/soc/include/hal/i2s_hal.h b/components/soc/include/hal/i2s_hal.h index 75779c6ddf..40dafdde7f 100644 --- a/components/soc/include/hal/i2s_hal.h +++ b/components/soc/include/hal/i2s_hal.h @@ -40,12 +40,6 @@ typedef struct { uint32_t version; } i2s_hal_context_t; -/** - * @brief Reset I2S fifo - * - * @param hal Context of the HAL layer - */ -void i2s_hal_reset_fifo(i2s_hal_context_t *hal); /** * @brief Get I2S interrupt status @@ -212,7 +206,7 @@ void i2s_hal_set_tx_bits_mod(i2s_hal_context_t *hal, i2s_bits_per_sample_t bits) void i2s_hal_set_rx_bits_mod(i2s_hal_context_t *hal, i2s_bits_per_sample_t bits); /** - * @brief Reset I2S tx + * @brief Reset I2S TX & RX module, including DMA and FIFO * * @param hal Context of the HAL layer */ diff --git a/components/soc/src/hal/i2s_hal.c b/components/soc/src/hal/i2s_hal.c index 6639525ea8..5179b31720 100644 --- a/components/soc/src/hal/i2s_hal.c +++ b/components/soc/src/hal/i2s_hal.c @@ -18,11 +18,6 @@ #include "esp_log.h" #include "hal/i2s_hal.h" -void i2s_hal_reset_fifo(i2s_hal_context_t *hal) -{ - i2s_ll_reset_rx_fifo(hal->dev); - i2s_ll_reset_tx_fifo(hal->dev); -} void i2s_hal_set_tx_mode(i2s_hal_context_t *hal, i2s_channel_t ch, i2s_bits_per_sample_t bits) { @@ -77,10 +72,14 @@ void i2s_hal_set_rx_bits_mod(i2s_hal_context_t *hal, i2s_bits_per_sample_t bits) void i2s_hal_reset(i2s_hal_context_t *hal) { - i2s_ll_reset_dma_in(hal->dev); - i2s_ll_reset_dma_out(hal->dev); + // Reset I2S TX/RX module first, and then, reset DMA and FIFO. i2s_ll_reset_tx(hal->dev); i2s_ll_reset_rx(hal->dev); + i2s_ll_reset_dma_in(hal->dev); + i2s_ll_reset_dma_out(hal->dev); + i2s_ll_reset_rx_fifo(hal->dev); + i2s_ll_reset_tx_fifo(hal->dev); + } void i2s_hal_start_tx(i2s_hal_context_t *hal)