Byte swapping between I2S and USB audio

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ravo
Level 5
Level 5
10 likes received 5 comments on blog 5 solutions authored

Dears

I am examining USB Audio Device (FreeRTOS) demo project https://github.com/Infineon/mtb-example-psoc6-usb-audio-device-freertos. I did not see any endian conversion in sample code between I2S and USB audio data buffers. Only conversions between 32 -> 24 bits. I also have a look in mtb_shared if it is part of USB middleware.

I suppose that I2S communication is in Big endian (MSB transmitted on SD line first, then MSB-1, ...) but USB audio data is Little endian.

This is well written in datasheet for "Inter-IC Sound Bus (I2S) 2.60" module https://www.infineon.com/dgdl/Infineon-Component_I2S_V2.60-Software%20Module%20Datasheets-v02_07-EN.... for  PSoC Creator, and there is support for Byte-Swapping as written on page 6.

How it is done in ModusToolbox ?

Regards

Radim

0 Likes
1 Solution
RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

Hi Radim,

The data read from the I2S FIFO is already little endian. Sorry, actually the firmware is not doing byte-swapping, it is just a padding to pack the 32-bit values in 24-bits.

It seems the hardware already does what you are looking for. If you need to use big-endian, then you would need to do in firmware.

Sorry again for the confusion.

View solution in original post

7 Replies
RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

The byte-swapping feature is only available in the I2S UDB based implementation.

If using the I2S fixed-function block from PSoC 6, there is no option to do byte-swapping. It has to be done in firmware, as the audio-device-freertos code example does.

0 Likes
ravo
Level 5
Level 5
10 likes received 5 comments on blog 5 solutions authored

Dear @RodolfoGL ,

Thanks for quick response.

And where, maybe I am so blind... ? I am not able to find it.

/* Read all the data in the I2S RX buffer */
cyhal_i2s_read(&i2s, (void *) audio_in_pcm_buffer, &audio_in_count);

It seems that audio_in_pcm_buffer is little endian. So it is stored already by words instead of raw bytes readed from I2S SD data line ?

Than I have found only 32 bit -> 24 bit conversion and this did not swap, data in PCM and then send to USB endpoint buffer.

/*******************************************************************************
* Function Name: convert_32_to_24_array
********************************************************************************
* Summary:
* Convert a 32-bit array to 24-bit array.
*
*******************************************************************************/
void convert_32_to_24_array(uint8_t *src, uint8_t *dst, uint32_t length)
{
while (0u != length--)
{
*(dst++) = *src++;
*(dst++) = *src++;
*(dst++) = *src++;
src++;
}
}

 

Regards

Radim

0 Likes
RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

Hi Radim,

The data read from the I2S FIFO is already little endian. Sorry, actually the firmware is not doing byte-swapping, it is just a padding to pack the 32-bit values in 24-bits.

It seems the hardware already does what you are looking for. If you need to use big-endian, then you would need to do in firmware.

Sorry again for the confusion.

ravo
Level 5
Level 5
10 likes received 5 comments on blog 5 solutions authored

Dear @RodolfoGL ,

thanks for confirmation. Now it is clean for me... I am fine with little endian (because it is default endianness for ARM and also needed for USB audio endpoint)  So really need to do byte-swapping.

Best Regards

Radim

0 Likes
ravo
Level 5
Level 5
10 likes received 5 comments on blog 5 solutions authored

Dear @RodolfoGL ,

Small update... Maybe I am wrong, but the function convert_32_to_24_array is for Big-Endian, because it throw away last 4th byte asi it is least significant byte. Do tou still think that i2s read really return little endian?

Radim

 

0 Likes
RodolfoGL
Employee
Employee
250 solutions authored 250 sign-ins 5 comments on KBA

Yes, it is definitely little-endian. We can do operations directly with the words read from the I2S FIFO with the ARM CPU, which is little-endian.

I think the convert_32_to_24_array implementation is correct. Here is an example of a register in 32-bit format:

RodolfoGL_0-1674514118765.png

In our case, we want to discard the 0x0A byte, which is placed in a+3.

ravo
Level 5
Level 5
10 likes received 5 comments on blog 5 solutions authored

Dear @RodolfoGL ,

yes I know the coding of int32 in memory, but I forgot that Cirrus Logic CS5343 is 24bit DAC and  (a+3) byte is still 0x00 (zero, unused). So the calculation is correct if we throw away this unused byte.

So now it is working as expected, and I can generate sounds programmatically. 

Best Regards

Radim

0 Likes