CP2615 I2S compatibility

StijnVM
Posts: 4
Joined: Mon Jul 30, 2018 7:31 pm

CP2615 I2S compatibility

Postby StijnVM » Mon Jul 30, 2018 8:49 pm

Hi Guys,

Pretty new to the ESP32. I'm trying to interface it with Silicon Labs CP2615 USB-I2S bridge.
  • CP2615 can only function as I2S master
  • The bitclock is not continuous, but in bursts.
  • The bursts always come in 24 pulses, even if you set the bridge to 16bit mode (needed, because playback + recording should be possible at the same time). See https://www.silabs.com/community/interf ... decad-84UG

For now, ESP32 is only to be used as an A2DP sink so started from the A2DP sink example. My config:

Code: Select all

 i2s_config_t i2s_config = {
        .mode = I2S_MODE_SLAVE | I2S_MODE_TX,                                  // Only TX
        .sample_rate = 48000,
        .bits_per_sample = 16,                                             
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           //2-channels
        .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
        .dma_buf_count = 6,
        .dma_buf_len = 60,                                                      //
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1                                //Interrupt level 1
        .use_apll = true
    };


I've been playing around with
  • changing i2s_set_clk(0, sample_rate, 16, 2) to i2s_set_clk(0, sample_rate, 24, 2); on line 114 of bt_app_av.c
  • calling i2s_write_expand (16 src, 24 aim) instead of i2s_write on line 57 of bt_app_av.c
  • I noticed the data was being pushed out on the rising edge of the clock instead of falling, while this was not the case in master mode. Rather odd, tried multiplying the fi2s_clk with a factor 3/2 on line 434 of i2s.c because the bursts are about 3/2 faster than a normal bitclock. Not really trusting this one..

Right now I can barely recognise the song being played. It's heavily distorted.

Something else I came across. The technical reference manual says:
when esp32 i2s works in slave mode, the master must use i2sn_clk as the master clock and fi2s >= 8 * fbck.

I'm not sure what this means.. Right now the bridge is just supplying the bitclock and the LRclock.

I have a lot more research to do but if anyone has experience, ideas, knowledge this will not work,.. please shoot!
Many thanks!

StijnVM
Posts: 4
Joined: Mon Jul 30, 2018 7:31 pm

Re: CP2615 I2S compatibility

Postby StijnVM » Thu Aug 02, 2018 9:36 am

OK so I found out the data got shifted and couldn't explain why.
I started simplifying the problem and now I have 2 esp32's connected, with one acting as a master and one as a slave. This takes away the uncertainty of the bursty/higher frequency bitclock from the CP2615.

This is the testprogram I'm using on the slave right now:
It basically always writes the same pattern to left and right in a block of 40 to the DMA buffer.

Code: Select all

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "esp_system.h"
#include <math.h>

#define I2S_NUM         (0)

static void setup_testblock()
{
   unsigned int n_blocks = 40;
    int *samples_data = malloc(8*n_blocks);
       size_t i2s_bytes_write = 0;

    unsigned int i;
    for(i = 0; i < n_blocks; i++)
    {
            samples_data[i*2] = -1431655681;          //0b101010101010101010101010(11111111) last byte should be dropped
            samples_data[i*2 + 1] = -286331137;         //0b111011101110111011101110(11111111) last byte should be dropped
    }

    i2s_write(I2S_NUM, samples_data, n_blocks*4, &i2s_bytes_write, 100);
    //i2s_write_expand(I2S_NUM, samples_data, ((bits+8)/16)*SAMPLE_PER_CYCLE*4, 16, 16, &i2s_bytes_write, 10);

    free(samples_data);
}
void app_main()
{
    i2s_config_t i2s_config = {
        .mode = I2S_MODE_SLAVE | I2S_MODE_TX,                                  // Only TX
        .sample_rate = 48000,
        .bits_per_sample = 24,
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                           //2-channels
        .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
        .dma_buf_count = 2,
        .dma_buf_len = 30,
        .use_apll = true,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1                               //Interrupt level 1
    };
    i2s_pin_config_t pin_config = {
        .bck_io_num = 26,
        .ws_io_num = 22,
        .data_out_num = 25,
        .data_in_num = -1                                                       //Not used
    };
    i2s_driver_install(0, &i2s_config, 0, NULL);
    i2s_set_pin(0, &pin_config);

    setup_testblock();
    while (1)
    {
        vTaskDelay(5000/portTICK_RATE_MS);
    }

}




Although less pronounced, I still see the same shifts of data I was seeing before. Occasionally, the data out is low during 16 clockcycles although I never write more than 1 consecutive zero's. The data is shifted but usually recovers on a high-to-low LRclock transition.

Overview of the problem. Channel 1 is LRclock (coming from the master esp32), Channel 2 is data (coming from the slave esp32)
Image

Zoomed in:
Image
(Sorry for the low quality screens)

I noticed this does not happen when bits_per_sample is set to 32 (for both master and slave).
It seems like the esp32 sometimes 'forgets' the bit depth is set to 24 and clocks out 2*32 bits instead of 2*24 bits although not using the final byte in the data (which should be discarded) because it is set to 0xFF and it outputs 0x00 instead..

Can someone confirm this? Am I missing something?
Many thanks!

StijnVM
Posts: 4
Joined: Mon Jul 30, 2018 7:31 pm

Re: CP2615 I2S compatibility

Postby StijnVM » Thu Aug 02, 2018 9:21 pm


Who is online

Users browsing this forum: Google [Bot] and 12 guests