Skip to main content
kraiskil
Associate III
August 2, 2017
Solved

CubeMX generates wrong I2S frequency on STM32F401C-Discovery

  • August 2, 2017
  • 4 replies
  • 7983 views
Posted on August 02, 2017 at 11:42

I have a clean slate CubeMX project on a STM32F401C-Discovery board. I have set up the onboard Cirrus audio DAC, and send a hard-coded test signal to it via DMA-driven I2S. I can hear the sound, but it is at wrong frequency.

The 2kHz test signal, and the i2s-3 is set to 48kHz samplerate, but depending on how I configure the PLL, I hear 122Hz, 180Hz or 244Hz audio. I have confirmed with a logic analyzer that the I2S protocol runs too slow.

The only things I have changed from the CubeMX generated template project is:
  • enable i2c-1 (communication with the DAC, this works)
  • enable i2s-3
  • configure i2s-3 to have a cyclic DMA, 48kHz, 16bits on 32bit dataframe

In the source code, I only initialize the DAC and enable the DMA. No other changes to the generated source are done.

The three configurations I tried with:

PLLM=4 gives a I2S WS (frame clock) of 2.93kHz, and the 2kHz audio is at 122Hz:0690X00000607mlQAA.png

With PLLM=6, I see a WS of 4.4kHz, and audio at 184Hz:

0690X00000607ptQAA.png

And with PLLM=8, WS is at 5.859kHz, and the audio at 244Hz:

0690X00000607pyQAA.png

CubeMX is version 4.21.0, F4-firmware package is version 1.16.0

Going through the STM32F401 reference manual and device registers hasn't yet given me a clue where CubeMX generates the bug.

Suggestions (and CubeMX bugfixes) much appreciated

kalle

#cubemx #i2s #frequency
This topic has been closed for replies.
Best answer by kraiskil
Posted on August 03, 2017 at 07:59

waclawek.jan wrote:

PS. What's written on the chip?

That's it! Thanks for the tip.

While the board is clearly labeled 'STM32F401C-DISCO', the chip on it is, in fact a STM32F411VET6U.

So in Cube's jargon, I have a 'STM32F411E-DISCO' board. Perhaps it said so on the package, but that is lost in time.

(Now looking on my Nucleo boards, the board label is on a sticker. But seems the Nucleo boards don't seem to have a default value under the sticker... Anyways, I can't recall this Discovery board ever having had a sticker on it.)

Almost besides the point now, but as an explanation for the problems above: it seems the F411 has separate PLL_M divisors for I2S and the rest of the system. Using the correct chip in CubeMX solves the issue - the audio comes out at 2kHz now.

Thanks for the help. This was a learning experience

kalle

4 replies

waclawek.jan
Super User
August 2, 2017
Posted on August 02, 2017 at 12:15

Output the I2S and main clock to MCO to check.

Read out and post the content of relevant RCC and SPI/I2S registers.

JW

kraiskil
kraiskilAuthor
Associate III
August 2, 2017
Posted on August 02, 2017 at 13:38

RCC:

  • RCC_PLLCR: 0x0f038683
  • RCC_PLLCFGR = 0x06412404
  • RCC_CFGR = 0x0000100a
  • RCC_PLLI2SCFGR = 0x20003000

SPI3:

  • CR1 = 0x0
  • CR2 = 0x0
  • SR = 0x2
  • I2SCFGR = 0xa01
  • I2SPR = 0x208

Did I miss any relevant ones?

This is taken after MX_I2S_Init() has finished, but before transmission. The only odd thing I can find is the I2SE (enabled) bit is zero here,

but if I interrupt the processor when it has started streaming, even that bit is set (I2SCFGR=0x0e01).

This is the configuration from above where PLL_M=4

(Edit: I need to find a more high-powered analyzer to check the clocks via MCO. Will do this as soon as possible)

waclawek.jan
Super User
August 2, 2017
Posted on August 02, 2017 at 14:21

Well, I expected my post will make you think and do the analysis (read: homework) yourself... :)

There's no RCC_PLLCR in RM0368, I take it you meant RCC_CR.

If I calculate it correctly, you have:

- both PLLs and HSE ON (and also HSI ON  but that does not matter except for a miniscule increase in consumption)

