Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_rng.c
0004   * @author  MCD Application Team
0005   * @brief   RNG HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Random Number Generator (RNG) peripheral:
0008   *           + Initialization and configuration functions
0009   *           + Peripheral Control functions
0010   *           + Peripheral State functions
0011   *
0012   ******************************************************************************
0013   * @attention
0014   *
0015   * Copyright (c) 2017 STMicroelectronics.
0016   * All rights reserved.
0017   *
0018   * This software is licensed under terms that can be found in the LICENSE file
0019   * in the root directory of this software component.
0020   * If no LICENSE file comes with this software, it is provided AS-IS.
0021   *
0022   ******************************************************************************
0023   @verbatim
0024   ==============================================================================
0025                      ##### How to use this driver #####
0026   ==============================================================================
0027   [..]
0028       The RNG HAL driver can be used as follows:
0029 
0030       (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro
0031           in HAL_RNG_MspInit().
0032       (#) Activate the RNG peripheral using HAL_RNG_Init() function.
0033       (#) Wait until the 32 bit Random Number Generator contains a valid
0034           random data using (polling/interrupt) mode.
0035       (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function.
0036 
0037     ##### Callback registration #####
0038     ==================================
0039 
0040     [..]
0041     The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1
0042     allows the user to configure dynamically the driver callbacks.
0043 
0044     [..]
0045     Use Function HAL_RNG_RegisterCallback() to register a user callback.
0046     Function HAL_RNG_RegisterCallback() allows to register following callbacks:
0047     (+) ErrorCallback             : RNG Error Callback.
0048     (+) MspInitCallback           : RNG MspInit.
0049     (+) MspDeInitCallback         : RNG MspDeInit.
0050     This function takes as parameters the HAL peripheral handle, the Callback ID
0051     and a pointer to the user callback function.
0052 
0053     [..]
0054     Use function HAL_RNG_UnRegisterCallback() to reset a callback to the default
0055     weak (overridden) function.
0056     HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle,
0057     and the Callback ID.
0058     This function allows to reset following callbacks:
0059     (+) ErrorCallback             : RNG Error Callback.
0060     (+) MspInitCallback           : RNG MspInit.
0061     (+) MspDeInitCallback         : RNG MspDeInit.
0062 
0063     [..]
0064     For specific callback ReadyDataCallback, use dedicated register callbacks:
0065     respectively HAL_RNG_RegisterReadyDataCallback() , HAL_RNG_UnRegisterReadyDataCallback().
0066 
0067     [..]
0068     By default, after the HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET
0069     all callbacks are set to the corresponding weak (overridden) functions:
0070     example HAL_RNG_ErrorCallback().
0071     Exception done for MspInit and MspDeInit functions that are respectively
0072     reset to the legacy weak (overridden) functions in the HAL_RNG_Init()
0073     and HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand).
0074     If not, MspInit or MspDeInit are not null, the HAL_RNG_Init() and HAL_RNG_DeInit()
0075     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
0076 
0077     [..]
0078     Callbacks can be registered/unregistered in HAL_RNG_STATE_READY state only.
0079     Exception done MspInit/MspDeInit that can be registered/unregistered
0080     in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user)
0081     MspInit/DeInit callbacks can be used during the Init/DeInit.
0082     In that case first register the MspInit/MspDeInit user callbacks
0083     using HAL_RNG_RegisterCallback() before calling HAL_RNG_DeInit()
0084     or HAL_RNG_Init() function.
0085 
0086     [..]
0087     When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or
0088     not defined, the callback registration feature is not available
0089     and weak (overridden) callbacks are used.
0090 
0091   @endverbatim
0092   ******************************************************************************
0093   */
0094 
0095 /* Includes ------------------------------------------------------------------*/
0096 #include "stm32h7xx_hal.h"
0097 
0098 /** @addtogroup STM32H7xx_HAL_Driver
0099   * @{
0100   */
0101 
0102 #if defined (RNG)
0103 
0104 /** @addtogroup RNG
0105   * @brief RNG HAL module driver.
0106   * @{
0107   */
0108 
0109 #ifdef HAL_RNG_MODULE_ENABLED
0110 
0111 /* Private types -------------------------------------------------------------*/
0112 /* Private defines -----------------------------------------------------------*/
0113 /** @defgroup RNG_Private_Defines RNG Private Defines
0114   * @ingroup RTEMSBSPsARMSTM32H7
0115   * @{
0116   */
0117 /*  Health test control register information to use in CCM algorithm */
0118 #define RNG_HTCFG_1   0x17590ABCU /*!< Magic number */
0119 #if defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
0120 #define RNG_HTCFG     0x000CAA74U /*!< For best latency and to be compliant with NIST */
0121 #else /* RNG_VER_3_2 */
0122 #define RNG_HTCFG     0x00007274U /*!< For best latency and to be compliant with NIST */
0123 #endif /* RNG_VER_3_1 || RNG_VER_3_0 */
0124 /**
0125   * @}
0126   */
0127 /* Private variables ---------------------------------------------------------*/
0128 /* Private constants ---------------------------------------------------------*/
0129 /** @defgroup RNG_Private_Constants RNG Private Constants
0130   * @ingroup RTEMSBSPsARMSTM32H7
0131   * @{
0132   */
0133 #define RNG_TIMEOUT_VALUE     2U
0134 /**
0135   * @}
0136   */
0137 /* Private macros ------------------------------------------------------------*/
0138 /* Private functions prototypes ----------------------------------------------*/
0139 /* Exported functions --------------------------------------------------------*/
0140 
0141 /** @addtogroup RNG_Exported_Functions
0142   * @{
0143   */
0144 
0145 /** @addtogroup RNG_Exported_Functions_Group1
0146   *  @brief   Initialization and configuration functions
0147   *
0148 @verbatim
0149  ===============================================================================
0150           ##### Initialization and configuration functions #####
0151  ===============================================================================
0152     [..]  This section provides functions allowing to:
0153       (+) Initialize the RNG according to the specified parameters
0154           in the RNG_InitTypeDef and create the associated handle
0155       (+) DeInitialize the RNG peripheral
0156       (+) Initialize the RNG MSP
0157       (+) DeInitialize RNG MSP
0158 
0159 @endverbatim
0160   * @{
0161   */
0162 
0163 /**
0164   * @brief  Initializes the RNG peripheral and creates the associated handle.
0165   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0166   *                the configuration information for RNG.
0167   * @retval HAL status
0168   */
0169 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
0170 {
0171   uint32_t tickstart;
0172   /* Check the RNG handle allocation */
0173   if (hrng == NULL)
0174   {
0175     return HAL_ERROR;
0176   }
0177   /* Check the parameters */
0178   assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
0179   assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
0180 
0181 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
0182   if (hrng->State == HAL_RNG_STATE_RESET)
0183   {
0184     /* Allocate lock resource and initialize it */
0185     hrng->Lock = HAL_UNLOCKED;
0186 
0187     hrng->ReadyDataCallback  = HAL_RNG_ReadyDataCallback;  /* Legacy weak ReadyDataCallback  */
0188     hrng->ErrorCallback      = HAL_RNG_ErrorCallback;      /* Legacy weak ErrorCallback      */
0189 
0190     if (hrng->MspInitCallback == NULL)
0191     {
0192       hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit  */
0193     }
0194 
0195     /* Init the low level hardware */
0196     hrng->MspInitCallback(hrng);
0197   }
0198 #else
0199   if (hrng->State == HAL_RNG_STATE_RESET)
0200   {
0201     /* Allocate lock resource and initialize it */
0202     hrng->Lock = HAL_UNLOCKED;
0203 
0204     /* Init the low level hardware */
0205     HAL_RNG_MspInit(hrng);
0206   }
0207 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
0208 
0209   /* Change RNG peripheral state */
0210   hrng->State = HAL_RNG_STATE_BUSY;
0211 
0212 #if defined(RNG_CR_CONDRST)
0213   /* Disable RNG */
0214   __HAL_RNG_DISABLE(hrng);
0215 
0216   /* Clock Error Detection Configuration when CONDRT bit is set to 1 */
0217   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, hrng->Init.ClockErrorDetection | RNG_CR_CONDRST);
0218 #if defined(RNG_VER_3_2) || defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
0219   /*!< magic number must be written immediately before to RNG_HTCRG */
0220   WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG_1);
0221   /* for best latency and to be compliant with NIST */
0222   WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG);
0223 #endif /* RNG_VER_3_2 || RNG_VER_3_1 || RNG_VER_3_0 */
0224 
0225   /* Writing bit CONDRST=0 */
0226   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
0227 
0228   /* Get tick */
0229   tickstart = HAL_GetTick();
0230 
0231   /* Wait for conditioning reset process to be completed */
0232   while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
0233   {
0234     if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
0235     {
0236       /* New check to avoid false timeout detection in case of preemption */
0237       if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
0238       {
0239         hrng->State = HAL_RNG_STATE_READY;
0240         hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
0241         return HAL_ERROR;
0242       }
0243     }
0244   }
0245 #else
0246   /* Clock Error Detection Configuration */
0247   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
0248 #endif /* RNG_CR_CONDRST */
0249 
0250   /* Enable the RNG Peripheral */
0251   __HAL_RNG_ENABLE(hrng);
0252 
0253   /* verify that no seed error */
0254   if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
0255   {
0256     hrng->State = HAL_RNG_STATE_ERROR;
0257     return HAL_ERROR;
0258   }
0259   /* Get tick */
0260   tickstart = HAL_GetTick();
0261   /* Check if data register contains valid random data */
0262   while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
0263   {
0264     if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
0265     {
0266       /* New check to avoid false timeout detection in case of preemption */
0267       if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
0268       {
0269         hrng->State = HAL_RNG_STATE_ERROR;
0270         hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
0271         return HAL_ERROR;
0272       }
0273     }
0274   }
0275 
0276   /* Initialize the RNG state */
0277   hrng->State = HAL_RNG_STATE_READY;
0278 
0279   /* Initialise the error code */
0280   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
0281 
0282   /* Return function status */
0283   return HAL_OK;
0284 }
0285 
0286 /**
0287   * @brief  DeInitializes the RNG peripheral.
0288   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0289   *                the configuration information for RNG.
0290   * @retval HAL status
0291   */
0292 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
0293 {
0294 #if defined(RNG_CR_CONDRST)
0295   uint32_t tickstart;
0296 
0297 #endif /* RNG_CR_CONDRST */
0298   /* Check the RNG handle allocation */
0299   if (hrng == NULL)
0300   {
0301     return HAL_ERROR;
0302   }
0303 
0304 #if defined(RNG_CR_CONDRST)
0305   /* Clear Clock Error Detection bit when CONDRT bit is set to 1 */
0306   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST);
0307 
0308   /* Writing bit CONDRST=0 */
0309   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
0310 
0311   /* Get tick */
0312   tickstart = HAL_GetTick();
0313 
0314   /* Wait for conditioning reset process to be completed */
0315   while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
0316   {
0317     if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
0318     {
0319       /* New check to avoid false timeout detection in case of preemption */
0320       if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
0321       {
0322         hrng->State = HAL_RNG_STATE_READY;
0323         hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
0324         /* Process Unlocked */
0325         __HAL_UNLOCK(hrng);
0326         return HAL_ERROR;
0327       }
0328     }
0329   }
0330 
0331 #else
0332   /* Clear Clock Error Detection bit */
0333   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
0334 #endif /* RNG_CR_CONDRST */
0335   /* Disable the RNG Peripheral */
0336   CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
0337 
0338   /* Clear RNG interrupt status flags */
0339   CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
0340 
0341 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
0342   if (hrng->MspDeInitCallback == NULL)
0343   {
0344     hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit  */
0345   }
0346 
0347   /* DeInit the low level hardware */
0348   hrng->MspDeInitCallback(hrng);
0349 #else
0350   /* DeInit the low level hardware */
0351   HAL_RNG_MspDeInit(hrng);
0352 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
0353 
0354   /* Update the RNG state */
0355   hrng->State = HAL_RNG_STATE_RESET;
0356 
0357   /* Initialise the error code */
0358   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
0359 
0360   /* Release Lock */
0361   __HAL_UNLOCK(hrng);
0362 
0363   /* Return the function status */
0364   return HAL_OK;
0365 }
0366 
0367 /**
0368   * @brief  Initializes the RNG MSP.
0369   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0370   *                the configuration information for RNG.
0371   * @retval None
0372   */
0373 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
0374 {
0375   /* Prevent unused argument(s) compilation warning */
0376   UNUSED(hrng);
0377   /* NOTE : This function should not be modified. When the callback is needed,
0378             function HAL_RNG_MspInit must be implemented in the user file.
0379    */
0380 }
0381 
0382 /**
0383   * @brief  DeInitializes the RNG MSP.
0384   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0385   *                the configuration information for RNG.
0386   * @retval None
0387   */
0388 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
0389 {
0390   /* Prevent unused argument(s) compilation warning */
0391   UNUSED(hrng);
0392   /* NOTE : This function should not be modified. When the callback is needed,
0393             function HAL_RNG_MspDeInit must be implemented in the user file.
0394    */
0395 }
0396 
0397 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
0398 /**
0399   * @brief  Register a User RNG Callback
0400   *         To be used instead of the weak predefined callback
0401   * @param  hrng RNG handle
0402   * @param  CallbackID ID of the callback to be registered
0403   *         This parameter can be one of the following values:
0404   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
0405   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
0406   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
0407   * @param  pCallback pointer to the Callback function
0408   * @retval HAL status
0409   */
0410 HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID,
0411                                            pRNG_CallbackTypeDef pCallback)
0412 {
0413   HAL_StatusTypeDef status = HAL_OK;
0414 
0415   if (pCallback == NULL)
0416   {
0417     /* Update the error code */
0418     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0419     return HAL_ERROR;
0420   }
0421 
0422   if (HAL_RNG_STATE_READY == hrng->State)
0423   {
0424     switch (CallbackID)
0425     {
0426       case HAL_RNG_ERROR_CB_ID :
0427         hrng->ErrorCallback = pCallback;
0428         break;
0429 
0430       case HAL_RNG_MSPINIT_CB_ID :
0431         hrng->MspInitCallback = pCallback;
0432         break;
0433 
0434       case HAL_RNG_MSPDEINIT_CB_ID :
0435         hrng->MspDeInitCallback = pCallback;
0436         break;
0437 
0438       default :
0439         /* Update the error code */
0440         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0441         /* Return error status */
0442         status =  HAL_ERROR;
0443         break;
0444     }
0445   }
0446   else if (HAL_RNG_STATE_RESET == hrng->State)
0447   {
0448     switch (CallbackID)
0449     {
0450       case HAL_RNG_MSPINIT_CB_ID :
0451         hrng->MspInitCallback = pCallback;
0452         break;
0453 
0454       case HAL_RNG_MSPDEINIT_CB_ID :
0455         hrng->MspDeInitCallback = pCallback;
0456         break;
0457 
0458       default :
0459         /* Update the error code */
0460         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0461         /* Return error status */
0462         status =  HAL_ERROR;
0463         break;
0464     }
0465   }
0466   else
0467   {
0468     /* Update the error code */
0469     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0470     /* Return error status */
0471     status =  HAL_ERROR;
0472   }
0473 
0474   return status;
0475 }
0476 
0477 /**
0478   * @brief  Unregister an RNG Callback
0479   *         RNG callback is redirected to the weak predefined callback
0480   * @param  hrng RNG handle
0481   * @param  CallbackID ID of the callback to be unregistered
0482   *         This parameter can be one of the following values:
0483   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
0484   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
0485   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
0486   * @retval HAL status
0487   */
0488 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
0489 {
0490   HAL_StatusTypeDef status = HAL_OK;
0491 
0492 
0493   if (HAL_RNG_STATE_READY == hrng->State)
0494   {
0495     switch (CallbackID)
0496     {
0497       case HAL_RNG_ERROR_CB_ID :
0498         hrng->ErrorCallback = HAL_RNG_ErrorCallback;          /* Legacy weak ErrorCallback  */
0499         break;
0500 
0501       case HAL_RNG_MSPINIT_CB_ID :
0502         hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
0503         break;
0504 
0505       case HAL_RNG_MSPDEINIT_CB_ID :
0506         hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspDeInit  */
0507         break;
0508 
0509       default :
0510         /* Update the error code */
0511         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0512         /* Return error status */
0513         status =  HAL_ERROR;
0514         break;
0515     }
0516   }
0517   else if (HAL_RNG_STATE_RESET == hrng->State)
0518   {
0519     switch (CallbackID)
0520     {
0521       case HAL_RNG_MSPINIT_CB_ID :
0522         hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
0523         break;
0524 
0525       case HAL_RNG_MSPDEINIT_CB_ID :
0526         hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspInit  */
0527         break;
0528 
0529       default :
0530         /* Update the error code */
0531         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0532         /* Return error status */
0533         status =  HAL_ERROR;
0534         break;
0535     }
0536   }
0537   else
0538   {
0539     /* Update the error code */
0540     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0541     /* Return error status */
0542     status =  HAL_ERROR;
0543   }
0544 
0545   return status;
0546 }
0547 
0548 /**
0549   * @brief  Register Data Ready RNG Callback
0550   *         To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
0551   * @param  hrng RNG handle
0552   * @param  pCallback pointer to the Data Ready Callback function
0553   * @retval HAL status
0554   */
0555 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
0556 {
0557   HAL_StatusTypeDef status = HAL_OK;
0558 
0559   if (pCallback == NULL)
0560   {
0561     /* Update the error code */
0562     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0563     return HAL_ERROR;
0564   }
0565   /* Process locked */
0566   __HAL_LOCK(hrng);
0567 
0568   if (HAL_RNG_STATE_READY == hrng->State)
0569   {
0570     hrng->ReadyDataCallback = pCallback;
0571   }
0572   else
0573   {
0574     /* Update the error code */
0575     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0576     /* Return error status */
0577     status =  HAL_ERROR;
0578   }
0579 
0580   /* Release Lock */
0581   __HAL_UNLOCK(hrng);
0582   return status;
0583 }
0584 
0585 /**
0586   * @brief  UnRegister the Data Ready RNG Callback
0587   *         Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
0588   * @param  hrng RNG handle
0589   * @retval HAL status
0590   */
0591 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
0592 {
0593   HAL_StatusTypeDef status = HAL_OK;
0594 
0595   /* Process locked */
0596   __HAL_LOCK(hrng);
0597 
0598   if (HAL_RNG_STATE_READY == hrng->State)
0599   {
0600     hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback  */
0601   }
0602   else
0603   {
0604     /* Update the error code */
0605     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
0606     /* Return error status */
0607     status =  HAL_ERROR;
0608   }
0609 
0610   /* Release Lock */
0611   __HAL_UNLOCK(hrng);
0612   return status;
0613 }
0614 
0615 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
0616 
0617 /**
0618   * @}
0619   */
0620 
0621 /** @addtogroup RNG_Exported_Functions_Group2
0622   *  @brief   Peripheral Control functions
0623   *
0624 @verbatim
0625  ===============================================================================
0626                       ##### Peripheral Control functions #####
0627  ===============================================================================
0628     [..]  This section provides functions allowing to:
0629       (+) Get the 32 bit Random number
0630       (+) Get the 32 bit Random number with interrupt enabled
0631       (+) Handle RNG interrupt request
0632 
0633 @endverbatim
0634   * @{
0635   */
0636 
0637 /**
0638   * @brief  Generates a 32-bit random number.
0639   * @note   This function checks value of RNG_FLAG_DRDY flag to know if valid
0640   *         random number is available in the DR register (RNG_FLAG_DRDY flag set
0641   *         whenever a random number is available through the RNG_DR register).
0642   *         After transitioning from 0 to 1 (random number available),
0643   *         RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading
0644   *         four words from the RNG_DR register, i.e. further function calls
0645   *         will immediately return a new u32 random number (additional words are
0646   *         available and can be read by the application, till RNG_FLAG_DRDY flag remains high).
0647   * @note   When no more random number data is available in DR register, RNG_FLAG_DRDY
0648   *         flag is automatically cleared.
0649   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0650   *                the configuration information for RNG.
0651   * @param  random32bit pointer to generated random number variable if successful.
0652   * @retval HAL status
0653   */
0654 
0655 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
0656 {
0657   uint32_t tickstart;
0658   HAL_StatusTypeDef status = HAL_OK;
0659 
0660   /* Process Locked */
0661   __HAL_LOCK(hrng);
0662 
0663   /* Check RNG peripheral state */
0664   if (hrng->State == HAL_RNG_STATE_READY)
0665   {
0666     /* Change RNG peripheral state */
0667     hrng->State = HAL_RNG_STATE_BUSY;
0668 #if defined(RNG_CR_CONDRST)
0669     /* Check if there is a seed error */
0670     if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
0671     {
0672       /* Update the error code */
0673       hrng->ErrorCode = HAL_RNG_ERROR_SEED;
0674       /* Reset from seed error */
0675       status = RNG_RecoverSeedError(hrng);
0676       if (status == HAL_ERROR)
0677       {
0678         return status;
0679       }
0680     }
0681 #endif /* RNG_CR_CONDRST */
0682 
0683     /* Get tick */
0684     tickstart = HAL_GetTick();
0685 
0686     /* Check if data register contains valid random data */
0687     while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
0688     {
0689       if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
0690       {
0691         /* New check to avoid false timeout detection in case of preemption */
0692         if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
0693         {
0694           hrng->State = HAL_RNG_STATE_READY;
0695           hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
0696           /* Process Unlocked */
0697           __HAL_UNLOCK(hrng);
0698           return HAL_ERROR;
0699         }
0700       }
0701     }
0702 
0703     /* Get a 32bit Random number */
0704     hrng->RandomNumber = hrng->Instance->DR;
0705 #if defined(RNG_CR_CONDRST)
0706     /* In case of seed error, the value available in the RNG_DR register must not
0707        be used as it may not have enough entropy */
0708     if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
0709     {
0710       /* Update the error code and status */
0711       hrng->ErrorCode = HAL_RNG_ERROR_SEED;
0712       status = HAL_ERROR;
0713     }
0714     else /* No seed error */
0715     {
0716       *random32bit = hrng->RandomNumber;
0717     }
0718 #else
0719     *random32bit = hrng->RandomNumber;
0720 
0721 #endif /* RNG_CR_CONDRST */
0722     hrng->State = HAL_RNG_STATE_READY;
0723   }
0724   else
0725   {
0726     hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
0727     status = HAL_ERROR;
0728   }
0729 
0730   /* Process Unlocked */
0731   __HAL_UNLOCK(hrng);
0732 
0733   return status;
0734 }
0735 
0736 /**
0737   * @brief  Generates a 32-bit random number in interrupt mode.
0738   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0739   *                the configuration information for RNG.
0740   * @retval HAL status
0741   */
0742 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
0743 {
0744   HAL_StatusTypeDef status = HAL_OK;
0745 
0746   /* Process Locked */
0747   __HAL_LOCK(hrng);
0748 
0749   /* Check RNG peripheral state */
0750   if (hrng->State == HAL_RNG_STATE_READY)
0751   {
0752     /* Change RNG peripheral state */
0753     hrng->State = HAL_RNG_STATE_BUSY;
0754 
0755     /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
0756     __HAL_RNG_ENABLE_IT(hrng);
0757   }
0758   else
0759   {
0760     /* Process Unlocked */
0761     __HAL_UNLOCK(hrng);
0762 
0763     hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
0764     status = HAL_ERROR;
0765   }
0766 
0767   return status;
0768 }
0769 
0770 /**
0771   * @brief  Handles RNG interrupt request.
0772   * @note   In the case of a clock error, the RNG is no more able to generate
0773   *         random numbers because the PLL48CLK clock is not correct. User has
0774   *         to check that the clock controller is correctly configured to provide
0775   *         the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
0776   *         The clock error has no impact on the previously generated
0777   *         random numbers, and the RNG_DR register contents can be used.
0778   * @note   In the case of a seed error, the generation of random numbers is
0779   *         interrupted as long as the SECS bit is '1'. If a number is
0780   *         available in the RNG_DR register, it must not be used because it may
0781   *         not have enough entropy. In this case, it is recommended to clear the
0782   *         SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
0783   *         the RNG peripheral to reinitialize and restart the RNG.
0784   * @note   User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
0785   *         or CEIS are set.
0786   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0787   *                the configuration information for RNG.
0788   * @retval None
0789 
0790   */
0791 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
0792 {
0793   uint32_t rngclockerror = 0U;
0794   uint32_t itflag   = hrng->Instance->SR;
0795 
0796   /* RNG clock error interrupt occurred */
0797   if ((itflag & RNG_IT_CEI) == RNG_IT_CEI)
0798   {
0799     /* Update the error code */
0800     hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
0801     rngclockerror = 1U;
0802   }
0803   else if ((itflag & RNG_IT_SEI) == RNG_IT_SEI)
0804   {
0805     /* Check if Seed Error Current Status (SECS) is set */
0806     if ((itflag & RNG_FLAG_SECS) != RNG_FLAG_SECS)
0807     {
0808       /* RNG IP performed the reset automatically (auto-reset) */
0809       /* Clear bit SEIS */
0810       CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
0811     }
0812     else
0813     {
0814       /* Seed Error has not been recovered : Update the error code */
0815       hrng->ErrorCode = HAL_RNG_ERROR_SEED;
0816       rngclockerror = 1U;
0817       /* Disable the IT */
0818       __HAL_RNG_DISABLE_IT(hrng);
0819     }
0820   }
0821   else
0822   {
0823     /* Nothing to do */
0824   }
0825 
0826   if (rngclockerror == 1U)
0827   {
0828     /* Change RNG peripheral state */
0829     hrng->State = HAL_RNG_STATE_ERROR;
0830 
0831 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
0832     /* Call registered Error callback */
0833     hrng->ErrorCallback(hrng);
0834 #else
0835     /* Call legacy weak Error callback */
0836     HAL_RNG_ErrorCallback(hrng);
0837 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
0838 
0839     /* Clear the clock error flag */
0840     __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
0841 
0842     return;
0843   }
0844 
0845   /* Check RNG data ready interrupt occurred */
0846   if ((itflag & RNG_IT_DRDY) == RNG_IT_DRDY)
0847   {
0848     /* Generate random number once, so disable the IT */
0849     __HAL_RNG_DISABLE_IT(hrng);
0850 
0851     /* Get the 32bit Random number (DRDY flag automatically cleared) */
0852     hrng->RandomNumber = hrng->Instance->DR;
0853 
0854     if (hrng->State != HAL_RNG_STATE_ERROR)
0855     {
0856       /* Change RNG peripheral state */
0857       hrng->State = HAL_RNG_STATE_READY;
0858       /* Process Unlocked */
0859       __HAL_UNLOCK(hrng);
0860 
0861 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
0862       /* Call registered Data Ready callback */
0863       hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
0864 #else
0865       /* Call legacy weak Data Ready callback */
0866       HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
0867 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
0868     }
0869   }
0870 }
0871 
0872 /**
0873   * @brief  Read latest generated random number.
0874   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0875   *                the configuration information for RNG.
0876   * @retval random value
0877   */
0878 uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng)
0879 {
0880   return (hrng->RandomNumber);
0881 }
0882 
0883 /**
0884   * @brief  Data Ready callback in non-blocking mode.
0885   * @note   When RNG_FLAG_DRDY flag value is set, first random number has been read
0886   *         from DR register in IRQ Handler and is provided as callback parameter.
0887   *         Depending on valid data available in the conditioning output buffer,
0888   *         additional words can be read by the application from DR register till
0889   *         DRDY bit remains high.
0890   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0891   *                the configuration information for RNG.
0892   * @param  random32bit generated random number.
0893   * @retval None
0894   */
0895 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
0896 {
0897   /* Prevent unused argument(s) compilation warning */
0898   UNUSED(hrng);
0899   UNUSED(random32bit);
0900   /* NOTE : This function should not be modified. When the callback is needed,
0901             function HAL_RNG_ReadyDataCallback must be implemented in the user file.
0902    */
0903 }
0904 
0905 /**
0906   * @brief  RNG error callbacks.
0907   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0908   *                the configuration information for RNG.
0909   * @retval None
0910   */
0911 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
0912 {
0913   /* Prevent unused argument(s) compilation warning */
0914   UNUSED(hrng);
0915   /* NOTE : This function should not be modified. When the callback is needed,
0916             function HAL_RNG_ErrorCallback must be implemented in the user file.
0917    */
0918 }
0919 /**
0920   * @}
0921   */
0922 
0923 
0924 /** @addtogroup RNG_Exported_Functions_Group3
0925   *  @brief   Peripheral State functions
0926   *
0927 @verbatim
0928  ===============================================================================
0929                       ##### Peripheral State functions #####
0930  ===============================================================================
0931     [..]
0932     This subsection permits to get in run-time the status of the peripheral
0933     and the data flow.
0934 
0935 @endverbatim
0936   * @{
0937   */
0938 
0939 /**
0940   * @brief  Returns the RNG state.
0941   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
0942   *                the configuration information for RNG.
0943   * @retval HAL state
0944   */
0945 HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng)
0946 {
0947   return hrng->State;
0948 }
0949 
0950 /**
0951   * @brief  Return the RNG handle error code.
0952   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
0953   * @retval RNG Error Code
0954   */
0955 uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng)
0956 {
0957   /* Return RNG Error Code */
0958   return hrng->ErrorCode;
0959 }
0960 /**
0961   * @}
0962   */
0963 
0964 /**
0965   * @}
0966   */
0967 #if defined(RNG_CR_CONDRST)
0968 /* Private functions ---------------------------------------------------------*/
0969 /** @addtogroup RNG_Private_Functions
0970   * @{
0971   */
0972 
0973 /**
0974   * @brief  RNG sequence to recover from a seed error
0975   * @param  hrng pointer to a RNG_HandleTypeDef structure.
0976   * @retval HAL status
0977   */
0978 HAL_StatusTypeDef RNG_RecoverSeedError(RNG_HandleTypeDef *hrng)
0979 {
0980   __IO uint32_t count = 0U;
0981 
0982   /*Check if seed error current status (SECS)is set */
0983   if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) == RESET)
0984   {
0985     /* RNG performed the reset automatically (auto-reset) */
0986     /* Clear bit SEIS */
0987     CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
0988   }
0989   else  /* Sequence to fully recover from a seed error*/
0990   {
0991     /* Writing bit CONDRST=1*/
0992     SET_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
0993     /* Writing bit CONDRST=0*/
0994     CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
0995 
0996     /* Wait for conditioning reset process to be completed */
0997     count = RNG_TIMEOUT_VALUE;
0998     do
0999     {
1000       count-- ;
1001       if (count == 0U)
1002       {
1003         hrng->State = HAL_RNG_STATE_READY;
1004         hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT;
1005         /* Process Unlocked */
1006         __HAL_UNLOCK(hrng);
1007 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
1008         /* Call registered Error callback */
1009         hrng->ErrorCallback(hrng);
1010 #else
1011         /* Call legacy weak Error callback */
1012         HAL_RNG_ErrorCallback(hrng);
1013 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
1014         return HAL_ERROR;
1015       }
1016     } while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST));
1017 
1018     if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
1019     {
1020       /* Clear bit SEIS */
1021       CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
1022     }
1023 
1024     /* Wait for SECS to be cleared */
1025     count = RNG_TIMEOUT_VALUE;
1026     do
1027     {
1028       count-- ;
1029       if (count == 0U)
1030       {
1031         hrng->State = HAL_RNG_STATE_READY;
1032         hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT;
1033         /* Process Unlocked */
1034         __HAL_UNLOCK(hrng);
1035 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
1036         /* Call registered Error callback */
1037         hrng->ErrorCallback(hrng);
1038 #else
1039         /* Call legacy weak Error callback */
1040         HAL_RNG_ErrorCallback(hrng);
1041 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
1042         return HAL_ERROR;
1043       }
1044     } while (HAL_IS_BIT_SET(hrng->Instance->SR, RNG_FLAG_SECS));
1045   }
1046   /* Update the error code */
1047   hrng->ErrorCode &= ~ HAL_RNG_ERROR_SEED;
1048   return HAL_OK;
1049 }
1050 
1051 /**
1052   * @}
1053   */
1054 #endif /* RNG_CR_CONDRST */
1055 
1056 
1057 #endif /* HAL_RNG_MODULE_ENABLED */
1058 /**
1059   * @}
1060   */
1061 
1062 #endif /* RNG */
1063 
1064 /**
1065   * @}
1066   */
1067