cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronize peripherals SAI & I2S output clocks

LCE
Principal

Heyho,

I'm using a H733 with both SAI 1 and SAI 4 with SAI 1 as I2S clock master to get 8 synced audio channels.

Audio clock comes from I2SCKIN, this is used for SAIs and I2S.

Problem: because of the fixed oversampling ratio (256 or 512) of the SAI, I have to use an SPI/I2S peripheral to generate the "MCLK" to make 200 kHz possible, with 200 kHz x 128 = 25.6 MHz.

That's basically working, but I wonder why sometimes at start (not while running) the MCLK (from SPI/I2S) shifts by 180° / is inverted, in relation to the SAI/I2S clocks (SCLK (=SCK), LRCK (=WS)).

For regular audio stuff this is not a problem, but I have another slave on the I2S bus doing other things which needs a fixed phase relation between MCLK and LRCK / SCLK (previously controlled by an FPGA).

So how are theses clocks generated that this phase shift can happen, with the same clock input , and "going through" the same hardware each time?

What can I do to sync these clocks?

 

1 ACCEPTED SOLUTION

Accepted Solutions

waclawekjan_4-1725991090609.png

versus

waclawekjan_2-1725991055274.png

Note mclk_ena and bclk_ena which originate from the faster processor/AHB/APB clock (and are generated by the program writing the enable bits in the respective peripherals), which are faster and asynchronous to I2SCK. There may be a different delay between them in different runs, depending on the "there's too much other stuff still running". And voila, that results in different phase of mclk compared to bclk edge.

(In your case, bclk_cnt counts up to 128, but that's just a technicality, the point is the same).

JW

(bclk = bit-clock = SCLK/SCK)

 

View solution in original post

7 REPLIES 7

What is the MCLK divider, i.e. what is the I2SCKIN frequency?

If it's not 2*MCLK, I'd wonder, how comes, that the phase shift is only 180deg. I'd expect it to be all over the place. The only synchronization mechanism you have in place now is just expecting consistent execution timing between setting up/enabling the separate divider chains, isn't it. And given the incredibly complicated beasts 'H7 are, and the fact that you apparently run the I2S from a clock asynchronous to the processor clock, such synchronicity is far from being trivial to achieve.

You do disable all; interrupts during the I2S/SPI and SAI setup, don't you.

If yes, and you already run from some half-predictible code memory like ITCM, then IMO the only option is to generate the complete clocks mix using e.g. a timer, and feed that back into the SAIs being set up as slaves.

JW

PS. Yes, the fixed MCLK divider ratio is annoying.

LCE
Principal

Jan, thanks for your input!

I think it was you who gave me the idea using another peripheral for MCLK generation, thanks again, that saved me a lot of "hardware" trouble.

Anyway...

> What is the MCLK divider, i.e. what is the I2SCKIN frequency?
> If it's not 2*MCLK

Hehe, anything but /2^n would be terrible, so I stay away from that.
Divider is mostly none, and it's the same behavior if it's 2.

> You do disable all; interrupts during the I2S/SPI and SAI setup, don't you.

Yes and no, that might be it, I surely en- / disable all "at the same time" with SAI & I2S interrupts disabled, but there's too much other stuff still running. So I will disable all interrupts until all is running, let's see...

> I think it was you who gave me the idea using another peripheral for MCLK generation

I hereby DENY any responsibility!!!!

I had a look at the 'H72x RM and, unfortunately, I saw no internal path to engage timers to I2SCKIN, or sync SAI to SPI/I2S... There are paths from SAIx_FSx to some timer's ETR; sadly, the I2SCKIN is not fed to those timers, so they can't be used to generate the MCLK...

JW

 

One wild idea which may very well not work at all: what about setting up both SAI and the SPI/I2S, and only after that setting PC9 to AF in GPIO_MODER (i.e. until then, PC9 would be Analog, and there would be no I2SCKIN signal to be fed to the SAI/SPI/I2S kernels, so at least in theory, all modules should start up at once).

This will fail miserably if there's a need for the kernel clock to be present for the registers setup. But I'd try, maybe there's no such need.

JW

>> I think it was you who gave me the idea using another peripheral for MCLK generation

> I hereby DENY any responsibility!!!! 

Absolutely, still thankful!  

Thanks again for checking, I also didn't find anything.

I just wondered why this can happen anyway, because my guess was that the STM sets the corresponding "switches and paths", so that this is a pure hardware / divider routing which should behave in a "determinate" / reliable way.

Because there is no sampling of that I2SCKIN clock for sure, for that it looks too good.

I can't imagine it's a propagation problem, the path should be the same each time, and it's constantly inverted or not, and not shifted by some degrees in-between.

To find out what's going on, maybe @Peter BENSCH can "route" us to ST's chip designers or anybody else who can explain the signal path.

 

waclawekjan_4-1725991090609.png

versus

waclawekjan_2-1725991055274.png

Note mclk_ena and bclk_ena which originate from the faster processor/AHB/APB clock (and are generated by the program writing the enable bits in the respective peripherals), which are faster and asynchronous to I2SCK. There may be a different delay between them in different runs, depending on the "there's too much other stuff still running". And voila, that results in different phase of mclk compared to bclk edge.

(In your case, bclk_cnt counts up to 128, but that's just a technicality, the point is the same).

JW

(bclk = bit-clock = SCLK/SCK)

 

LCE
Principal

@waclawek.jan Thanks again!

I actually forgot that I always divide I2SCKIN by (at least) 2 for MCLK, so so that explains the phase shift.

Somehow I had in my mind that I2SCKIN= MCLK.