cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeMX clock HSI and automatic code generation - why is HSI explicitly initialized?

AAnth.1
Senior

Hi

I just tried to setup my STM32F407 using STM32CubeMX and chose the internal high speed oscillator (HSI), which is a 16MHz RC oscillator.

By inspecting the generated code, I can see that the function SystemClock_Config() is called and basically initializes the Sysclk to be driven by HSI.

Isn't that kind of redundant since the HSI is the default clock source after reset? Or is it just the way it is to use a generic HAL function provided by ST?

I'm not complaining about it, I'm just a bit confused as I am fairly new to MCU programming and understand the datasheet/reference manual that the HSI does not explicitly need to be configured.

I do understand prescaler, peripheral buses etc. need to be initialized, I am solely talking about the HSI initialization.

Hope someone can enlighten me. Thank you,

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage 
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 10;
  RCC_OscInitStruct.PLL.PLLN = 180;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 6;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
  PeriphClkInitStruct.PLLI2S.PLLI2SN = 70;
  PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
}

3 REPLIES 3

That function is probably intended to be used universally, i.e. not only at startup, so it then might be called also later in contexts where other than HSI is the primary source and HSI is disabled.

JW

Hi waclawek.jan,

Thank you for your quick reply. Initially, I thought the same, and it would kind of make sense. But the function SystemClock_Config does not take any arguments. So when calling that function wherever in the program, that function always creates a struct out of the struct template, where the struct members will always be the same as defined within the function. So I do not really see any way to use this function universally in different points in the program.

Or am I misunderstanding anything here?

TDK
Guru

It's also possible to jump to the reset handler under clock conditions which are not the default HSI. By explicitly setting it, you avoid issues or misconceptions in this scenario.

If you feel a post has answered your question, please click "Accept as Solution".