i2s callback question
Posted: Tue Nov 05, 2024 9:28 pm
Hello,
As soon as I enable i2s tx channel the on_sent callback fires continuously.
I comment out i2s_channel_write statement to make sure nothing
is being written to the tx dma buffers.
Anyone have an idea why this would happen ?
Thank you
As soon as I enable i2s tx channel the on_sent callback fires continuously.
I comment out i2s_channel_write statement to make sure nothing
is being written to the tx dma buffers.
Anyone have an idea why this would happen ?
Thank you
Code: Select all
/* I2S Speaker Example*/
static const char *TAG = "std_rec_example";
#define WAV_BITS_PER_SAMPLE 16
#define SPI_DMA_CHAN SPI_DMA_CH_AUTO
TaskHandle_t writeTaskHandle, callback_status;
i2s_chan_handle_t tx_handle = NULL;
#define SAMPLE_SIZE (1440)
static int16_t samples[SAMPLE_SIZE]; // 1440 * 2
int my_int = 0;
bool flag = false;
static bool IRAM_ATTR tx_done_callback(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(callback_status, &xHigherPriorityTaskWoken);
// vTaskNotifyGiveFromISR(writeTaskHandle, &xHigherPriorityTaskWoken);
return false;
}
const i2s_event_callbacks_t cbs = {
.on_recv = NULL,
.on_recv_q_ovf = NULL,
.on_sent = tx_done_callback,
.on_send_q_ovf = NULL,
};
static void callback_status_task(void *args)
{
static uint32_t count = 0;
while (1)
{
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
ESP_LOGI(TAG, "count: %lu", count++);
}
vTaskDelete(NULL);
}
void init_speaker(void)
{
i2s_chan_config_t tx_chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
tx_chan_cfg.auto_clear = true;
tx_chan_cfg.auto_clear_before_cb = true;
ESP_ERROR_CHECK(i2s_new_channel(&tx_chan_cfg, &tx_handle, NULL));
i2s_std_config_t tx_std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(CONFIG_EXAMPLE_SAMPLE_RATE),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_22,
.ws = GPIO_NUM_23,
.dout = GPIO_NUM_21,
.din = I2S_GPIO_UNUSED,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
tx_std_cfg.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT;
ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_handle, &tx_std_cfg));
}
static void i2s_example_write_task(void *args) // write to I2S dma -> bus, output to speaker
{
FILE *f = fopen(SD_MOUNT_POINT "/record.wav", "r"); // open for reading;
if (f == NULL)
{
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
size_t bytes_written = 0;
size_t sum = 0;
size_t total_frames = 0;
size_t count = 0;
fseek(f, 44, SEEK_SET); //reset file pointer to beginning of data
while (count < 5) // play recording 5X
{
ESP_ERROR_CHECK(i2s_channel_enable(tx_handle));
while (1)
{
size_t read = fread(samples, sizeof(int16_t), (size_t)1440, f); // read 2880 bytes from record.wav into samples
if (read == 0)
break;
total_frames += read; // ESP_LOGI(TAG, "elements read: %u", read);
// i2s_channel_write(tx_handle, samples, (size_t)1440 * sizeof(int16_t), &bytes_written, portMAX_DELAY); // Write i2s data
sum += bytes_written;
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // controlled by i2s_data_sent event
} // if
ESP_ERROR_CHECK(i2s_channel_disable(tx_handle));
ESP_LOGI(TAG, "total frames read: %u", total_frames);
ESP_LOGI(TAG, "total frames sent: %u", sum / 2);
fseek(f, 44, SEEK_SET); // reset file pointer
total_frames = 0;
sum = 0;
count++;
vTaskDelay(pdMS_TO_TICKS(1000));
} // while1
fclose(f);
esp_vfs_fat_sdcard_unmount(SD_MOUNT_POINT, card); // All done, unmount partition and disable SPI peripheral
spi_bus_free(host.slot); // Deinitialize the bus after all devices are removed
vTaskDelay(pdMS_TO_TICKS(10));
vTaskDelete(NULL);
}
void app_main(void)
{
mount_sdcard();
init_speaker();
const i2s_event_callbacks_t cbs = {
.on_recv = NULL,
.on_recv_q_ovf = NULL,
.on_sent = tx_done_callback,
.on_send_q_ovf = NULL,
};
i2s_channel_register_event_callback(tx_handle, &cbs, &temp);
xTaskCreate(i2s_example_write_task, "i2s_example_write_task", 4096, NULL, 3, &writeTaskHandle);
xTaskCreate(callback_status_task, "callback_status_task", 2048, NULL, 1, &callback_status);
}