2014-02-11
09:18 AM
- last edited on
2023-07-05
01:10 AM
by
Lina_DABASINSKA
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
2014-02-12 05:53 AM
> 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? JW2014-02-12 08:54 AM
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:0x000000022014-02-12 09:52 AM
> 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. JW2014-02-13 12:52 AM
Hello,
In fact, I just check I2SCLK value in the I2S_Init(). RCC register: CR = 0x0F007F83 PLLCFGR = 0x07015410 CFGR = 0x0400100A PLLI2SCFGR = 0x600030002014-02-13 01:29 AM
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. JW2014-02-17 01:18 AM
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. JW2015-06-08 02:13 AM
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, Vincent2015-06-08 05:33 AM
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. meansI2S_InitStructure.I2S_AudioFreq = 4000; // instead of 8000
JW2015-06-09 05:40 AM
Hello,
I confirm it works fine with the change your suggest. Thank you for all. Vincent