esp32/machine_i2s: Add support for ESP-IDF 4.4.

- Add default values for I2S features added in ESP-IDF 4.4.
- Add workaround for bug introduced in ESP-IDF 4.4
  (https://github.com/espressif/esp-idf/issues/8121).
This commit is contained in:
MikeTeachman 2021-12-23 09:27:49 -08:00 committed by Damien George
parent 644f4dcc94
commit 49d8ae3ecc

View File

@ -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 delay = portMAX_DELAY; // block until supplied buffer is filled
} }
// read a chunk of audio samples from DMA memory esp_err_t ret = i2s_read(
check_esp_err(i2s_read(
self->port, self->port,
self->transform_buffer, self->transform_buffer,
num_bytes_requested_from_dma, num_bytes_requested_from_dma,
&num_bytes_received_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. // process the transform buffer one frame at a time.
// copy selected bytes from the transform buffer into the user supplied appbuf. // 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 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)) { 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. // 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.dma_buf_len = DMA_BUF_LEN_IN_I2S_FRAMES;
i2s_config.use_apll = false; i2s_config.use_apll = false;
i2s_config.tx_desc_auto_clear = true; 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 // 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)); 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 #endif
i2s_pin_config_t pin_config; 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.bck_io_num = self->sck;
pin_config.ws_io_num = self->ws; pin_config.ws_io_num = self->ws;
if (mode == (I2S_MODE_MASTER | I2S_MODE_RX)) { if (mode == (I2S_MODE_MASTER | I2S_MODE_RX)) {
pin_config.data_in_num = self->sd; pin_config.data_in_num = self->sd;
pin_config.data_out_num = -1; pin_config.data_out_num = I2S_PIN_NO_CHANGE;
} else { // TX } else { // TX
pin_config.data_in_num = -1; pin_config.data_in_num = I2S_PIN_NO_CHANGE;
pin_config.data_out_num = self->sd; pin_config.data_out_num = self->sd;
} }