cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 HAL Libs I2S 16bit Stereo?

Marco Hess
Associate II
Posted on November 25, 2015 at 21:59

I am confused with the HAL I2S libraries as there does not seem to be support for 16bit stereo (2 channels).

I admit, I am a bit new on I2S but I suspect that with 44100 sampling frequency with two channels of 16 bits each, I need to transfer 32bits per stereo sample to the codec.

The HAL Libraries don't seem to support that. The only modes are the following:

#define I2S_DATAFORMAT_16B               ((uint32_t)0x00000000)

#define I2S_DATAFORMAT_16B_EXTENDED      ((uint32_t)0x00000001)

#define I2S_DATAFORMAT_24B               ((uint32_t)0x00000003)

#define I2S_DATAFORMAT_32B               ((uint32_t)0x00000005)

With the DATAFORMAT value providing bits for two fields on the chip:

In the reference manual 28.5.8 SPI_I2S configuration register (SPI_I2SCFGR)

I find there are two fields related to this: 

Bits 2:1 DATLEN: Data length to be transferred with values for 16, 24, and 32 bits.

and

Bit 0 CHLEN: Channel length (number of bits per audio channel) with 9 for 16 bit and 1 for 32 bits

In the the DATAFORMAT values in the HAL Libraries there is no #define for

transfer of 32bits with 16bit channels. i.e.  ((uint32_t)0x00000004)

What am I missing?

On the same issue, using DMA I suspect I need to do a 32bit memory to 2*16 SPI type transfer to get this right.

2 REPLIES 2
thomfischer
Senior
Posted on November 26, 2015 at 00:14

have a look at DM00031020.pdf 28.4.3 supported audio protocols

if I2S phillips standard is selected (

Bits 5:4

I2SSTD) then 2 channels (left and right) are transmitted

datalen is the number of active bits in a channel (channel is left channel or right channel)

CHLEN is the lenght of one channel (channel is left channel or right channel)

if CHLEN=0 16 bit are transferred for one channel (32 bit for stereo)

if CHLEN=1 32 bit are transferred for one channel (64 bit for stereo)

e.g.

I2S_DATAFORMAT_16B 0x00 (DATALEN=00 CHLEN=0 (16 bit, 32 bit stereo))

LLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRR

I2S_DATAFORMAT_16B_EXTENDED (DATALEN=00 CHLEN=1 (32 bit, 64 bit stereo))

LLLLLLLLLLLLLLLL0000000000000000RRRRRRRRRRRRRRRR0000000000000000

I2S_DATAFORMAT_24B (DATALEN=01 CHLEN=1)

LLLLLLLLLLLLLLLLLLLLLLLL00000000RRRRRRRRRRRRRRRRRRRRRRRR00000000

I2S_DATAFORMAT_32B (DATALEN=01 CHLEN=1)

LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR

for a datalen > 16bit you always need a channel length of 32bit

see

Bit 0

CHLEN

: Channel length (number of bits per audio channel) in SPI_I2SCFGR

''The bit write operation has a meaning only if DATLEN = 00 otherwise the channel length is fixed to

32-bit by hardware whatever the value filled in.''

so 32 bit data lenght cannot be transferred in an 16 bit channel,

what you need is I2S_DATAFORMAT_16B

best regards

maohelin
Associate
Posted on November 29, 2015 at 11:10

Hi,

>On the same issue, using DMA I suspect I need to do a 32bit memory to 2*16 SPI type >transfer to get this right.

No, it doesn't seem to work. When using 16-bit data format (I2S or other) you have to configure the DMA to use ''Half Word'' data width with ''Circular''  DMA mode and memory increment address selected on Cubemx.  Using these I got I2S working with STM32F031F6 device using Cubemx generated project with System Workbench. Haven't yet implemented the half buffer complete callback though, just playing the same buffer initialized with saw waveform forever.