1 /* USER CODE BEGIN Header */ 2 /** 3 ****************************************************************************** 4 * @file hw_rng.c 5 * @author GPM WBL Application Team 6 * @brief This file provides functions implementation for RNG Manager. 7 ****************************************************************************** 8 * @attention 9 * 10 * Copyright (c) 2024 STMicroelectronics. 11 * All rights reserved. 12 * 13 * This software is licensed under terms that can be found in the LICENSE file 14 * in the root directory of this software component. 15 * If no LICENSE file comes with this software, it is provided AS-IS. 16 * 17 ****************************************************************************** 18 */ 19 /* USER CODE END Header */ 20 21 /* Includes ------------------------------------------------------------------*/ 22 #include "hw_rng.h" 23 #include "stm32wb0x_ll_rng.h" 24 #include "stm32wb0x_ll_bus.h" 25 26 /** @defgroup RNG_Manager RNG Manager 27 * @{ 28 */ 29 30 /** @defgroup RNG_Manager_TypesDefinitions Private Type Definitions 31 * @{ 32 */ 33 /** 34 * @} 35 */ 36 37 /** @defgroup RNG_Manager_Private_Defines Private Defines 38 * @{ 39 */ 40 /** 41 * @} 42 */ 43 44 /** @defgroup RNG_Manager_Private_Variables Private Variables 45 * @{ 46 */ 47 /** 48 * @} 49 */ 50 51 /** @defgroup RNG_Manager_External_Variables External Variables 52 * @{ 53 */ 54 /** 55 * @} 56 */ 57 58 /** @defgroup RNG_Manager_Public_Functions Public Functions 59 * @{ 60 */ 61 HW_RNG_Init(void)62HW_RNG_ResultStatus HW_RNG_Init(void) 63 { 64 #ifdef STM32WB09 65 /* Peripheral clock enable */ 66 LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_RNG); 67 68 uint32_t SamplingClockDivider = 0; 69 70 /* Check that the divider value is equal to the one to configure. If not, it must redo the write and checking. */ 71 while( LL_RNG_GetSamplingClockEnableDivider(RNG) != SamplingClockDivider) 72 { 73 /* While the new divider value is being resynchronized with the TRNG core clock domain, it is not possible to write another new value. */ 74 LL_RNG_SetSamplingClockEnableDivider(RNG, SamplingClockDivider); 75 } 76 77 /* Initialize random numbers generation */ 78 LL_RNG_Enable(RNG); 79 80 /* Wait for RNG enable operation */ 81 while (LL_RNG_IsActiveFlag_DISABLED(RNG)); 82 83 /* Check if internal clock error occurs */ 84 if (LL_RNG_IsActiveFlag_REVEAL_CLK_ERR(RNG)) 85 { 86 return HW_RNG_ERROR; 87 } 88 #endif /* STM32WB09 */ 89 90 #if defined (STM32WB07) || defined (STM32WB06) || defined(STM32WB05) 91 /* Peripheral clock enable */ 92 LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_RNG); 93 94 /* Initialize random numbers generation */ 95 LL_RNG_Enable(RNG); 96 97 /* Wait for DRDY flag to be raised */ 98 while (!LL_RNG_IsActiveFlag_RNGRDY(RNG)); 99 100 /* Check if error occurs */ 101 if ( LL_RNG_IsActiveFlag_FAULT(RNG) ) 102 { 103 /* Clock or Seed Error detected. Set LED to blinking mode (Error type)*/ 104 return HW_RNG_ERROR; 105 } 106 107 /* Values of Generated Random numbers are now available in num array. */ 108 109 #endif /* STM32WB07 || STM32WB06 || STM32WB05*/ 110 return HW_RNG_SUCCESS; 111 } 112 HW_RNG_Deinit(void)113HW_RNG_ResultStatus HW_RNG_Deinit(void) 114 { 115 /* Stop random numbers generation */ 116 LL_RNG_Disable(RNG); 117 return HW_RNG_SUCCESS; 118 } 119 120 /** 121 * @brief Provide a 16-bit true random number 122 * @param num: pointer to the random value returned 123 * @return error status: 0 = No error 124 */ HW_RNG_GetRandom16(uint16_t * num)125HW_RNG_ResultStatus HW_RNG_GetRandom16(uint16_t* num) 126 { 127 #ifdef STM32WB09 128 /* Wait for VAL_READY signal */ 129 while (!LL_RNG_IsActiveFlag_VAL_READY(RNG)); 130 131 *num = LL_RNG_READRANDDATA32(RNG); 132 133 #endif /* STM32WB09 */ 134 135 #if defined (STM32WB07) || defined (STM32WB06) || defined(STM32WB05) 136 /* Wait for RNGRDY signal */ 137 while (!LL_RNG_IsActiveFlag_RNGRDY(RNG)); 138 139 *num = (uint16_t)LL_RNG_ReadRandData16(RNG); 140 141 #endif /* STM32WB07 || STM32WB06 || STM32WB05*/ 142 143 return HW_RNG_SUCCESS; 144 } 145 146 /** 147 * @brief Provide a 32-bit true random number 148 * @param num: pointer to the random value returned 149 * 150 * @return error status: 0 = No error 151 */ HW_RNG_GetRandom32(uint32_t * num)152HW_RNG_ResultStatus HW_RNG_GetRandom32(uint32_t* num) 153 { 154 #ifdef STM32WB09 155 /* Wait for VAL_READY signal */ 156 while (!LL_RNG_IsActiveFlag_VAL_READY(RNG)); 157 158 *num = LL_RNG_READRANDDATA32(RNG); 159 #endif /* STM32WB09 */ 160 161 #if defined (STM32WB07) || defined (STM32WB06) || defined(STM32WB05) 162 uint16_t *num_16 = (uint16_t *) num; 163 164 /* Wait for RNGRDY signal */ 165 while (!LL_RNG_IsActiveFlag_RNGRDY(RNG)); 166 167 num_16[0] = (uint16_t)LL_RNG_ReadRandData16(RNG); 168 169 /* Wait for RNGRDY signal */ 170 while (!LL_RNG_IsActiveFlag_RNGRDY(RNG)); 171 172 num_16[1] = (uint16_t)LL_RNG_ReadRandData16(RNG); 173 #endif /* STM32WB07 || STM32WB06 || STM32WB05*/ 174 175 return HW_RNG_SUCCESS; 176 } 177 178 /** 179 * @} 180 */ 181 182 /** 183 * @} 184 */ 185