- PLLM = 4 => PLL input is 2MHz (if the Xtal is 8MHz indeed)

- PLLN=144 (that does not match the M=4 picture from above)

- PLLP = 1 => /4 => (together with HPRE =0 i.e. AHB not divided) SYSCLK = 8/4*144/4 = 72MHz

- PLLQ = 6

- I2S clock is PLLI2S

- PLLI2SN = 192

- PLLI2SR = 2 => I2SClock = 8/4*192/2=192MHz

Is this what you wanted? Can you confirm it with outputting the I2SPLL onto MCO2 and observing it using the LA?

SPI_I2SPR.MCKOE = 1 i.e. MCK is enabled

I2SDIV = 8  and ODD = 0 => MCK frequency is 192MHz/(2*8+0) = 12MHz  Can you confirm it?

JW

Mohamed Jallouli_2
Associate
August 2, 2017
Posted on August 02, 2017 at 13:45

Hi

Raiskila.Kalle

‌,

What is your target I2S bitrate (the frequency atwhichyou are willing to send the datato the DAC)?

Jae

kraiskil
kraiskilAuthor
Associate III
August 2, 2017
Posted on August 02, 2017 at 13:55

Hi,

I'm targeting 48kHz samplerate, with 2*32 bits per sample (actually 16 bits data on a 32 bit frame). So bitrate is 3.072Mbps.

The test signal is 2kHz sine wave sampled at 48kHz. A standard 1kHz sine was nolonger recognizable as a sine wave in the audio output. At least with these low quality speakers

waclawek.jan
Super User
August 2, 2017
Posted on August 02, 2017 at 15:02

But you still can measure the bitclock (I2S_CK) can't you. With the above setting it should be exactly 3MHz.

JW

kraiskil
kraiskilAuthor
Associate III
August 2, 2017
Posted on August 02, 2017 at 15:39

Yes, the I2S bitclock is measurable. With the above register settings, it is 187.5 kHz which is  2*32*Fs (here the measured Fs(i.e. I2S_WS)=2.93kHz).

So it seems the SPI/I2S hw block is getting some strange input clock?

waclawek.jan
Super User
August 2, 2017
Posted on August 02, 2017 at 16:04

Yeah, that's strange. This is why it would be nice to see the clock as close to the root as possible.

Could you try to configure the PLL to the lowest possible frequency (PLLM set to 8 so that I2SPLL input is 1MHz, PLLI2SN set to so that PLL output is 192MHz, R divider set to 7 thus I2S input frequency is ) and then output it onto MCO2 while dividing it as much as possible (/5) - that should bring it down to 5.485MHz which should already be measurable with what you have at hand.

JW

waclawek.jan
Super User
August 2, 2017
Posted on August 02, 2017 at 20:00

Try to set the lower 5 bits in RCC_PLLI2SCFGR to 0x08, i.e. in the example

https://community.st.com/0D50X00009XkXzCSAV

set RCC_PLLI2SCFGR = 0x20003008

JW

PS. What's written on the chip?

kraiskil
kraiskilAuthorAnswer
Associate III
August 3, 2017
Posted on August 03, 2017 at 07:59

waclawek.jan wrote:

PS. What's written on the chip?

That's it! Thanks for the tip.

While the board is clearly labeled 'STM32F401C-DISCO', the chip on it is, in fact a STM32F411VET6U.

So in Cube's jargon, I have a 'STM32F411E-DISCO' board. Perhaps it said so on the package, but that is lost in time.

(Now looking on my Nucleo boards, the board label is on a sticker. But seems the Nucleo boards don't seem to have a default value under the sticker... Anyways, I can't recall this Discovery board ever having had a sticker on it.)

Almost besides the point now, but as an explanation for the problems above: it seems the F411 has separate PLL_M divisors for I2S and the rest of the system. Using the correct chip in CubeMX solves the issue - the audio comes out at 2kHz now.

Thanks for the help. This was a learning experience

kalle

waclawek.jan
Super User
August 3, 2017
Posted on August 03, 2017 at 09:47

Wow.

I did not check and realize that there's no 401-DISCO in the current offering... The 401-DISCO has apparently been withdrawn in favour of the 411-DISCO, recycling the board.

There are some remnants of the 401-DISCO on st.com, such as UM1660.

JW