cancel
Showing results for 
Search instead for 
Did you mean: 

Suggestion - don't initialise all clocks with one call to HAL_RCC_OscConfig()

markb
Associate II
Posted on October 15, 2015 at 17:00

I've just wasted an STM32405 chip + a day of my time trying to work out why the USB FS CDC device wasn't working on a new (partially populated) board that I was testing.

Why wasn't the USB working? Well, the board also uses the 32KHz LSE to drive the RTC and I hadn't got around to attaching the 32KHz crystal. Yes, you've guessed it, the cube generated code to initialise the clocks fails to initialise the PLL if the LSE clock isn't working because HAL_RCC_OscConfig() returns early.

The cube generated code looks like this:

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE

                              |RCC_OSCILLATORTYPE_LSE;

  RCC_OscInitStruct.HSEState = RCC_HSE_ON;

  RCC_OscInitStruct.LSEState = RCC_LSE_ON;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

  RCC_OscInitStruct.PLL.PLLM = 8;

  RCC_OscInitStruct.PLL.PLLN = 336;

  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

  RCC_OscInitStruct.PLL.PLLQ = 7;

  HAL_RCC_OscConfig(&RCC_OscInitStruct);

It doesn't have to be like that because HAL_RCC_OscConfig() can be called separately for each of the clocks (and PLL) that is to be initialised and so if, say, the LSE clock isn't working, it wouldn't affect the initialisation of the other clocks/PLL.

So to avoid future problems it would be better to make the above code more like this (untested) suggestion:

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

  RCC_OscInitStruct.HSEState = RCC_HSE_ON;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

  RCC_OscInitStruct.PLL.PLLM = 8;

  RCC_OscInitStruct.PLL.PLLN = 336;

  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

  RCC_OscInitStruct.PLL.PLLQ = 7;

  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;

  RCC_OscInitStruct.HSEState = RCC_LSE_ON;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

  HAL_RCC_OscConfig(&RCC_OscInitStruct);

3 REPLIES 3
Posted on October 15, 2015 at 19:30

The latter should specify LSE

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured!

RCC_OscInitStruct.LSEState = RCC_LSE_ON; // External 768 kHz clock on OSC_IN/OSC_OUT

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {

error(''RTC error: LSE clock initialization failed.'');

}

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

Having battled with the PLLs before, the fail through behaviour on the SPL can also give headaches, I've added code to use the HSI/PLL when the HSE/PLL don't start. The thing to watch is that the SDIO/CRYPT/HASH/USB are dependent on the Q Tap of the PLL, if the PLL isn't running, because the HSE didn't start, none of these work as expected.

Having the board, or test suite, test the external oscillators and flag failures can be helpful in manufacturing, oscillators are prone to tomb-stone, or get knocked
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
markb
Associate II
Posted on October 15, 2015 at 19:55

Hi clive1,

Thanks for spotting that mistake, cut and paste strikes again!

Cheers,

Mark