STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_rng.c 00004 * @author MCD Application Team 00005 * @brief RNG HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Random Number Generator (RNG) peripheral: 00008 * + Initialization and configuration functions 00009 * + Peripheral Control functions 00010 * + Peripheral State functions 00011 * 00012 ****************************************************************************** 00013 * @attention 00014 * 00015 * Copyright (c) 2017 STMicroelectronics. 00016 * All rights reserved. 00017 * 00018 * This software is licensed under terms that can be found in the LICENSE file 00019 * in the root directory of this software component. 00020 * If no LICENSE file comes with this software, it is provided AS-IS. 00021 * 00022 ****************************************************************************** 00023 @verbatim 00024 ============================================================================== 00025 ##### How to use this driver ##### 00026 ============================================================================== 00027 [..] 00028 The RNG HAL driver can be used as follows: 00029 00030 (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro 00031 in HAL_RNG_MspInit(). 00032 (#) Activate the RNG peripheral using HAL_RNG_Init() function. 00033 (#) Wait until the 32 bit Random Number Generator contains a valid 00034 random data using (polling/interrupt) mode. 00035 (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function. 00036 00037 ##### Callback registration ##### 00038 ================================== 00039 00040 [..] 00041 The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1 00042 allows the user to configure dynamically the driver callbacks. 00043 00044 [..] 00045 Use Function HAL_RNG_RegisterCallback() to register a user callback. 00046 Function HAL_RNG_RegisterCallback() allows to register following callbacks: 00047 (+) ErrorCallback : RNG Error Callback. 00048 (+) MspInitCallback : RNG MspInit. 00049 (+) MspDeInitCallback : RNG MspDeInit. 00050 This function takes as parameters the HAL peripheral handle, the Callback ID 00051 and a pointer to the user callback function. 00052 00053 [..] 00054 Use function HAL_RNG_UnRegisterCallback() to reset a callback to the default 00055 weak (surcharged) function. 00056 HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle, 00057 and the Callback ID. 00058 This function allows to reset following callbacks: 00059 (+) ErrorCallback : RNG Error Callback. 00060 (+) MspInitCallback : RNG MspInit. 00061 (+) MspDeInitCallback : RNG MspDeInit. 00062 00063 [..] 00064 For specific callback ReadyDataCallback, use dedicated register callbacks: 00065 respectively HAL_RNG_RegisterReadyDataCallback() , HAL_RNG_UnRegisterReadyDataCallback(). 00066 00067 [..] 00068 By default, after the HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET 00069 all callbacks are set to the corresponding weak (surcharged) functions: 00070 example HAL_RNG_ErrorCallback(). 00071 Exception done for MspInit and MspDeInit functions that are respectively 00072 reset to the legacy weak (surcharged) functions in the HAL_RNG_Init() 00073 and HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand). 00074 If not, MspInit or MspDeInit are not null, the HAL_RNG_Init() and HAL_RNG_DeInit() 00075 keep and use the user MspInit/MspDeInit callbacks (registered beforehand). 00076 00077 [..] 00078 Callbacks can be registered/unregistered in HAL_RNG_STATE_READY state only. 00079 Exception done MspInit/MspDeInit that can be registered/unregistered 00080 in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user) 00081 MspInit/DeInit callbacks can be used during the Init/DeInit. 00082 In that case first register the MspInit/MspDeInit user callbacks 00083 using HAL_RNG_RegisterCallback() before calling HAL_RNG_DeInit() 00084 or HAL_RNG_Init() function. 00085 00086 [..] 00087 When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or 00088 not defined, the callback registration feature is not available 00089 and weak (surcharged) callbacks are used. 00090 00091 @endverbatim 00092 ****************************************************************************** 00093 */ 00094 00095 /* Includes ------------------------------------------------------------------*/ 00096 #include "stm32h7xx_hal.h" 00097 00098 /** @addtogroup STM32H7xx_HAL_Driver 00099 * @{ 00100 */ 00101 00102 #if defined (RNG) 00103 00104 /** @addtogroup RNG 00105 * @brief RNG HAL module driver. 00106 * @{ 00107 */ 00108 00109 #ifdef HAL_RNG_MODULE_ENABLED 00110 00111 /* Private types -------------------------------------------------------------*/ 00112 /* Private defines -----------------------------------------------------------*/ 00113 /** @defgroup RNG_Private_Defines RNG Private Defines 00114 * @{ 00115 */ 00116 /* Health test control register information to use in CCM algorithm */ 00117 #define RNG_HTCFG_1 0x17590ABCU /*!< Magic number */ 00118 #if defined(RNG_VER_3_1) || defined(RNG_VER_3_0) 00119 #define RNG_HTCFG 0x000CAA74U /*!< For best latency and to be compliant with NIST */ 00120 #else /* RNG_VER_3_2 */ 00121 #define RNG_HTCFG 0x00007274U /*!< For best latency and to be compliant with NIST */ 00122 #endif /* RNG_VER_3_1 || RNG_VER_3_0 */ 00123 /** 00124 * @} 00125 */ 00126 /* Private variables ---------------------------------------------------------*/ 00127 /* Private constants ---------------------------------------------------------*/ 00128 /** @defgroup RNG_Private_Constants RNG Private Constants 00129 * @{ 00130 */ 00131 #define RNG_TIMEOUT_VALUE 2U 00132 /** 00133 * @} 00134 */ 00135 /* Private macros ------------------------------------------------------------*/ 00136 /* Private functions prototypes ----------------------------------------------*/ 00137 /* Exported functions --------------------------------------------------------*/ 00138 00139 /** @addtogroup RNG_Exported_Functions 00140 * @{ 00141 */ 00142 00143 /** @addtogroup RNG_Exported_Functions_Group1 00144 * @brief Initialization and configuration functions 00145 * 00146 @verbatim 00147 =============================================================================== 00148 ##### Initialization and configuration functions ##### 00149 =============================================================================== 00150 [..] This section provides functions allowing to: 00151 (+) Initialize the RNG according to the specified parameters 00152 in the RNG_InitTypeDef and create the associated handle 00153 (+) DeInitialize the RNG peripheral 00154 (+) Initialize the RNG MSP 00155 (+) DeInitialize RNG MSP 00156 00157 @endverbatim 00158 * @{ 00159 */ 00160 00161 /** 00162 * @brief Initializes the RNG peripheral and creates the associated handle. 00163 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00164 * the configuration information for RNG. 00165 * @retval HAL status 00166 */ 00167 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng) 00168 { 00169 uint32_t tickstart; 00170 /* Check the RNG handle allocation */ 00171 if (hrng == NULL) 00172 { 00173 return HAL_ERROR; 00174 } 00175 /* Check the parameters */ 00176 assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance)); 00177 assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection)); 00178 00179 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) 00180 if (hrng->State == HAL_RNG_STATE_RESET) 00181 { 00182 /* Allocate lock resource and initialize it */ 00183 hrng->Lock = HAL_UNLOCKED; 00184 00185 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */ 00186 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */ 00187 00188 if (hrng->MspInitCallback == NULL) 00189 { 00190 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */ 00191 } 00192 00193 /* Init the low level hardware */ 00194 hrng->MspInitCallback(hrng); 00195 } 00196 #else 00197 if (hrng->State == HAL_RNG_STATE_RESET) 00198 { 00199 /* Allocate lock resource and initialize it */ 00200 hrng->Lock = HAL_UNLOCKED; 00201 00202 /* Init the low level hardware */ 00203 HAL_RNG_MspInit(hrng); 00204 } 00205 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ 00206 00207 /* Change RNG peripheral state */ 00208 hrng->State = HAL_RNG_STATE_BUSY; 00209 00210 #if defined(RNG_CR_CONDRST) 00211 /* Disable RNG */ 00212 __HAL_RNG_DISABLE(hrng); 00213 00214 /* Clock Error Detection Configuration when CONDRT bit is set to 1 */ 00215 MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, hrng->Init.ClockErrorDetection | RNG_CR_CONDRST); 00216 00217 #if defined(RNG_VER_3_2) || defined(RNG_VER_3_1) || defined(RNG_VER_3_0) 00218 /*!< magic number must be written immediately before to RNG_HTCRG */ 00219 WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG_1); 00220 /* for best latency and to be compliant with NIST */ 00221 WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG); 00222 #endif /* RNG_VER_3_2 || RNG_VER_3_1 || RNG_VER_3_0 */ 00223 00224 /* Writing bit CONDRST=0 */ 00225 CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST); 00226 00227 /* Get tick */ 00228 tickstart = HAL_GetTick(); 00229 00230 /* Wait for conditioning reset process to be completed */ 00231 while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) 00232 { 00233 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) 00234 { 00235 /* New check to avoid false timeout detection in case of preemption */ 00236 if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) 00237 { 00238 hrng->State = HAL_RNG_STATE_READY; 00239 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; 00240 return HAL_ERROR; 00241 } 00242 } 00243 } 00244 #else 00245 /* Clock Error Detection Configuration */ 00246 MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection); 00247 #endif /* RNG_CR_CONDRST */ 00248 00249 /* Enable the RNG Peripheral */ 00250 __HAL_RNG_ENABLE(hrng); 00251 00252 /* verify that no seed error */ 00253 if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) 00254 { 00255 hrng->State = HAL_RNG_STATE_ERROR; 00256 return HAL_ERROR; 00257 } 00258 /* Get tick */ 00259 tickstart = HAL_GetTick(); 00260 /* Check if data register contains valid random data */ 00261 while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET) 00262 { 00263 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) 00264 { 00265 /* New check to avoid false timeout detection in case of preemption */ 00266 if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET) 00267 { 00268 hrng->State = HAL_RNG_STATE_ERROR; 00269 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; 00270 return HAL_ERROR; 00271 } 00272 } 00273 } 00274 00275 /* Initialize the RNG state */ 00276 hrng->State = HAL_RNG_STATE_READY; 00277 00278 /* Initialise the error code */ 00279 hrng->ErrorCode = HAL_RNG_ERROR_NONE; 00280 00281 /* Return function status */ 00282 return HAL_OK; 00283 } 00284 00285 /** 00286 * @brief DeInitializes the RNG peripheral. 00287 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00288 * the configuration information for RNG. 00289 * @retval HAL status 00290 */ 00291 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng) 00292 { 00293 #if defined(RNG_CR_CONDRST) 00294 uint32_t tickstart; 00295 00296 #endif /* RNG_CR_CONDRST */ 00297 /* Check the RNG handle allocation */ 00298 if (hrng == NULL) 00299 { 00300 return HAL_ERROR; 00301 } 00302 00303 #if defined(RNG_CR_CONDRST) 00304 /* Clear Clock Error Detection bit when CONDRT bit is set to 1 */ 00305 MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST); 00306 00307 /* Writing bit CONDRST=0 */ 00308 CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST); 00309 00310 /* Get tick */ 00311 tickstart = HAL_GetTick(); 00312 00313 /* Wait for conditioning reset process to be completed */ 00314 while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) 00315 { 00316 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) 00317 { 00318 /* New check to avoid false timeout detection in case of preemption */ 00319 if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)) 00320 { 00321 hrng->State = HAL_RNG_STATE_READY; 00322 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; 00323 /* Process Unlocked */ 00324 __HAL_UNLOCK(hrng); 00325 return HAL_ERROR; 00326 } 00327 } 00328 } 00329 00330 #else 00331 /* Clear Clock Error Detection bit */ 00332 CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED); 00333 #endif /* RNG_CR_CONDRST */ 00334 /* Disable the RNG Peripheral */ 00335 CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN); 00336 00337 /* Clear RNG interrupt status flags */ 00338 CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS); 00339 00340 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) 00341 if (hrng->MspDeInitCallback == NULL) 00342 { 00343 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */ 00344 } 00345 00346 /* DeInit the low level hardware */ 00347 hrng->MspDeInitCallback(hrng); 00348 #else 00349 /* DeInit the low level hardware */ 00350 HAL_RNG_MspDeInit(hrng); 00351 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ 00352 00353 /* Update the RNG state */ 00354 hrng->State = HAL_RNG_STATE_RESET; 00355 00356 /* Initialise the error code */ 00357 hrng->ErrorCode = HAL_RNG_ERROR_NONE; 00358 00359 /* Release Lock */ 00360 __HAL_UNLOCK(hrng); 00361 00362 /* Return the function status */ 00363 return HAL_OK; 00364 } 00365 00366 /** 00367 * @brief Initializes the RNG MSP. 00368 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00369 * the configuration information for RNG. 00370 * @retval None 00371 */ 00372 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng) 00373 { 00374 /* Prevent unused argument(s) compilation warning */ 00375 UNUSED(hrng); 00376 /* NOTE : This function should not be modified. When the callback is needed, 00377 function HAL_RNG_MspInit must be implemented in the user file. 00378 */ 00379 } 00380 00381 /** 00382 * @brief DeInitializes the RNG MSP. 00383 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00384 * the configuration information for RNG. 00385 * @retval None 00386 */ 00387 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng) 00388 { 00389 /* Prevent unused argument(s) compilation warning */ 00390 UNUSED(hrng); 00391 /* NOTE : This function should not be modified. When the callback is needed, 00392 function HAL_RNG_MspDeInit must be implemented in the user file. 00393 */ 00394 } 00395 00396 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) 00397 /** 00398 * @brief Register a User RNG Callback 00399 * To be used instead of the weak predefined callback 00400 * @param hrng RNG handle 00401 * @param CallbackID ID of the callback to be registered 00402 * This parameter can be one of the following values: 00403 * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID 00404 * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID 00405 * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID 00406 * @param pCallback pointer to the Callback function 00407 * @retval HAL status 00408 */ 00409 HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, 00410 pRNG_CallbackTypeDef pCallback) 00411 { 00412 HAL_StatusTypeDef status = HAL_OK; 00413 00414 if (pCallback == NULL) 00415 { 00416 /* Update the error code */ 00417 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00418 return HAL_ERROR; 00419 } 00420 /* Process locked */ 00421 __HAL_LOCK(hrng); 00422 00423 if (HAL_RNG_STATE_READY == hrng->State) 00424 { 00425 switch (CallbackID) 00426 { 00427 case HAL_RNG_ERROR_CB_ID : 00428 hrng->ErrorCallback = pCallback; 00429 break; 00430 00431 case HAL_RNG_MSPINIT_CB_ID : 00432 hrng->MspInitCallback = pCallback; 00433 break; 00434 00435 case HAL_RNG_MSPDEINIT_CB_ID : 00436 hrng->MspDeInitCallback = pCallback; 00437 break; 00438 00439 default : 00440 /* Update the error code */ 00441 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00442 /* Return error status */ 00443 status = HAL_ERROR; 00444 break; 00445 } 00446 } 00447 else if (HAL_RNG_STATE_RESET == hrng->State) 00448 { 00449 switch (CallbackID) 00450 { 00451 case HAL_RNG_MSPINIT_CB_ID : 00452 hrng->MspInitCallback = pCallback; 00453 break; 00454 00455 case HAL_RNG_MSPDEINIT_CB_ID : 00456 hrng->MspDeInitCallback = pCallback; 00457 break; 00458 00459 default : 00460 /* Update the error code */ 00461 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00462 /* Return error status */ 00463 status = HAL_ERROR; 00464 break; 00465 } 00466 } 00467 else 00468 { 00469 /* Update the error code */ 00470 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00471 /* Return error status */ 00472 status = HAL_ERROR; 00473 } 00474 00475 /* Release Lock */ 00476 __HAL_UNLOCK(hrng); 00477 return status; 00478 } 00479 00480 /** 00481 * @brief Unregister an RNG Callback 00482 * RNG callabck is redirected to the weak predefined callback 00483 * @param hrng RNG handle 00484 * @param CallbackID ID of the callback to be unregistered 00485 * This parameter can be one of the following values: 00486 * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID 00487 * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID 00488 * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID 00489 * @retval HAL status 00490 */ 00491 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID) 00492 { 00493 HAL_StatusTypeDef status = HAL_OK; 00494 00495 /* Process locked */ 00496 __HAL_LOCK(hrng); 00497 00498 if (HAL_RNG_STATE_READY == hrng->State) 00499 { 00500 switch (CallbackID) 00501 { 00502 case HAL_RNG_ERROR_CB_ID : 00503 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */ 00504 break; 00505 00506 case HAL_RNG_MSPINIT_CB_ID : 00507 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */ 00508 break; 00509 00510 case HAL_RNG_MSPDEINIT_CB_ID : 00511 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */ 00512 break; 00513 00514 default : 00515 /* Update the error code */ 00516 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00517 /* Return error status */ 00518 status = HAL_ERROR; 00519 break; 00520 } 00521 } 00522 else if (HAL_RNG_STATE_RESET == hrng->State) 00523 { 00524 switch (CallbackID) 00525 { 00526 case HAL_RNG_MSPINIT_CB_ID : 00527 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */ 00528 break; 00529 00530 case HAL_RNG_MSPDEINIT_CB_ID : 00531 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */ 00532 break; 00533 00534 default : 00535 /* Update the error code */ 00536 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00537 /* Return error status */ 00538 status = HAL_ERROR; 00539 break; 00540 } 00541 } 00542 else 00543 { 00544 /* Update the error code */ 00545 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00546 /* Return error status */ 00547 status = HAL_ERROR; 00548 } 00549 00550 /* Release Lock */ 00551 __HAL_UNLOCK(hrng); 00552 return status; 00553 } 00554 00555 /** 00556 * @brief Register Data Ready RNG Callback 00557 * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback 00558 * @param hrng RNG handle 00559 * @param pCallback pointer to the Data Ready Callback function 00560 * @retval HAL status 00561 */ 00562 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback) 00563 { 00564 HAL_StatusTypeDef status = HAL_OK; 00565 00566 if (pCallback == NULL) 00567 { 00568 /* Update the error code */ 00569 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00570 return HAL_ERROR; 00571 } 00572 /* Process locked */ 00573 __HAL_LOCK(hrng); 00574 00575 if (HAL_RNG_STATE_READY == hrng->State) 00576 { 00577 hrng->ReadyDataCallback = pCallback; 00578 } 00579 else 00580 { 00581 /* Update the error code */ 00582 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00583 /* Return error status */ 00584 status = HAL_ERROR; 00585 } 00586 00587 /* Release Lock */ 00588 __HAL_UNLOCK(hrng); 00589 return status; 00590 } 00591 00592 /** 00593 * @brief UnRegister the Data Ready RNG Callback 00594 * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback 00595 * @param hrng RNG handle 00596 * @retval HAL status 00597 */ 00598 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng) 00599 { 00600 HAL_StatusTypeDef status = HAL_OK; 00601 00602 /* Process locked */ 00603 __HAL_LOCK(hrng); 00604 00605 if (HAL_RNG_STATE_READY == hrng->State) 00606 { 00607 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */ 00608 } 00609 else 00610 { 00611 /* Update the error code */ 00612 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK; 00613 /* Return error status */ 00614 status = HAL_ERROR; 00615 } 00616 00617 /* Release Lock */ 00618 __HAL_UNLOCK(hrng); 00619 return status; 00620 } 00621 00622 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ 00623 00624 /** 00625 * @} 00626 */ 00627 00628 /** @addtogroup RNG_Exported_Functions_Group2 00629 * @brief Peripheral Control functions 00630 * 00631 @verbatim 00632 =============================================================================== 00633 ##### Peripheral Control functions ##### 00634 =============================================================================== 00635 [..] This section provides functions allowing to: 00636 (+) Get the 32 bit Random number 00637 (+) Get the 32 bit Random number with interrupt enabled 00638 (+) Handle RNG interrupt request 00639 00640 @endverbatim 00641 * @{ 00642 */ 00643 00644 /** 00645 * @brief Generates a 32-bit random number. 00646 * @note This function checks value of RNG_FLAG_DRDY flag to know if valid 00647 * random number is available in the DR register (RNG_FLAG_DRDY flag set 00648 * whenever a random number is available through the RNG_DR register). 00649 * After transitioning from 0 to 1 (random number available), 00650 * RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading 00651 * four words from the RNG_DR register, i.e. further function calls 00652 * will immediately return a new u32 random number (additional words are 00653 * available and can be read by the application, till RNG_FLAG_DRDY flag remains high). 00654 * @note When no more random number data is available in DR register, RNG_FLAG_DRDY 00655 * flag is automatically cleared. 00656 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00657 * the configuration information for RNG. 00658 * @param random32bit pointer to generated random number variable if successful. 00659 * @retval HAL status 00660 */ 00661 00662 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit) 00663 { 00664 uint32_t tickstart; 00665 HAL_StatusTypeDef status = HAL_OK; 00666 00667 /* Process Locked */ 00668 __HAL_LOCK(hrng); 00669 00670 /* Check RNG peripheral state */ 00671 if (hrng->State == HAL_RNG_STATE_READY) 00672 { 00673 /* Change RNG peripheral state */ 00674 hrng->State = HAL_RNG_STATE_BUSY; 00675 #if defined(RNG_CR_CONDRST) 00676 /* Check if there is a seed error */ 00677 if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) 00678 { 00679 /* Update the error code */ 00680 hrng->ErrorCode = HAL_RNG_ERROR_SEED; 00681 /* Reset from seed error */ 00682 status = RNG_RecoverSeedError(hrng); 00683 if (status == HAL_ERROR) 00684 { 00685 return status; 00686 } 00687 } 00688 #endif /* RNG_CR_CONDRST */ 00689 00690 /* Get tick */ 00691 tickstart = HAL_GetTick(); 00692 00693 /* Check if data register contains valid random data */ 00694 while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET) 00695 { 00696 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE) 00697 { 00698 /* New check to avoid false timeout detection in case of preemption */ 00699 if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET) 00700 { 00701 hrng->State = HAL_RNG_STATE_READY; 00702 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT; 00703 /* Process Unlocked */ 00704 __HAL_UNLOCK(hrng); 00705 return HAL_ERROR; 00706 } 00707 } 00708 } 00709 00710 /* Get a 32bit Random number */ 00711 hrng->RandomNumber = hrng->Instance->DR; 00712 #if defined(RNG_CR_CONDRST) 00713 /* In case of seed error, the value available in the RNG_DR register must not 00714 be used as it may not have enough entropy */ 00715 if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) 00716 { 00717 /* Update the error code */ 00718 hrng->ErrorCode = HAL_RNG_ERROR_SEED; 00719 /* Clear bit DRDY */ 00720 CLEAR_BIT(hrng->Instance->SR, RNG_FLAG_DRDY); 00721 } 00722 else /* No seed error */ 00723 { 00724 *random32bit = hrng->RandomNumber; 00725 } 00726 #else 00727 *random32bit = hrng->RandomNumber; 00728 00729 #endif /* RNG_CR_CONDRST */ 00730 hrng->State = HAL_RNG_STATE_READY; 00731 } 00732 else 00733 { 00734 hrng->ErrorCode = HAL_RNG_ERROR_BUSY; 00735 status = HAL_ERROR; 00736 } 00737 00738 /* Process Unlocked */ 00739 __HAL_UNLOCK(hrng); 00740 00741 return status; 00742 } 00743 00744 /** 00745 * @brief Generates a 32-bit random number in interrupt mode. 00746 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00747 * the configuration information for RNG. 00748 * @retval HAL status 00749 */ 00750 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng) 00751 { 00752 HAL_StatusTypeDef status = HAL_OK; 00753 00754 /* Process Locked */ 00755 __HAL_LOCK(hrng); 00756 00757 /* Check RNG peripheral state */ 00758 if (hrng->State == HAL_RNG_STATE_READY) 00759 { 00760 /* Change RNG peripheral state */ 00761 hrng->State = HAL_RNG_STATE_BUSY; 00762 00763 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */ 00764 __HAL_RNG_ENABLE_IT(hrng); 00765 } 00766 else 00767 { 00768 /* Process Unlocked */ 00769 __HAL_UNLOCK(hrng); 00770 00771 hrng->ErrorCode = HAL_RNG_ERROR_BUSY; 00772 status = HAL_ERROR; 00773 } 00774 00775 return status; 00776 } 00777 00778 /** 00779 * @brief Handles RNG interrupt request. 00780 * @note In the case of a clock error, the RNG is no more able to generate 00781 * random numbers because the PLL48CLK clock is not correct. User has 00782 * to check that the clock controller is correctly configured to provide 00783 * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT(). 00784 * The clock error has no impact on the previously generated 00785 * random numbers, and the RNG_DR register contents can be used. 00786 * @note In the case of a seed error, the generation of random numbers is 00787 * interrupted as long as the SECS bit is '1'. If a number is 00788 * available in the RNG_DR register, it must not be used because it may 00789 * not have enough entropy. In this case, it is recommended to clear the 00790 * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable 00791 * the RNG peripheral to reinitialize and restart the RNG. 00792 * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS 00793 * or CEIS are set. 00794 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00795 * the configuration information for RNG. 00796 * @retval None 00797 00798 */ 00799 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng) 00800 { 00801 uint32_t rngclockerror = 0U; 00802 00803 /* RNG clock error interrupt occurred */ 00804 if (__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET) 00805 { 00806 /* Update the error code */ 00807 hrng->ErrorCode = HAL_RNG_ERROR_CLOCK; 00808 rngclockerror = 1U; 00809 } 00810 else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) 00811 { 00812 /* Check if Seed Error Current Status (SECS) is set */ 00813 if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) == RESET) 00814 { 00815 /* RNG IP performed the reset automatically (auto-reset) */ 00816 /* Clear bit SEIS */ 00817 CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI); 00818 } 00819 else 00820 { 00821 /* Seed Error has not been recovered : Update the error code */ 00822 hrng->ErrorCode = HAL_RNG_ERROR_SEED; 00823 rngclockerror = 1U; 00824 /* Disable the IT */ 00825 __HAL_RNG_DISABLE_IT(hrng); 00826 } 00827 } 00828 else 00829 { 00830 /* Nothing to do */ 00831 } 00832 00833 if (rngclockerror == 1U) 00834 { 00835 /* Change RNG peripheral state */ 00836 hrng->State = HAL_RNG_STATE_ERROR; 00837 00838 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) 00839 /* Call registered Error callback */ 00840 hrng->ErrorCallback(hrng); 00841 #else 00842 /* Call legacy weak Error callback */ 00843 HAL_RNG_ErrorCallback(hrng); 00844 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ 00845 00846 /* Clear the clock error flag */ 00847 __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI); 00848 00849 return; 00850 } 00851 00852 /* Check RNG data ready interrupt occurred */ 00853 if (__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET) 00854 { 00855 /* Generate random number once, so disable the IT */ 00856 __HAL_RNG_DISABLE_IT(hrng); 00857 00858 /* Get the 32bit Random number (DRDY flag automatically cleared) */ 00859 hrng->RandomNumber = hrng->Instance->DR; 00860 00861 if (hrng->State != HAL_RNG_STATE_ERROR) 00862 { 00863 /* Change RNG peripheral state */ 00864 hrng->State = HAL_RNG_STATE_READY; 00865 /* Process Unlocked */ 00866 __HAL_UNLOCK(hrng); 00867 00868 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) 00869 /* Call registered Data Ready callback */ 00870 hrng->ReadyDataCallback(hrng, hrng->RandomNumber); 00871 #else 00872 /* Call legacy weak Data Ready callback */ 00873 HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber); 00874 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ 00875 } 00876 } 00877 } 00878 00879 /** 00880 * @brief Read latest generated random number. 00881 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00882 * the configuration information for RNG. 00883 * @retval random value 00884 */ 00885 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng) 00886 { 00887 return (hrng->RandomNumber); 00888 } 00889 00890 /** 00891 * @brief Data Ready callback in non-blocking mode. 00892 * @note When RNG_FLAG_DRDY flag value is set, first random number has been read 00893 * from DR register in IRQ Handler and is provided as callback parameter. 00894 * Depending on valid data available in the conditioning output buffer, 00895 * additional words can be read by the application from DR register till 00896 * DRDY bit remains high. 00897 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00898 * the configuration information for RNG. 00899 * @param random32bit generated random number. 00900 * @retval None 00901 */ 00902 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit) 00903 { 00904 /* Prevent unused argument(s) compilation warning */ 00905 UNUSED(hrng); 00906 UNUSED(random32bit); 00907 /* NOTE : This function should not be modified. When the callback is needed, 00908 function HAL_RNG_ReadyDataCallback must be implemented in the user file. 00909 */ 00910 } 00911 00912 /** 00913 * @brief RNG error callbacks. 00914 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00915 * the configuration information for RNG. 00916 * @retval None 00917 */ 00918 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng) 00919 { 00920 /* Prevent unused argument(s) compilation warning */ 00921 UNUSED(hrng); 00922 /* NOTE : This function should not be modified. When the callback is needed, 00923 function HAL_RNG_ErrorCallback must be implemented in the user file. 00924 */ 00925 } 00926 /** 00927 * @} 00928 */ 00929 00930 00931 /** @addtogroup RNG_Exported_Functions_Group3 00932 * @brief Peripheral State functions 00933 * 00934 @verbatim 00935 =============================================================================== 00936 ##### Peripheral State functions ##### 00937 =============================================================================== 00938 [..] 00939 This subsection permits to get in run-time the status of the peripheral 00940 and the data flow. 00941 00942 @endverbatim 00943 * @{ 00944 */ 00945 00946 /** 00947 * @brief Returns the RNG state. 00948 * @param hrng pointer to a RNG_HandleTypeDef structure that contains 00949 * the configuration information for RNG. 00950 * @retval HAL state 00951 */ 00952 HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng) 00953 { 00954 return hrng->State; 00955 } 00956 00957 /** 00958 * @brief Return the RNG handle error code. 00959 * @param hrng: pointer to a RNG_HandleTypeDef structure. 00960 * @retval RNG Error Code 00961 */ 00962 uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng) 00963 { 00964 /* Return RNG Error Code */ 00965 return hrng->ErrorCode; 00966 } 00967 /** 00968 * @} 00969 */ 00970 00971 /** 00972 * @} 00973 */ 00974 #if defined(RNG_CR_CONDRST) 00975 /* Private functions ---------------------------------------------------------*/ 00976 /** @addtogroup RNG_Private_Functions 00977 * @{ 00978 */ 00979 00980 /** 00981 * @brief RNG sequence to recover from a seed error 00982 * @param hrng pointer to a RNG_HandleTypeDef structure. 00983 * @retval HAL status 00984 */ 00985 HAL_StatusTypeDef RNG_RecoverSeedError(RNG_HandleTypeDef *hrng) 00986 { 00987 __IO uint32_t count = 0U; 00988 00989 /*Check if seed error current status (SECS)is set */ 00990 if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) == RESET) 00991 { 00992 /* RNG performed the reset automatically (auto-reset) */ 00993 /* Clear bit SEIS */ 00994 CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI); 00995 } 00996 else /* Sequence to fully recover from a seed error*/ 00997 { 00998 /* Writing bit CONDRST=1*/ 00999 SET_BIT(hrng->Instance->CR, RNG_CR_CONDRST); 01000 /* Writing bit CONDRST=0*/ 01001 CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST); 01002 01003 /* Wait for conditioning reset process to be completed */ 01004 count = RNG_TIMEOUT_VALUE; 01005 do 01006 { 01007 count-- ; 01008 if (count == 0U) 01009 { 01010 hrng->State = HAL_RNG_STATE_READY; 01011 hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT; 01012 /* Process Unlocked */ 01013 __HAL_UNLOCK(hrng); 01014 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) 01015 /* Call registered Error callback */ 01016 hrng->ErrorCallback(hrng); 01017 #else 01018 /* Call legacy weak Error callback */ 01019 HAL_RNG_ErrorCallback(hrng); 01020 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ 01021 return HAL_ERROR; 01022 } 01023 } while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST)); 01024 01025 if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET) 01026 { 01027 /* Clear bit SEIS */ 01028 CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI); 01029 } 01030 01031 /* Wait for SECS to be cleared */ 01032 count = RNG_TIMEOUT_VALUE; 01033 do 01034 { 01035 count-- ; 01036 if (count == 0U) 01037 { 01038 hrng->State = HAL_RNG_STATE_READY; 01039 hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT; 01040 /* Process Unlocked */ 01041 __HAL_UNLOCK(hrng); 01042 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1) 01043 /* Call registered Error callback */ 01044 hrng->ErrorCallback(hrng); 01045 #else 01046 /* Call legacy weak Error callback */ 01047 HAL_RNG_ErrorCallback(hrng); 01048 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */ 01049 return HAL_ERROR; 01050 } 01051 } while (HAL_IS_BIT_SET(hrng->Instance->SR, RNG_FLAG_SECS)); 01052 } 01053 /* Update the error code */ 01054 hrng->ErrorCode &= ~ HAL_RNG_ERROR_SEED; 01055 return HAL_OK; 01056 } 01057 01058 /** 01059 * @} 01060 */ 01061 #endif /* RNG_CR_CONDRST */ 01062 01063 01064 #endif /* HAL_RNG_MODULE_ENABLED */ 01065 /** 01066 * @} 01067 */ 01068 01069 #endif /* RNG */ 01070 01071 /** 01072 * @} 01073 */ 01074