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);
}