Store I2S bytes in different order

goldenDragon
Posts: 3
Joined: Tue Jan 29, 2019 3:48 pm

Store I2S bytes in different order

Postby goldenDragon » Tue Jan 29, 2019 5:32 pm

Hi, I am using I2S to retrieve data from an ADC. Each sample is 32 bits and comes MSB first with the frame sync frequency equaling the ADC sampling speed. The two most significant bytes come in as the frame sync signal is high and then the two least significant bytes come in as frame sync is low. The problem is the esp32 seems to put the least significant bytes of the previous ADC sample with the most significant bytes of the current sample in memory (or at least that's what it looks like to me). Does anyone know how to make the esp32 store the bytes with the right channel first followed by the left channel since that is the order in which the bytes are being transferred from my ADC?

Here is what i see from the logic analyzer:
Capture.JPG
Capture.JPG (44.75 KiB) Viewed 3564 times
But this is the order that I get the data when I run the code below:

0: 526d1072
1: 146f7028

Code: Select all

   

void print_adc_data(void)
{
	for(uint32_t i = 0; i < adc.index; i = i+BYTES_PER_SAMPLE)
    	{
		printf("%d: %02x%02x%02x%02x\n",
		(i/BYTES_PER_SAMPLE),(uint8_t)adc.data[i],(uint8_t)adc.data[i+1],(uint8_t)adc.data[i+2],(uint8_t)adc.data[i+3]);
    }   
}  

 
#define NUM_OF_SAMPLES 100
#define BYTES_PER_SAMPLE 4
#define SAMPLE_RATE  125000


typedef struct
{
    int8_t data[NUM_OF_SAMPLES*BYTES_PER_SAMPLE];
    uint32_t index;
} ADC;

ADC adc;

void app_main(void)
{
   i2s_config_t i2s_config = {
        .mode = I2S_MODE_SLAVE | I2S_MODE_RX,                                  
        .sample_rate = SAMPLE_RATE,
        .bits_per_sample = 16,
            .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,                         
        .communication_format = I2S_COMM_FORMAT_PCM,
        .dma_buf_count = 4,
        .dma_buf_len = 100,
        .use_apll = false,
        .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1                                //Interrupt level 1
    };
    i2s_pin_config_t pin_config = {
        .bck_io_num = ADC_SCLK,
        .ws_io_num = ADC_FSYNC,
        .data_out_num = -1,
        .data_in_num = ADC_DOUT                                              
    };

    i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
    i2s_stop(I2S_NUM);
    i2s_set_pin(I2S_NUM, &pin_config);
    ....
    i2s_read(I2S_NUM, adc.data, NUM_OF_SAMPLES*BYTES_PER_SAMPLE, &br, portMAX_DELAY );
    print_adc_data(void);
 }

ESP_Sprite
Posts: 9599
Joined: Thu Nov 26, 2015 4:08 am

Re: Store I2S bytes in different order

Postby ESP_Sprite » Wed Jan 30, 2019 4:04 am

The ESP32 is little-endian, so if you let the CPU interpret it as an 16-bit number, the byte swap happens 'automatically':

Code: Select all

printf("%d: %02x %02x\n",
		(i/BYTES_PER_SAMPLE),(uint16_t)adc.data[i/2],(uint16_t)adc.data[i/2+1]);
The only problem then is that the I2S peripheral stores the 16-bit values in the wrong order; unfortunately there's not really a solution for that.

Who is online

Users browsing this forum: derricksenva, khervey and 87 guests