cancel
Showing results for 
Search instead for 
Did you mean: 

I2S and variable sampling rate

M0NKA
Senior
Posted on November 22, 2012 at 13:53

Hello,

I have fully working I2S with external codec (TLV320AIC23). I have decided to save a

crystal and feed the clock to the codec from the I2C pll. So according to the codec pdf this

clock needs to be constant (say 12.288 Mhz) and sampling rate is changed via SPI/I2C

command. Then the STM32 pdf says that the I2S output clock is based on the sampling

rate (256 * Fs). In practice changing the sampling rate when making init of the I2S will

change the divider values and correct clock will be available only at 48 kHz. With

8 kHz sampling rate the clock will drop as low as 2 Mhz.

Because i thought that would be good idea to have variable sampling rate for different

modes of operation i just did a quick hack by setting the dividers const at any rate to

output close to 12.288 Mhz. But then i guess the I2S hardware will not function correctly

- when i run my software implemented DDS process to output a sine wave (0-4000 Hz)

i need to setup sampling frequency of 48 kHz as input of the frequency formula while the

codec is running at 8 kHz.

So it seems i need to set I2S hardware to run at correct sampling rate and same time have

constant output clock to feed the codec. Is this mode of operation possible or i do the

whole thing in a wrong way. Any help to clear my confusion will be appreciated. Thanks

Regards, Chris
7 REPLIES 7
Posted on November 22, 2012 at 15:05

If I didn't need to use USB I'd definitely consider running the STM32 from the 12.288 MHz crystal, or one of the other magic values for audio.

The AIC23 had a USB as I recall, but I'm not sure that helps given the inflexibly poor divider strategy employed by ST.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on November 22, 2012 at 15:34

You don't mention which STM32 device you are using, but on STM32F4xx the output of I2S PLL can be directed to the MCO2 output (through its dedicated divider).

It would also help if you would pay more attention to describing your case. Replacing ''I2S'' randomly by ''I2C'' indicates you might not really want anybody to study the details of your problem.

JW

M0NKA
Senior
Posted on November 22, 2012 at 15:58

Hi,

Thanks for your responses.

clive1: At the moment i have the codec, LCD via software SPI (needs 9bit frames) and

PHY in RMII mode(i plan to supply it with 25 Mhz too). So no USB right now, but i think

i will try to add USB in near future.

waclawek.jan:

I am sorry, just a typing error, fixed now. My part is STM32F407 on STM32F4Discovery

board. Would redirecting the I2S PLL fix the variable rate based on sampling rate ? Or

just output to different pin ?

Some more explanation. The reason i need as less possible crystals/oscillators on the

final board is because my project is software defined radio. As it requires to be very

sensitive by design, it also picks up all the different clocks and this is a big problem.

One interesting side effect on the off the shelf Discovery board is the 2 chips with own,

8 Mhz crystal. As temperature changes both crystals move up and down, but with different

rate, the sum and difference create interesting 'beat tone' that can be heard on many

bands.

Back to the I2S - my main confusion is why the I2S output clock changes based on

sampling rate ? What part would need such changing clock - some ADC/DACs ?

Is it wrong to use this pin as master clock for a CODEC ?

BR
Posted on November 22, 2012 at 16:32

One interesting side effect on the off the shelf Discovery board is the 2 chips with own,

 

8 Mhz crystal. As temperature changes both crystals move up and down, but with different rate, the sum and difference create interesting 'beat tone' that can be heard on many bands.

 

Something you'll see pretty much with any pair of independent sources to a varying degree, thus having a single source and some DDS/NCO type frequency generators would have been so much more useful than binary divider chains.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on November 22, 2012 at 17:07

> I am sorry, just a typing error, fixed now.

Not completely... 😉

> Would redirecting the I2S PLL fix the variable

> rate based on sampling rate ?

I recommend thorough reading of the relevant chapters of manual(s) (including the RCC chapter) before asking further questions.

Also, above I did not say ''*re*direct''; I said ''direct''.

You can output the I2SPLL to MCO2 independently from the I2S module (and optionally divide it too). The same clock is then fed to the I2S module and divided by its divider as wished.

I don't know if this fits your requirements, as I still don't understand what do you intend to achieve.

JW

M0NKA
Senior
Posted on November 22, 2012 at 18:01

Hi,

The SPI/I2C part in the first post is about the control interface of the codec that is

independent of the I2S interface. In normal configuration the codec will run on

external crystal (eg 12.288 Mhz) and internally will divide it to achieve sampling

rate, which is in turn programmed via the control interface.

So i assume the variable I2S rate on the STM32 chip is to accommodate ADC/DACs that

don't have such internal logic.

Thanks for the suggestion, i will read further and experiment.

BR

M0NKA
Senior
Posted on November 22, 2012 at 22:32

Hi JW,

That actually did the trick. Thanks! Now the output clock is constant and not dependent

on the I2S sampling rate, also the I2S hardware functions correctly as expected for

other than 48 kHz selected rate.

I have tested my SoftDDS routine - it can output correct audio signal at any sample rate.

Also the constant firing rate of the I2S DMA interrupt is now different, based on the

selected sample rate.

So for future reference, my settings:

HSE clock = 25 Mhz

PLL_M = 25

PLLI2S_N = 258

PLLI2S_R = 7

I2SCLK = 36.8571 Mhz (ideal: 36.864 Mhz)

Error = 0.0186

MCO2 divider = 3

and init code:

...

I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;

...

// Configure MCO2 (PC9)

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

// Output I2S PLL via MCO2 pin - 12.288 Mhz

RCC_MCO2Config(RCC_MCO2Source_PLLI2SCLK, RCC_MCO2Div_3);

Regards, Chris