diff --git a/ports/esp32/machine_i2s.c b/ports/esp32/machine_i2s.c index 71d3ad1163..108caf677b 100644 --- a/ports/esp32/machine_i2s.c +++ b/ports/esp32/machine_i2s.c @@ -263,13 +263,22 @@ STATIC uint32_t fill_appbuf_from_dma(machine_i2s_obj_t *self, mp_buffer_info_t * delay = portMAX_DELAY; // block until supplied buffer is filled } - // read a chunk of audio samples from DMA memory - check_esp_err(i2s_read( + esp_err_t ret = i2s_read( self->port, self->transform_buffer, num_bytes_requested_from_dma, &num_bytes_received_from_dma, - delay)); + delay); + + // the following is a workaround for a bug in ESP-IDF v4.4 + // https://github.com/espressif/esp-idf/issues/8121 + #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4) + if ((delay != portMAX_DELAY) && (ret == ESP_ERR_TIMEOUT)) { + ret = ESP_OK; + } + #endif + + check_esp_err(ret); // process the transform buffer one frame at a time. // copy selected bytes from the transform buffer into the user supplied appbuf. @@ -324,7 +333,17 @@ STATIC size_t copy_appbuf_to_dma(machine_i2s_obj_t *self, mp_buffer_info_t *appb delay = portMAX_DELAY; // block until supplied buffer is emptied } - check_esp_err(i2s_write(self->port, appbuf->buf, appbuf->len, &num_bytes_written, delay)); + esp_err_t ret = i2s_write(self->port, appbuf->buf, appbuf->len, &num_bytes_written, delay); + + // the following is a workaround for a bug in ESP-IDF v4.4 + // https://github.com/espressif/esp-idf/issues/8121 + #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4) + if ((delay != portMAX_DELAY) && (ret == ESP_ERR_TIMEOUT)) { + ret = ESP_OK; + } + #endif + + check_esp_err(ret); if ((self->io_mode == UASYNCIO) && (num_bytes_written < appbuf->len)) { // Unable to empty the entire app buffer into DMA memory. This indicates all DMA TX buffers are full. @@ -447,6 +466,11 @@ STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args, i2s_config.dma_buf_len = DMA_BUF_LEN_IN_I2S_FRAMES; i2s_config.use_apll = false; i2s_config.tx_desc_auto_clear = true; + i2s_config.fixed_mclk = 0; + #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4) + i2s_config.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT; + i2s_config.bits_per_chan = 0; + #endif // I2S queue size equals the number of DMA buffers check_esp_err(i2s_driver_install(self->port, &i2s_config, i2s_config.dma_buf_count, &self->i2s_event_queue)); @@ -463,14 +487,17 @@ STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args, #endif i2s_pin_config_t pin_config; + #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4) + pin_config.mck_io_num = I2S_PIN_NO_CHANGE; + #endif pin_config.bck_io_num = self->sck; pin_config.ws_io_num = self->ws; if (mode == (I2S_MODE_MASTER | I2S_MODE_RX)) { pin_config.data_in_num = self->sd; - pin_config.data_out_num = -1; + pin_config.data_out_num = I2S_PIN_NO_CHANGE; } else { // TX - pin_config.data_in_num = -1; + pin_config.data_in_num = I2S_PIN_NO_CHANGE; pin_config.data_out_num = self->sd; }