Skip to main content
Marco Hess
Associate II
November 25, 2015
Question

STM32 HAL Libs I2S 16bit Stereo?

  • November 25, 2015
  • 2 replies
  • 1406 views
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.

    This topic has been closed for replies.

    2 replies

    thomfischer
    Senior
    November 25, 2015
    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
    November 29, 2015
    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.