I2S Input DMA setup
Posted: Sun Mar 19, 2023 10:41 pm
Hello - I am trying to interface a mems I2C microphone to I2S0 - I have verified that the device is clocking and outputing data - The idea is to setup DMA buffers, to trigger an interrupt when DMA is complete, from the DMA ISR signal a task that will read out the last buffer, process it and notify other consumers for that data.
My problem seems to be that the DMA ISR is not getting set. I checked that the semaphores are setup properly, but I can't quite figure it out. Here is the code:
Any ideas why i2s_isr_handler does not get called? Both esp_intr_alloc() and esp_intr_enable() return ESP_OK.
Thank you
My problem seems to be that the DMA ISR is not getting set. I checked that the semaphores are setup properly, but I can't quite figure it out. Here is the code:
- static int16_t dma_buf[DMA_BUF_COUNT][DMA_BUF_LEN];
- static int buf_ptr = 0;
- SemaphoreHandle_t i2s_dma_sem;
- static intr_handle_t i2s_isr_ret_handle;
- void IRAM_ATTR i2s_isr_handler(void *arg)
- {
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- xSemaphoreGiveFromISR(i2s_dma_sem, &xHigherPriorityTaskWoken);
- if (xHigherPriorityTaskWoken) {
- portYIELD_FROM_ISR();
- }
- }
- void mic_task(void *arg)
- {
- size_t bytesRead;
- color_t sample_colors[6] = { red, green, blue, yellow, purple, silver };
- printf("mic_task enabled\n\r");
- while (1)
- {
- if (xSemaphoreTake(i2s_dma_sem, portMAX_DELAY) == pdTRUE) {
- // Process the data in dma_buf[buf_ptr]
- // ...
- i2s_read(I2S_NUM, (void *)&dma_buf[buf_ptr], DMA_BUF_LEN * sizeof(int16_t), &bytesRead, 0);
- buf_ptr = (buf_ptr + 1) % DMA_BUF_COUNT;
- printf("Read %d bytes",bytesRead);
- // Signal the main application that new data is available
- // ...
- }
- }
- }
- void mic_init()
- {
- i2s_config_t i2s_config = {
- .mode = I2S_MODE_MASTER | I2S_MODE_RX,
- .sample_rate = 44100,
- .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
- .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
- .communication_format = I2S_COMM_FORMAT_I2S_MSB,
- .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
- .dma_buf_count = DMA_BUF_COUNT,
- .dma_buf_len = DMA_BUF_LEN,
- .use_apll = false,
- .tx_desc_auto_clear = false,
- .fixed_mclk = 0,
- };
- i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
- i2s_set_clk(I2S_NUM, 44100, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO);
- i2s_pin_config_t pin_config = {
- .mck_io_num = I2S_PIN_NO_CHANGE,
- .bck_io_num = 3,
- .ws_io_num = I2S_PIN_NO_CHANGE,
- .data_out_num = I2S_PIN_NO_CHANGE,
- .data_in_num = 8
- };
- i2s_set_pin(I2S_NUM, &pin_config);
- i2s_zero_dma_buffer(I2S_NUM);
- i2s_dma_sem = xSemaphoreCreateBinary();
- esp_err_t err =esp_intr_alloc(ETS_I2S0_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1 | ESP_INTR_FLAG_IRAM, i2s_isr_handler, NULL, &i2s_isr_ret_handle);
- if (err != ESP_OK)
- ESP_LOGE(TAG, "Error esp_intr_alloc %s", esp_err_to_name(err));
- err = esp_intr_enable(i2s_isr_ret_handle);
- ESP_LOGI(TAG, "INTERRUPT Enable: %d ", err);
- xTaskCreate(mic_task, "mic_task", 4096, NULL, 5, NULL);
- }
Thank you