cancel
Showing results for 
Search instead for 
Did you mean: 

SAI - get best clock accuracy

SLasn.1
Associate II

Hi 🙂

This is related to my other post (https://community.st.com/s/question/0D53W00000EcBvNSAV/sai-no-signal-on-mclk-pin) but I thought it would be more organised to make two posts since the question is different.

How do I get the best audio clock accuracy using the separate SAI PLL without fiddling manually with all the values?

The SAI clock should be one of these, or as close as possible to be accurate:

0693W000002lgZ0QAI.png

I tried just entering the value in CubeMX but clearly it is not possible to get exactly those values so CubeMX cannot manage.

What I would like ideally is a simple way to say I want fs=44.1kHz audio freq for ex and then the tool tries to get a SAI clock as close as possible as one of the possible frequencies (128fs, 256fs, etc.).

I actually found the perfect tool - exactly what I'm describing - but it is for the I2S and not the SAI which uses different master clocks. (for those interested, the tool is an excel sheet: https://www.st.com/resource/en/application_note/dm00039457-clock-configuration-tool-for-stm32f40xx41xx427x437x-microcontrollers-stmicroelectronics.pdf )

My question to you: how do you do it, you just fiddle manually with the values until you get something close?

Thanks

Simon

11 REPLIES 11

Well, you start with a crystal appropriate to the task, i.e if you want 44.1kHz, you get a multiple of that, and not any integer-multiple-of-MHz one.

There's also a dedicated clock input for I2S/SAI, for a reason.

JW

gregstm
Senior III

In my application I only wanted to use the LSE as my accurate clock source, so I did a bit of a cheat - I DMA'ed the SAI results to a single memory location, then used a timer driven by the LSE clock to DMA to another buffer. That way I had crystal accurate results with just a low cost LSE. (note: my sample rate requirements were fairly modest (16KHz). DMAing from the SAI to a single memory location is required because the SAI has a FIFO that needs to be continually cleared to make the LSE resampling accurate)

Oooh interesting!! I actually did not think about that at all :D

I can see the I2S clock input is only on one pin though, that means I need an external IC to generate a clock, I cannot simply use a crystal there, can I?

Also my product ideally has to be able to run both at 48kHz and 44.1kHz (not simultaneously but with the same hardware).

I am not using the LSE so I probably won't do that but it's still super interesting! :D

Thanks for sharing 😉

Yes, the I2S clock input would need an oscillator. Some audio ADC/DAC/codecs do have integrated oscillator, even fractional-PLL; there are also standalone oscillators, sometimes integrated with PLL, too. I don't say they are cheap, but they are convenient.

Maybe you can pull this out using the HSE oscillator, but first, make priorities. In audio product, it's probably the audio you want to be the most precise. It may be possible to find a solution to generate both the 44k1 and 48k range of frequencies from a single crystal. I'm not going to find it now. Then, prioritize according to required precision (USB-USART-whatnot; system clock as such is probably the least important although that's what most calculators aim at primarily) and try to find the combination of multipliers and dividers to get as close as possible.

JW

For example:

6.144MHz / 5 * 147 / 16 = 44k1 * 256

6.144MHz / 5 * 100 / 10 = 48k * 256

6.144MHz / 4 * 125 / 4 = 48MHz

6.144MHz / 4 * 234 / 2 = 179.712MHz

JW

SLasn.1
Associate II

Wow I am literally blown away, this is amazing!! :D

For some reason I was stuck in the world of 8/16/25Mhz crystals, that opened a whole new world! 🙂

Yes I was thinking ideally avoid the costly external oscillators, and avoid the very probably price raise of the DAC if I want it to have integrated oscillator (the one I chose is cheap and does not have one).

And yes indeed the project will use USB + SDIO + FSMC display (I have not really looked into this yet but I guess this will not require a special clock) and I'll also need a UART at 31.250kHz but that is quite low so it should be possible to get very close with pretty much any config I think.

So basically you sorted it out for me - thank you so much for that - I am still wondering though:

1) how did you do it - just kinda guestimating the values here and there, testing and after some time found a value that works?

2) would it not be nice to have to tool to do that for us? I am literally thinking of making one.

Ok I actually have a partial answer to my first question - going there f.x.: https://en.wikipedia.org/wiki/Crystal_oscillator_frequencies actually gives a really good starting point as they mention which frequency is usually used for what 🙂 That reduces a lot the amount of crystal frequencies to try with.

> UART at 31.250kHz

Ah, a MIDI gadget...

179.712MHz / 4 / 90 / 16 = 31.200kHz, the error is 0.16%, that should be okay.

> 1) how did you do it - just kinda guestimating the values here and there, testing and after some time found a value that works?

I was already there, having worked with audio and 'F446. I had the luxury of having a dedicated high-quality oscillator on the dedicated I2S_CLK input, and also I didn't need to support 44k1... but I had the calculations done back then and just dug them out 🙂 .

> 2) would it not be nice to have to tool to do that for us? I am literally thinking of making one.

It's actually not THAT hard to write an ad-hoc tool for it. However, it's probably hard to polish it into anything universally usable.

> https://en.wikipedia.org/wiki/Crystal_oscillator_frequencies

Yes I know that table, but I actually go by the offerings in outlets like Mouser. For example, the least common denominator between 44k1 and 48k is 7.056MHz (that value is not in that table, but twice that is, 14.112MHz). However, these are fairly rare crystals.

JW