Store I2S bytes in different order
Posted: 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:
But this is the order that I get the data when I run the code below:
0: 526d1072
1: 146f7028
Here is what i see from the logic analyzer:
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);
}