cancel
Showing results for 
Search instead for 
Did you mean: 

permanent I2S MCK output

tilolutz
Associate II
Posted on May 28, 2012 at 10:30

Hi

I want to connect a PCM3168a audio codec to a STM32F407VG (Discovery board).

The problem is the Codec is only alive when MCK is provided. Without MCK the control interface (i2c) is dead.

Is use SPI3 in I2S mode for communication. Regarding documentation MCK is only active when a transfer is in progress. Does that mean the PLLI2S clock is only active when a transfer is in progress?

My idea is to use MCO2 to provide the clock output of PLLI2S instead of using the MCK feature of the I2S to provide the clock for the coded.

Will this work?

#stm32f4-i2s
14 REPLIES 14
Posted on May 28, 2012 at 13:39

I'd be surprised if it turns the PLL off, otherwise you'd be spending all your time waiting for it to lock again. Realistically the PLL clock is simply gated into the peripheral.

You should be able to get a signal out of MCO, but the phase might not be what you need, you could presumably measure that with a scope.

Alternatively you might be able to sustain the clock by keeping the interface alive with a circular DMA buffer.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
tilolutz
Associate II
Posted on May 28, 2012 at 21:03

A circular DMA was my first idea but I would prefer using the MCO because this solution will cost less resources.

The manual of the codec tells phase between MCK and CK is not important. Only the ratio must fit. I think I will just give it a try.

tilolutz
Associate II
Posted on May 28, 2012 at 22:26

Unfortunatly it is not working.

I have configured PC9:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOC, &GPIO_InitStructure);

/* Don't connect pin to I2S peripheral. Pin will be connected to MCO2 */

GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_MCOF);

/* Enable MCLK output via MCO2 */

RCC_MCO2Config(RCC_MCO2Source_PLLI2SCLK, RCC_MCO2Div_1);

/* Enable the CODEC_I2S peripheral clock */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);

/* CODEC_I2S peripheral configuration. Don't enable MCLK output because output is using MCO2 */

SPI_I2S_DeInit(SPI3);

I2S_InitStructure.I2S_AudioFreq = AudioFreq;

I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;

I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_24b;

I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;

I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;

I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;

/* Initialize the I2S peripheral with the structure above */

I2S_Init(SPI3, &I2S_InitStructure);

I2S_FullDuplexConfig(I2S3ext, &I2S_InitStructure);

/* Enable I2S PLL clock */

RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);

RCC_PLLI2SCmd(ENABLE);

RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY);   /* Enable I2S peripheral */

I2S_Cmd(PSPI3, ENABLE);

I2S_Cmd(SPI3, ENABLE);

Samplerate is 48kHz. This should result in a PLL I2S clock af around 12MHz. I measure the signal on PC9 with an old analog oscilloscope. With RCC_MCO2Config signal is changing from 1,5V to 0V. After RCC_PLLI2SCmd I get the clock signal with 500mVpp signal and 1,5V DC offset.

Same setup with RCC_MCO2Source_HSE instead of RCC_MCO2Source_PLLI2SCLK results in a correct clock output with no DC and 3Vpp after RCC_MCO2Config().

Any ideas what might be wrong?

tilolutz
Associate II
Posted on May 29, 2012 at 18:52

Update:

When I set the divider at least to RCC_MCO2Div_2 amplitude is OK. So PLLI2S should be configured correct.

Hm, any ideas?

Posted on May 29, 2012 at 20:48

So how exactly is PLLI2S generating ~12 MHz (288 MHz?), what settings are you using for the PLL. Reading the specs suggests a operational range of 429 to 192 MHz, although this could be divided somewhat via the MCO pin driver.

Are you using a magic crystal value (ie not 8 or 25 MHz, like 6.144 MHz) ? I have it swinging rail-to-rail (w/overshoot) at 4 MHz on a Discovery board

// STM32F4 Discovery - MCO2 - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
/**************************************************************************************/
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_MCO);
RCC_PLLI2SCmd(DISABLE);
RCC_PLLI2SConfig(192, 5); // .432, 2..7, ie range of 429 Mhz to 192 MHz
RCC_MCO2Config(RCC_MCO2Source_PLLI2SCLK, RCC_MCO2Div_1); // 4 MHz with defaults
RCC_PLLI2SCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY) == RESET);
while(1); // Don't want to exit
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
tilolutz
Associate II
Posted on May 31, 2012 at 20:15

Hi

You're right. I have understand the PLL wrong. I thought the PLL frequency is the frequency which is used as clock in I2S. I haven't recognized the divider after the PLL.

Now it seems to work, thank you.
hualing_yu
Associate II
Posted on November 06, 2013 at 15:20

s

Posted on November 06, 2013 at 15:43

You have a question?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hualing_yu
Associate II
Posted on November 06, 2013 at 15:58

Hi,

First I wonder now after more than a year if we have found a new way to use stm32f4 discovery board i2s mclk as the constant clk input to an audio module, even without i2s traffic. Any one has an idea? I am having almost exactly the same problem as described here. As I cannot get i2s mclk output for i2c interface to configure the audio board, I am thinking of using MCO2 sourced from plli2sclk. I kept all my code that configure i2s and i2s ext, except changed

 to use 192/5 for N/R parameters when call
RCC_PLLI2SConfig(192, 5);

just to try out, and copied Clive's this code to setup MCO2. As expected, I got an 4 MHz i2sclk which I found by stepping into code I2S_Init() where i2sclk is used to calculate DIV and ODD for wanted Fs. However, the output on PC9 is at around 10 MHz as shown in my logic analyzer and is not even at all (8Mhz - 12 Mhz). Since the code use RCC_MCO2Div_1, the MCO2 should be straight from i2sclk and get 4 mhz. What else can screw up here? What does ''this could be divided somewhat via the MCO pin driver.'' in Clive's message mean? Thanks! Clive, saw your response, thanks. I was having trouble post my message... Hope you can help. Thanks.