cancel
Showing results for 
Search instead for 
Did you mean: 

Word Select Frequency when I2S format is setting to PCM

vincent
Associate II

Posted on February 11, 2014 at 18:18

Hello,

Today, we are using a STM32F405VG which is connected through I2S to a PCM interface of a Bluetooth Controller. The STM32F405VG and the Bluetooth Controller exchange audio data through this I2S with audio frequency = 8 kHz.

In case of the PCM interface of the Bluetooth Controller is master and I2S on STM32 is configured as follow, the audio is OK :

I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;
I2S_InitStructure.I2S_Standard = I2S_Standard_PCMShort;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16bextended;
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
I2S_InitStructure.I2S_AudioFreq = 8000; 
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_Init(I2S_PCM_CSR_SEL, &I2S_InitStructure);

After checking, the frequency of the Word Select Signal is setting to 8 kHz.

But in case of the PCM interface of the Bluetooth Controller is slave and I2S on STM32 is configured as follow, the audio is NOT OK:

I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;

 I2S_InitStructure.I2S_Standard = I2S_Standard_PCMShort;

 I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16bextended;

 I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;

 I2S_InitStructure.I2S_AudioFreq = 8000;

 I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;

 I2S_Init(I2S_PCM_CSR_SEL, &I2S_InitStructure);

After checking,  the frequency of the Word Select Signal is to 16 kHz.

Could you please give us a way to have audio OK when I2S of STM32 is Master?

Thank you

#i2s-pcm-format #poor-quality-of-documentation

9 REPLIES 9
Posted on February 12, 2014 at 14:53

> In case of the PCM interface of the Bluetooth Controller is master and I2S on STM32 is configured as follow, the audio is OK :

> I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;

The frequency set in STM32 in this case is irrelevant.

----

After checking,  the frequency of the Word Select Signal is to 16 kHz.

What is the clock source to I2S?

Can you please read out and tell us the content of relevant registers?

JW

vincent
Associate II
Posted on February 12, 2014 at 17:54

The clock source to I2S is PLL I2S

The PLL clock source is HSI.

After checking, the I2SCLK is setting to 32 MHz as expected (need to change HSE_VALUE by HSI_VALUE in the I2S_Init() function.

The I2S3 registers are :

- for SPI3 :

    CR1:0x00000000

    CR2:0x00000002

    SR:0x00000002

    DR:0x0000FFD8

    CRCPR:0x00000007

    RXCRCR:0

    TXCRCR:0

    I2SCFGR:0x00000E31

    I2SPR:0x0000011F

- for I2S3ext :

    CR1:0x00000000

    CR2:0x00000001

    SR:0x00000002

    DR:0x000000B3

    CRCPR:0x00000007

    RXCRCR:0

    TXCRCR:0

    I2SCFGR:0x00000D31

    I2SPR:0x00000002

Posted on February 12, 2014 at 18:52

> The clock source to I2S is PLL I2S

> The PLL clock source is HSI.

Really?

Are you aware that both the ''main'' PLL and the I2S PLL in fact share the same clock source?

> After checking, the I2SCLK is setting to 32 MHz as expected

How did you check that? You can output I2SPLL onto MCO2. Or, post the relevant RCC registers (CR, PLLCFGR, CFGR, PLLI2SCFGR) too.

JW

vincent
Associate II
Posted on February 13, 2014 at 09:52

Hello,

In fact, I just check I2SCLK value in the I2S_Init().

RCC register:

CR = 0x0F007F83

PLLCFGR = 0x07015410

CFGR = 0x0400100A

PLLI2SCFGR = 0x60003000

Posted on February 13, 2014 at 10:29

Both register sets look good, although the HSI calibration value set (by hardware) to 0x7F is slightly suspicious (but I looked at my specimen of '407 here and that one has 0x73, so maybe it is OK).

You are running the main clock at 84MHz, right? Can you verify that somehow, maybe from timing of UART, SPI, timers and similar?

I'll try to reproduce this here later.

JW

Posted on February 17, 2014 at 10:18

OK so I tried and looking at the waveforms (where WS's frequency was indeed 16kHz and input frequency to SPI was 32MHz) I realized where's the problem: in the documentation (and consequently in the ''library'').

Both the formulae on p.892 of RM0090 rev.6 and the calcualation in I2S_Init() are valid for all the other modes, which are stereo. So, for Philips/LSB/MSB I2S, if you set e.g. 32-bit per channel (in SPI_I2SCFGR.CHLEN), WS is in one state (e.g. low for Philips I2S) for 32 bits (LEFT), then it is in the other state (e.g. high) for next 32 bits (RIGHT), so period in fact occurs after 2x32-bits. On the other hand PCM is mono, i.e. if you set 32-bit per channel, there is one WS pulse per 32-bit, and that's the period.

The remedy is simple, either cut the input frequency for I2S to half, or use twice as high value for the prescaler (SPI_I2SPR.I2SDIV:ODD). If you insist on using the ''library'', call it with half the sampling frequency you want.

JW

vincent
Associate II
Posted on June 08, 2015 at 11:13

Hello,

Sorry to come back now on this problem.

I am not sure to understand where I should change our code :

- change th PLLI2S_R values

- which line in the I2S_Init() API?

Best regards,

Vincent

Posted on June 08, 2015 at 14:33

I am not going to try to understand this issue again, but I guess that

> If you insist on using the ''library'', call it with half the sampling frequency you want.

means

I2S_InitStructure.I2S_AudioFreq = 4000; // instead of 8000

JW

vincent
Associate II
Posted on June 09, 2015 at 14:40

Hello,

I confirm it works fine with the change your suggest.

Thank you for all.

Vincent