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