cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F446: configure PLLSAI for 48MHz (USB) clock

mluessi
Associate II
Posted on September 14, 2015 at 18:40

I'm working on a new board that uses the STM32F446 running at 180MHz. The board uses an external 16MHz oszillator and I would like to use ''PLLSAIP'' for the 48MHz USB clock. The clock configuration from STM32CubeMX can be seen below:

0690X000006034UQAQ.jpg

To configure the clock, I modified the ''system_stm32f4xx.c'' file from the STM32 standard peripheral library. I.e., I added the following to the end of ''SetSysClock()'':

#if defined(STM32F446xx)

/* Configure 48MHz clock for USB */

RCC_PLLSAICmd(DISABLE);

RCC_PLLSAIConfig(PLLSAI_M, PLLSAI_N, PLLSAI_P, PLLSAI_Q);

RCC_48MHzClockSourceConfig(RCC_48MHZCLKSource_PLLSAI);

while (!(RCC->DCKCFGR & RCC_DCKCFGR_CK48MSEL))

{}

RCC_PLLSAICmd(ENABLE);

#endif /* STM32F446xx */where:

#define PLLSAI_M 8

#define PLLSAI_N 192

#define PLLSAI_P 8

#define PLLSAI_Q 2

The parameters for the main PLL are as follows:

#define PLL_M 8

#define PLL_N 180

#define PLL_P 2

#define PLL_Q 2

#define PLL_R 2

The entire file can be found

http://pastebin.com/0DB6u23L

. The Code runs on the target, but it doesn't get detected by USB when connected to a computer. I'm fairly sure that it is not a hardware problem, as I can communicate with the STM bootloader over USB. Also, I suspect the problem is with the clock initialization as the code is otherwise identical to code I'm using successfully with an STM32F405. Last, note that while the STM32CubeMx software can generate code to initialize the 48MHz clock on the STM32F446, I would not like to use it as it uses the HAL which I don't need for anything else.

Does anyone have an idea what could be wrong with the code above?

3 REPLIES 3
Posted on September 14, 2015 at 20:57

I would start by muxing the internal clocks out via one of the MCO pins and confirm everything was functioning at the rates I expected.

If your external source is not actually a crystal, but a can oscillator (TCXO, etc), check if you need the HSE BYPASS mode enabled.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mluessi
Associate II
Posted on September 15, 2015 at 19:29

Thanks, I was able to use MCO1 to verify that the main PLL is running at 180MHz. One other thing I tried is running the PLL at 168MHz and using the PLL as the 48MHz clock source. Unfortunately, this doesn't work either on the STM32F446, while the same code compiled for the STM32F405 works as expected. To be able to use either 168MHz and 180MHz I added the following:

#if SYSCLK_FREQ == 180000000

#if defined(STM32F40_41xxx)

#error 180MHz is not supported!

#endif

#define PLL_M 8

#define PLL_N 180

#define PLL_P 2

#define PLL_Q 2

#define PLL_R 2

#define PLLSAI_M 8

#define PLLSAI_N 192

#define PLLSAI_P 8

#define PLLSAI_Q 2

#elif SYSCLK_FREQ == 168000000

#define PLL_M 16

#define PLL_N 336

#define PLL_P 2

#define PLL_Q 7

#define PLL_R 7

#else

#error Invalid SYSCLK_FREQ

#endif

And the 48MHz clock configuration code is:

#if defined(STM32F446xx)

#define RCC_PLLSAI_GET_FLAG()((RCC->CR & (RCC_CR_PLLSAIRDY))==(RCC_CR_PLLSAIRDY))

#if SYSCLK_FREQ == 180000000

/* Configure 48MHz clock for USB */

// Set 48MHz clock source

RCC_48MHzClockSourceConfig(RCC_48MHZCLKSource_PLLSAI);

// Enable PLLSAI

RCC_PLLSAICmd(DISABLE);

// wait for PLLSAI to be disabled

while (RCC_PLLSAI_GET_FLAG() != 0)

{}

RCC_PLLSAIConfig(PLLSAI_M, PLLSAI_N, PLLSAI_P, PLLSAI_Q);

RCC_PLLSAICmd(ENABLE);

// wait for PLLSAI to be enabled

while (RCC_PLLSAI_GET_FLAG() == 0)

{}

#else

RCC_48MHzClockSourceConfig(RCC_48MHZCLKSource_PLL);

#endif /* SYSCLK_FREQ == 180000000 */

#endif /* STM32F446xx */

One thing I found is that there is a bug in the STM32 standard peripheral library. I.e., in 

RCC_48MHzClockSourceConfig()

the register

RCC

->

DCKCFGR

is being modified instead of

RCC

->

DCKCFGR2. However, even when this is fixed, USB still doesn't work at both 168MHz and 180MHz.Are there any other differences between the USB peripherals in the STM32F446 and STM32F405 that could be causing this problem?

mluessi
Associate II
Posted on September 16, 2015 at 00:39

My application uses the STM32_USB_Device_Library and the STM32_USB_OTG_Driver V 2.1.0 could it be that they are not compatible with the STM32F446?