Page 1 of 1

Is DAC output from i2s faster than writing to dma tx buffer ?

Posted: Fri Jul 19, 2024 4:11 pm
by noweare
Using esp-idf 4.4.7

In this code I am expecting to get buffer overflow events but I am not.

It appears that continously writing to the dma tx buffer is slower than
the dma_tx_buffer outputing data to the DAC.

One task is printing out i2s events as they happen.
The other task continously writes 2048 bytes to the dma tx buffer.

Each dma buffer is 256 bytes. I have 2 buffers.

I get I2S_EVENT_TX_DONE event 8 times for every i2s_write().

so 2048/8 = 256 bytes (which is the size of one dma buffer)

Does this mean that DAC is getting data faster than I can write to the dma tx buffer. That
seems the only explaination for not over running the buffer

Code: Select all

void i2sTaskMonitor(void *param)
{
    SignalGenerator *output = (SignalGenerator *)param;
    i2s_event_t evt;

    while (true)
    {
        if (xQueueReceive(output->m_i2sQueue, &evt, portMAX_DELAY) == pdPASS)
        {
            // log_i("evt = %d", evt.type);
            if (evt.type == I2S_EVENT_TX_DONE)
                log_i("TX_DONE");

            if (evt.type == I2S_EVENT_TX_Q_OVF)
                log_i("TX_Q_OVF");
        }
    }
}

void i2sWriterTask(void *param)
{
    int buffer_position = 0;
   
    uint16_t sawTooth[1024];
    for (int i = 0; i < 1024; i += 2)
    {
        sawTooth[i] = (i % 32) << 11;
        sawTooth[i + 1] = sawTooth[i];
        // Serial.printf("%d\n", sawTooth[i]);
    }
    while (true)
    {       
        size_t bytesWritten = 0;
        do
        {
            int availableSamples = 1024 ;
           
            i2s_write(I2S_NUM_0, sawTooth, availableSamples * 2, &bytesWritten, portMAX_DELAY);
            
             log_i("Wrote %d bytes", bytesWritten);
        } while (bytesWritten > 0);
    }
   
}

void SignalGenerator::start(long freq)
{
    // i2s config for writing both channels of I2S
    i2s_config_t i2sConfig = {
        .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
        .sample_rate = freq,
        .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_MSB),
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
        .dma_buf_count = 2,
        .dma_buf_len = 64,
        .use_apll = 1};

    // Set the pinout configuration (set using menuconfig)
    i2s_pin_config_t pin_config = {
        .mck_io_num = I2S_PIN_NO_CHANGE,
        .bck_io_num = PIN_I2S_SCK,      // 14
        .ws_io_num = PIN_I2S_FS,        // 25
        .data_out_num = PIN_I2S_SD_OUT, // 26
                                        // .data_in_num = PIN_I2S_SD_IN,   // 35
        .data_in_num = I2S_PIN_NO_CHANGE};

    // install and start i2s driver
    i2s_driver_install(I2S_NUM_0, &i2sConfig, 4, &m_i2sQueue);
    int status = i2s_set_pin(I2S_NUM_0, &pin_config);
    if (status != ESP_OK)
        log_i("pin config failed");
    // enable the DAC channels
    i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
    // clear the DMA buffers
    i2s_zero_dma_buffer(I2S_NUM_0);
    // start a task to write samples to the i2s peripheral
    TaskHandle_t writerTaskHandle;
    xTaskCreate(i2sWriterTask, "i2s Writer Task", 4096, this, 1, &writerTaskHandle);
    TaskHandle_t monitorTaskHandle;
    xTaskCreate(i2sTaskMonitor, "i2s Task Monitor", 2048, this, 2, &monitorTaskHandle);
}


Re: Is DAC output from i2s faster than writing to dma tx buffer ?

Posted: Fri Jul 19, 2024 6:35 pm
by MicroController
noweare wrote:
Fri Jul 19, 2024 4:11 pm
Does this mean that DAC is getting data faster than I can write to the dma tx buffer.
It means that i2s_write(..., portMAX_DELAY) will block and only return once it was able to enqueue all data to the buffer, thereby implicitly throttling the rate at which you can i2s_write data if necessary.

Re: Is DAC output from i2s faster than writing to dma tx buffer ?

Posted: Fri Jul 19, 2024 6:56 pm
by noweare
Thanks Microcontroller. Came back to delete the post after figuring that out but you beat me.
I was wondering why the dac output rate was less than the 16kHz sample rate.
Thanks again.

Re: Is DAC output from i2s faster than writing to dma tx buffer ?

Posted: Fri Jul 19, 2024 7:07 pm
by MicroController
noweare wrote:
Fri Jul 19, 2024 6:56 pm
Came back to delete the post after figuring that out but you beat me.
Sometimes I Post Reply faster than my own shadow :D