Skip to content

Commit 0d00d72

Browse files
projectgusdpgeorge
authored andcommitted
esp32/machine_i2s: Ensure 2 DMA buffers and improve I2S error handling.
ESP-IDF driver always requires at least two DMA buffers, so ensure that's the case. Failures during initialisation were being lost because ESP_ERROR_CHECK is configured as a no-op, so the failure was deferred until read() or write() was called on the port. Raise an error from init, instead. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <[email protected]>
1 parent 9ba04cc commit 0d00d72

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

ports/esp32/machine_i2s.c

+12-9
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static uint32_t get_dma_buf_count(uint8_t mode, i2s_data_bit_width_t bits, forma
151151

152152
uint32_t dma_buf_count = ibuf / (DMA_BUF_LEN_IN_I2S_FRAMES * dma_frame_size_in_bytes);
153153

154-
return dma_buf_count;
154+
return MAX(dma_buf_count, 2); // ESP-IDF requires at least two DMA buffers
155155
}
156156

157157
static uint32_t fill_appbuf_from_dma(machine_i2s_obj_t *self, mp_buffer_info_t *appbuf) {
@@ -363,9 +363,9 @@ static void mp_machine_i2s_init_helper(machine_i2s_obj_t *self, mp_arg_val_t *ar
363363
chan_config.auto_clear = true;
364364

365365
if (mode == MICROPY_PY_MACHINE_I2S_CONSTANT_TX) {
366-
ESP_ERROR_CHECK(i2s_new_channel(&chan_config, &self->i2s_chan_handle, NULL));
366+
check_esp_err(i2s_new_channel(&chan_config, &self->i2s_chan_handle, NULL));
367367
} else { // rx
368-
ESP_ERROR_CHECK(i2s_new_channel(&chan_config, NULL, &self->i2s_chan_handle));
368+
check_esp_err(i2s_new_channel(&chan_config, NULL, &self->i2s_chan_handle));
369369
}
370370

371371
i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(get_dma_bits(mode, bits), get_dma_format(mode, format));
@@ -394,9 +394,9 @@ static void mp_machine_i2s_init_helper(machine_i2s_obj_t *self, mp_arg_val_t *ar
394394
std_cfg.gpio_cfg.din = self->sd;
395395
}
396396

397-
ESP_ERROR_CHECK(i2s_channel_init_std_mode(self->i2s_chan_handle, &std_cfg));
398-
ESP_ERROR_CHECK(i2s_channel_register_event_callback(self->i2s_chan_handle, &i2s_callbacks, self));
399-
ESP_ERROR_CHECK(i2s_channel_enable(self->i2s_chan_handle));
397+
check_esp_err(i2s_channel_init_std_mode(self->i2s_chan_handle, &std_cfg));
398+
check_esp_err(i2s_channel_register_event_callback(self->i2s_chan_handle, &i2s_callbacks, self));
399+
check_esp_err(i2s_channel_enable(self->i2s_chan_handle));
400400
}
401401

402402
static machine_i2s_obj_t *mp_machine_i2s_make_new_instance(mp_int_t i2s_id) {
@@ -419,9 +419,12 @@ static machine_i2s_obj_t *mp_machine_i2s_make_new_instance(mp_int_t i2s_id) {
419419

420420
static void mp_machine_i2s_deinit(machine_i2s_obj_t *self) {
421421
if (!self->is_deinit) {
422-
ESP_ERROR_CHECK(i2s_channel_disable(self->i2s_chan_handle));
423-
ESP_ERROR_CHECK(i2s_channel_register_event_callback(self->i2s_chan_handle, &i2s_callbacks_null, self));
424-
ESP_ERROR_CHECK(i2s_del_channel(self->i2s_chan_handle));
422+
if (self->i2s_chan_handle) {
423+
i2s_channel_disable(self->i2s_chan_handle);
424+
i2s_channel_register_event_callback(self->i2s_chan_handle, &i2s_callbacks_null, self);
425+
i2s_del_channel(self->i2s_chan_handle);
426+
self->i2s_chan_handle = NULL;
427+
}
425428

426429
if (self->non_blocking_mode_task != NULL) {
427430
vTaskDelete(self->non_blocking_mode_task);

0 commit comments

Comments
 (0)