STM32L443xx HAL User Manual
stm32l4xx_hal_rng.c
Go to the documentation of this file.
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   */