Skip to main content
JKahn.1
Associate III
April 29, 2026
Question

STM32u585 RNG working without enabling HSI48. How?

  • April 29, 2026
  • 1 reply
  • 125 views

I am using an stm32u585, specifically the b-u585i-iot02a development kit board.
I set up a basic project using stm32cube ide to test clock configurations. System is clocked from the MSIS at 24MHz with PSC of 1 -> HCLK is 24MHz.
I enabled the RNG peripheral, clocked with the HSI48. In the default SystemClock_Config() function I commented out the code related to enabling the HSI48. RNG initialization is left as default.
Interestingly, the RNG can still generate random numbers with HAL_RNG_GenerateRandomNumber(). The MX_RNG_Init() function succeeds as well.

Reading HSI48ON and HSI48RDY bits from the status registers give both values as 0.

How is the RNG still working and generating valid numbers?

Another curiosity: In this state, the whole MCU takes less power than if I leave the SystemClock_Config() as generated (explicitly enabling the HSI48).

 

See code snippets below:

 

System clock config

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Configure the main internal regulator output voltage
 */
 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE3) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
// RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_MSI;
// RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_1;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
 |RCC_CLOCKTYPE_PCLK3;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
 {
 Error_Handler();
 }
}

RNG init

/**
 * @brief RNG Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_RNG_Init(void)
{

 /* USER CODE BEGIN RNG_Init 0 */

 /* USER CODE END RNG_Init 0 */

 /* USER CODE BEGIN RNG_Init 1 */

 /* USER CODE END RNG_Init 1 */
 hrng.Instance = RNG;
 hrng.Init.ClockErrorDetection = RNG_CED_ENABLE;
 if (HAL_RNG_Init(&hrng) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN RNG_Init 2 */

 /* USER CODE END RNG_Init 2 */

}

 

Checking status

	 volatile uint32_t rng_src=__HAL_RCC_GET_RNG_SOURCE(); // 0 => HSI48
	 volatile uint32_t hsi48_on = (READ_BIT(RCC->CR, RCC_CR_HSI48ON) != 0U);
	 volatile uint32_t hsi48_rdy= __HAL_RCC_GET_FLAG(RCC_FLAG_HSI48RDY);
	 volatile uint32_t drdy = __HAL_RNG_GET_FLAG(&hrng, RNG_FLAG_DRDY);
	 volatile uint32_t sr = RNG->SR; // check CECS/SECS bits
	 random32 = 0;
	 HAL_StatusTypeDef st = HAL_RNG_GenerateRandomNumber(&hrng, &random32);
	 volatile uint32_t err = HAL_RNG_GetError(&hrng);

	 if(st != HAL_OK)
	 {
		 __NOP();
	 }

 

clock configuration:

Screenshot 2026-04-29 093224.png

1 reply

Shirley.Ye
ST Employee
May 3, 2026

you can check the RNGSEL field in the RCC peripheral clock selection register, whether it is select the HSI48