Page 1 of 1

Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Fri Jan 20, 2017 2:21 pm
by BuddyCasino
I found the sample code in i2s.h, and noticed that we can use the built-in DAC to render I2S audio.
However I can't seem to get it working.

This is my init function:

Code: Select all

static void init_i2s_dac()
{

    i2s_config_t i2s_config = {
        .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,          // Only TX
        .sample_rate = 44100,
        .bits_per_sample = 8,                                                   // Only 8-bit DAC support
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           // 2-channels
        .communication_format = I2S_COMM_FORMAT_I2S_MSB,
        .dma_buf_count = 14,                                                    // number of buffers, 128 max.
        .dma_buf_len = 32*2,                                                    // size of each buffer
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1                                // Interrupt level 1
    };

    i2s_pin_config_t pin_config = {
        .bck_io_num = 26,
        .ws_io_num = 25,
        .data_out_num = 22,
        .data_in_num = I2S_PIN_NO_CHANGE                                          // Not used
    };

    i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM, &pin_config);
}
My normal I2S pipeline works fine, but when I use the DAC, I get DMA and buffer underruns.
I feed it samples like this:

Code: Select all

static int convert_sample(short s) {

    // convert 16bit to 8bit and duplicate mono sample to both channels
    char eightBit = s >> 8;
    short samp = eightBit;
    samp = (samp) & 0xff;
    samp = (samp << 8) | samp;
    return samp;
}
Any idea whats wrong?

Re: Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Wed Jan 25, 2017 4:05 am
by telanoc
Doesn't this do the same thing?

Code: Select all

static int convert_sample(short s) {

    return s & 0xff00 | s >> 8;
  
}

Re: Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Wed Jan 25, 2017 8:49 pm
by telanoc
Hmm... I think I should have typed

Code: Select all

return (unsigned short) s & 0xff00 | (unsigned short) s >> 8;
:oops:

Re: Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Fri Jan 27, 2017 9:19 am
by BuddyCasino
Probably, yes. I'm not very experienced with C though, so the commonly known bit-twiddling idioms don't come easy to me, yet. This method should return a short btw (2 x 8 Bit), my mistake. Not that this fixes anything.

Re: Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Sun Jan 29, 2017 3:48 am
by ESP_Sprite
Fyi, it seems the I2S driver has a bug in DAC mode: the sample rate it sets is actually 8 times the sample rate you tell it to use. I have a bug fix in the internal merge queue, it will probably be merged after the holidays.

Re: Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Sun Jan 29, 2017 5:15 am
by WiFive
ESP_Sprite wrote:Fyi, it seems the I2S driver has a bug in DAC mode: the sample rate it sets is actually 8 times the sample rate you tell it to use. I have a bug fix in the internal merge queue, it will probably be merged after the holidays.
Interesting is that because all the bits are latched into the DAC register on one clock edge?

Re: Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Sun Jan 29, 2017 7:20 am
by ESP_Sprite
I think the DAC mode is one of the odd ones that uses BCLK as the latch clock. All other parallel modes seem to use WS for that. Not entirely sure; I can't really ask the hw people at this moment.

Re: Use I2S in I2S_MODE_DAC_BUILT_IN Mode

Posted: Mon Jan 30, 2017 9:56 am
by BuddyCasino
Thanks for the feedback! Bit of a relief to finally know the cause.