AnsweredAssumed Answered

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

Question asked by Burton.Mark on Oct 15, 2015
Latest reply on Oct 15, 2015 by Burton.Mark

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);

Outcomes