123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065 |
- /**
- ******************************************************************************
- * @file stm32h7xx_hal_rng.c
- * @author MCD Application Team
- * @brief RNG HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Random Number Generator (RNG) peripheral:
- * + Initialization and configuration functions
- * + Peripheral Control functions
- * + Peripheral State functions
- *
- ******************************************************************************
- * @attention
- *
- * Copyright (c) 2017 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- ******************************************************************************
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- The RNG HAL driver can be used as follows:
- (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro
- in HAL_RNG_MspInit().
- (#) Activate the RNG peripheral using HAL_RNG_Init() function.
- (#) Wait until the 32 bit Random Number Generator contains a valid
- random data using (polling/interrupt) mode.
- (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function.
- ##### Callback registration #####
- ==================================
- [..]
- The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1
- allows the user to configure dynamically the driver callbacks.
- [..]
- Use Function HAL_RNG_RegisterCallback() to register a user callback.
- Function HAL_RNG_RegisterCallback() allows to register following callbacks:
- (+) ErrorCallback : RNG Error Callback.
- (+) MspInitCallback : RNG MspInit.
- (+) MspDeInitCallback : RNG MspDeInit.
- This function takes as parameters the HAL peripheral handle, the Callback ID
- and a pointer to the user callback function.
- [..]
- Use function HAL_RNG_UnRegisterCallback() to reset a callback to the default
- weak (overridden) function.
- HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle,
- and the Callback ID.
- This function allows to reset following callbacks:
- (+) ErrorCallback : RNG Error Callback.
- (+) MspInitCallback : RNG MspInit.
- (+) MspDeInitCallback : RNG MspDeInit.
- [..]
- For specific callback ReadyDataCallback, use dedicated register callbacks:
- respectively HAL_RNG_RegisterReadyDataCallback() , HAL_RNG_UnRegisterReadyDataCallback().
- [..]
- By default, after the HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET
- all callbacks are set to the corresponding weak (overridden) functions:
- example HAL_RNG_ErrorCallback().
- Exception done for MspInit and MspDeInit functions that are respectively
- reset to the legacy weak (overridden) functions in the HAL_RNG_Init()
- and HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand).
- If not, MspInit or MspDeInit are not null, the HAL_RNG_Init() and HAL_RNG_DeInit()
- keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
- [..]
- Callbacks can be registered/unregistered in HAL_RNG_STATE_READY state only.
- Exception done MspInit/MspDeInit that can be registered/unregistered
- in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user)
- MspInit/DeInit callbacks can be used during the Init/DeInit.
- In that case first register the MspInit/MspDeInit user callbacks
- using HAL_RNG_RegisterCallback() before calling HAL_RNG_DeInit()
- or HAL_RNG_Init() function.
- [..]
- When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or
- not defined, the callback registration feature is not available
- and weak (overridden) callbacks are used.
- @endverbatim
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "stm32h7xx_hal.h"
- /** @addtogroup STM32H7xx_HAL_Driver
- * @{
- */
- #if defined (RNG)
- /** @addtogroup RNG
- * @brief RNG HAL module driver.
- * @{
- */
- #ifdef HAL_RNG_MODULE_ENABLED
- /* Private types -------------------------------------------------------------*/
- /* Private defines -----------------------------------------------------------*/
- /** @defgroup RNG_Private_Defines RNG Private Defines
- * @{
- */
- /* Health test control register information to use in CCM algorithm */
- #define RNG_HTCFG_1 0x17590ABCU /*!< Magic number */
- #if defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
- #define RNG_HTCFG 0x000CAA74U /*!< For best latency and to be compliant with NIST */
- #else /* RNG_VER_3_2 */
- #define RNG_HTCFG 0x00007274U /*!< For best latency and to be compliant with NIST */
- #endif /* RNG_VER_3_1 || RNG_VER_3_0 */
- /**
- * @}
- */
- /* Private variables ---------------------------------------------------------*/
- /* Private constants ---------------------------------------------------------*/
- /** @defgroup RNG_Private_Constants RNG Private Constants
- * @{
- */
- #define RNG_TIMEOUT_VALUE 2U
- /**
- * @}
- */
- /* Private macros ------------------------------------------------------------*/
- /* Private functions prototypes ----------------------------------------------*/
- /* Exported functions --------------------------------------------------------*/
- /** @addtogroup RNG_Exported_Functions
- * @{
- */
- /** @addtogroup RNG_Exported_Functions_Group1
- * @brief Initialization and configuration functions
- *
- @verbatim
- ===============================================================================
- ##### Initialization and configuration functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize the RNG according to the specified parameters
- in the RNG_InitTypeDef and create the associated handle
- (+) DeInitialize the RNG peripheral
- (+) Initialize the RNG MSP
- (+) DeInitialize RNG MSP
- @endverbatim
- * @{
- */
- /**
- * @brief Initializes the RNG peripheral and creates the associated handle.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
- {
- uint32_t tickstart;
- /* Check the RNG handle allocation */
- if (hrng == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
- assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
- #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
- if (hrng->State == HAL_RNG_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hrng->Lock = HAL_UNLOCKED;
- hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
- hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
- if (hrng->MspInitCallback == NULL)
- {
- hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
- }
- /* Init the low level hardware */
- hrng->MspInitCallback(hrng);
- }
- #else
- if (hrng->State == HAL_RNG_STATE_RESET)
- {
- /* Allocate lock resource and initialize it */
- hrng->Lock = HAL_UNLOCKED;
- /* Init the low level hardware */
- HAL_RNG_MspInit(hrng);
- }
- #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
- /* Change RNG peripheral state */
- hrng->State = HAL_RNG_STATE_BUSY;
- #if defined(RNG_CR_CONDRST)
- /* Disable RNG */
- __HAL_RNG_DISABLE(hrng);
- /* Clock Error Detection Configuration when CONDRT bit is set to 1 */
- MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, hrng->Init.ClockErrorDetection | RNG_CR_CONDRST);
- #if defined(RNG_VER_3_2) || defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
- /*!< magic number must be written immediately before to RNG_HTCRG */
- WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG_1);
- /* for best latency and to be compliant with NIST */
- WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG);
- #endif /* RNG_VER_3_2 || RNG_VER_3_1 || RNG_VER_3_0 */
- /* Writing bit CONDRST=0 */
- CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
- /* Get tick */
- tickstart = HAL_GetTick();
- /* Wait for conditioning reset process to be completed */
- while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
- {
- if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
- {
- /* New check to avoid false timeout detection in case of preemption */
- if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
- {
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- return HAL_ERROR;
- }
- }
- }
- #else
- /* Clock Error Detection Configuration */
- MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
- #endif /* RNG_CR_CONDRST */
- /* Enable the RNG Peripheral */
- __HAL_RNG_ENABLE(hrng);
- /* verify that no seed error */
- if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
- {
- hrng->State = HAL_RNG_STATE_ERROR;
- return HAL_ERROR;
- }
- /* Get tick */
- tickstart = HAL_GetTick();
- /* Check if data register contains valid random data */
- while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
- {
- if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
- {
- /* New check to avoid false timeout detection in case of preemption */
- if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
- {
- hrng->State = HAL_RNG_STATE_ERROR;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- return HAL_ERROR;
- }
- }
- }
- /* Initialize the RNG state */
- hrng->State = HAL_RNG_STATE_READY;
- /* Initialise the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_NONE;
- /* Return function status */
- return HAL_OK;
- }
- /**
- * @brief DeInitializes the RNG peripheral.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
- {
- #if defined(RNG_CR_CONDRST)
- uint32_t tickstart;
- #endif /* RNG_CR_CONDRST */
- /* Check the RNG handle allocation */
- if (hrng == NULL)
- {
- return HAL_ERROR;
- }
- #if defined(RNG_CR_CONDRST)
- /* Clear Clock Error Detection bit when CONDRT bit is set to 1 */
- MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST);
- /* Writing bit CONDRST=0 */
- CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
- /* Get tick */
- tickstart = HAL_GetTick();
- /* Wait for conditioning reset process to be completed */
- while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
- {
- if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
- {
- /* New check to avoid false timeout detection in case of preemption */
- if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
- {
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- return HAL_ERROR;
- }
- }
- }
- #else
- /* Clear Clock Error Detection bit */
- CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
- #endif /* RNG_CR_CONDRST */
- /* Disable the RNG Peripheral */
- CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
- /* Clear RNG interrupt status flags */
- CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
- #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
- if (hrng->MspDeInitCallback == NULL)
- {
- hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
- }
- /* DeInit the low level hardware */
- hrng->MspDeInitCallback(hrng);
- #else
- /* DeInit the low level hardware */
- HAL_RNG_MspDeInit(hrng);
- #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
- /* Update the RNG state */
- hrng->State = HAL_RNG_STATE_RESET;
- /* Initialise the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_NONE;
- /* Release Lock */
- __HAL_UNLOCK(hrng);
- /* Return the function status */
- return HAL_OK;
- }
- /**
- * @brief Initializes the RNG MSP.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval None
- */
- __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
- {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrng);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_RNG_MspInit must be implemented in the user file.
- */
- }
- /**
- * @brief DeInitializes the RNG MSP.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval None
- */
- __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
- {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrng);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_RNG_MspDeInit must be implemented in the user file.
- */
- }
- #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
- /**
- * @brief Register a User RNG Callback
- * To be used instead of the weak predefined callback
- * @param hrng RNG handle
- * @param CallbackID ID of the callback to be registered
- * This parameter can be one of the following values:
- * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
- * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
- * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
- * @param pCallback pointer to the Callback function
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID,
- pRNG_CallbackTypeDef pCallback)
- {
- HAL_StatusTypeDef status = HAL_OK;
- if (pCallback == NULL)
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- return HAL_ERROR;
- }
- if (HAL_RNG_STATE_READY == hrng->State)
- {
- switch (CallbackID)
- {
- case HAL_RNG_ERROR_CB_ID :
- hrng->ErrorCallback = pCallback;
- break;
- case HAL_RNG_MSPINIT_CB_ID :
- hrng->MspInitCallback = pCallback;
- break;
- case HAL_RNG_MSPDEINIT_CB_ID :
- hrng->MspDeInitCallback = pCallback;
- break;
- default :
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- break;
- }
- }
- else if (HAL_RNG_STATE_RESET == hrng->State)
- {
- switch (CallbackID)
- {
- case HAL_RNG_MSPINIT_CB_ID :
- hrng->MspInitCallback = pCallback;
- break;
- case HAL_RNG_MSPDEINIT_CB_ID :
- hrng->MspDeInitCallback = pCallback;
- break;
- default :
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- break;
- }
- }
- else
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- }
- return status;
- }
- /**
- * @brief Unregister an RNG Callback
- * RNG callback is redirected to the weak predefined callback
- * @param hrng RNG handle
- * @param CallbackID ID of the callback to be unregistered
- * This parameter can be one of the following values:
- * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
- * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
- * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
- {
- HAL_StatusTypeDef status = HAL_OK;
- if (HAL_RNG_STATE_READY == hrng->State)
- {
- switch (CallbackID)
- {
- case HAL_RNG_ERROR_CB_ID :
- hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
- break;
- case HAL_RNG_MSPINIT_CB_ID :
- hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
- break;
- case HAL_RNG_MSPDEINIT_CB_ID :
- hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
- break;
- default :
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- break;
- }
- }
- else if (HAL_RNG_STATE_RESET == hrng->State)
- {
- switch (CallbackID)
- {
- case HAL_RNG_MSPINIT_CB_ID :
- hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
- break;
- case HAL_RNG_MSPDEINIT_CB_ID :
- hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */
- break;
- default :
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- break;
- }
- }
- else
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- }
- return status;
- }
- /**
- * @brief Register Data Ready RNG Callback
- * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
- * @param hrng RNG handle
- * @param pCallback pointer to the Data Ready Callback function
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
- {
- HAL_StatusTypeDef status = HAL_OK;
- if (pCallback == NULL)
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- return HAL_ERROR;
- }
- /* Process locked */
- __HAL_LOCK(hrng);
- if (HAL_RNG_STATE_READY == hrng->State)
- {
- hrng->ReadyDataCallback = pCallback;
- }
- else
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- }
- /* Release Lock */
- __HAL_UNLOCK(hrng);
- return status;
- }
- /**
- * @brief UnRegister the Data Ready RNG Callback
- * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
- * @param hrng RNG handle
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Process locked */
- __HAL_LOCK(hrng);
- if (HAL_RNG_STATE_READY == hrng->State)
- {
- hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
- }
- else
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
- /* Return error status */
- status = HAL_ERROR;
- }
- /* Release Lock */
- __HAL_UNLOCK(hrng);
- return status;
- }
- #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
- /**
- * @}
- */
- /** @addtogroup RNG_Exported_Functions_Group2
- * @brief Peripheral Control functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Get the 32 bit Random number
- (+) Get the 32 bit Random number with interrupt enabled
- (+) Handle RNG interrupt request
- @endverbatim
- * @{
- */
- /**
- * @brief Generates a 32-bit random number.
- * @note This function checks value of RNG_FLAG_DRDY flag to know if valid
- * random number is available in the DR register (RNG_FLAG_DRDY flag set
- * whenever a random number is available through the RNG_DR register).
- * After transitioning from 0 to 1 (random number available),
- * RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading
- * four words from the RNG_DR register, i.e. further function calls
- * will immediately return a new u32 random number (additional words are
- * available and can be read by the application, till RNG_FLAG_DRDY flag remains high).
- * @note When no more random number data is available in DR register, RNG_FLAG_DRDY
- * flag is automatically cleared.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @param random32bit pointer to generated random number variable if successful.
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
- {
- uint32_t tickstart;
- HAL_StatusTypeDef status = HAL_OK;
- /* Process Locked */
- __HAL_LOCK(hrng);
- /* Check RNG peripheral state */
- if (hrng->State == HAL_RNG_STATE_READY)
- {
- /* Change RNG peripheral state */
- hrng->State = HAL_RNG_STATE_BUSY;
- #if defined(RNG_CR_CONDRST)
- /* Check if there is a seed error */
- if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_SEED;
- /* Reset from seed error */
- status = RNG_RecoverSeedError(hrng);
- if (status == HAL_ERROR)
- {
- return status;
- }
- }
- #endif /* RNG_CR_CONDRST */
- /* Get tick */
- tickstart = HAL_GetTick();
- /* Check if data register contains valid random data */
- while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
- {
- if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
- {
- /* New check to avoid false timeout detection in case of preemption */
- if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
- {
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- return HAL_ERROR;
- }
- }
- }
- /* Get a 32bit Random number */
- hrng->RandomNumber = hrng->Instance->DR;
- #if defined(RNG_CR_CONDRST)
- /* In case of seed error, the value available in the RNG_DR register must not
- be used as it may not have enough entropy */
- if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
- {
- /* Update the error code and status */
- hrng->ErrorCode = HAL_RNG_ERROR_SEED;
- status = HAL_ERROR;
- }
- else /* No seed error */
- {
- *random32bit = hrng->RandomNumber;
- }
- #else
- *random32bit = hrng->RandomNumber;
- #endif /* RNG_CR_CONDRST */
- hrng->State = HAL_RNG_STATE_READY;
- }
- else
- {
- hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
- status = HAL_ERROR;
- }
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- return status;
- }
- /**
- * @brief Generates a 32-bit random number in interrupt mode.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Process Locked */
- __HAL_LOCK(hrng);
- /* Check RNG peripheral state */
- if (hrng->State == HAL_RNG_STATE_READY)
- {
- /* Change RNG peripheral state */
- hrng->State = HAL_RNG_STATE_BUSY;
- /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
- __HAL_RNG_ENABLE_IT(hrng);
- }
- else
- {
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
- status = HAL_ERROR;
- }
- return status;
- }
- /**
- * @brief Handles RNG interrupt request.
- * @note In the case of a clock error, the RNG is no more able to generate
- * random numbers because the PLL48CLK clock is not correct. User has
- * to check that the clock controller is correctly configured to provide
- * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
- * The clock error has no impact on the previously generated
- * random numbers, and the RNG_DR register contents can be used.
- * @note In the case of a seed error, the generation of random numbers is
- * interrupted as long as the SECS bit is '1'. If a number is
- * available in the RNG_DR register, it must not be used because it may
- * not have enough entropy. In this case, it is recommended to clear the
- * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
- * the RNG peripheral to reinitialize and restart the RNG.
- * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
- * or CEIS are set.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval None
- */
- void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
- {
- uint32_t rngclockerror = 0U;
- uint32_t itflag = hrng->Instance->SR;
- /* RNG clock error interrupt occurred */
- if ((itflag & RNG_IT_CEI) == RNG_IT_CEI)
- {
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
- rngclockerror = 1U;
- }
- else if ((itflag & RNG_IT_SEI) == RNG_IT_SEI)
- {
- /* Check if Seed Error Current Status (SECS) is set */
- if ((itflag & RNG_FLAG_SECS) != RNG_FLAG_SECS)
- {
- /* RNG IP performed the reset automatically (auto-reset) */
- /* Clear bit SEIS */
- CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
- }
- else
- {
- /* Seed Error has not been recovered : Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_SEED;
- rngclockerror = 1U;
- /* Disable the IT */
- __HAL_RNG_DISABLE_IT(hrng);
- }
- }
- else
- {
- /* Nothing to do */
- }
- if (rngclockerror == 1U)
- {
- /* Change RNG peripheral state */
- hrng->State = HAL_RNG_STATE_ERROR;
- #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
- /* Call registered Error callback */
- hrng->ErrorCallback(hrng);
- #else
- /* Call legacy weak Error callback */
- HAL_RNG_ErrorCallback(hrng);
- #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
- /* Clear the clock error flag */
- __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
- return;
- }
- /* Check RNG data ready interrupt occurred */
- if ((itflag & RNG_IT_DRDY) == RNG_IT_DRDY)
- {
- /* Generate random number once, so disable the IT */
- __HAL_RNG_DISABLE_IT(hrng);
- /* Get the 32bit Random number (DRDY flag automatically cleared) */
- hrng->RandomNumber = hrng->Instance->DR;
- if (hrng->State != HAL_RNG_STATE_ERROR)
- {
- /* Change RNG peripheral state */
- hrng->State = HAL_RNG_STATE_READY;
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
- /* Call registered Data Ready callback */
- hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
- #else
- /* Call legacy weak Data Ready callback */
- HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
- #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
- }
- }
- }
- /**
- * @brief Read latest generated random number.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval random value
- */
- uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng)
- {
- return (hrng->RandomNumber);
- }
- /**
- * @brief Data Ready callback in non-blocking mode.
- * @note When RNG_FLAG_DRDY flag value is set, first random number has been read
- * from DR register in IRQ Handler and is provided as callback parameter.
- * Depending on valid data available in the conditioning output buffer,
- * additional words can be read by the application from DR register till
- * DRDY bit remains high.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @param random32bit generated random number.
- * @retval None
- */
- __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
- {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrng);
- UNUSED(random32bit);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_RNG_ReadyDataCallback must be implemented in the user file.
- */
- }
- /**
- * @brief RNG error callbacks.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval None
- */
- __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
- {
- /* Prevent unused argument(s) compilation warning */
- UNUSED(hrng);
- /* NOTE : This function should not be modified. When the callback is needed,
- function HAL_RNG_ErrorCallback must be implemented in the user file.
- */
- }
- /**
- * @}
- */
- /** @addtogroup RNG_Exported_Functions_Group3
- * @brief Peripheral State functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
- @endverbatim
- * @{
- */
- /**
- * @brief Returns the RNG state.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval HAL state
- */
- HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng)
- {
- return hrng->State;
- }
- /**
- * @brief Return the RNG handle error code.
- * @param hrng: pointer to a RNG_HandleTypeDef structure.
- * @retval RNG Error Code
- */
- uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng)
- {
- /* Return RNG Error Code */
- return hrng->ErrorCode;
- }
- /**
- * @}
- */
- /**
- * @}
- */
- #if defined(RNG_CR_CONDRST)
- /* Private functions ---------------------------------------------------------*/
- /** @addtogroup RNG_Private_Functions
- * @{
- */
- /**
- * @brief RNG sequence to recover from a seed error
- * @param hrng pointer to a RNG_HandleTypeDef structure.
- * @retval HAL status
- */
- HAL_StatusTypeDef RNG_RecoverSeedError(RNG_HandleTypeDef *hrng)
- {
- __IO uint32_t count = 0U;
- /*Check if seed error current status (SECS)is set */
- if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) == RESET)
- {
- /* RNG performed the reset automatically (auto-reset) */
- /* Clear bit SEIS */
- CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
- }
- else /* Sequence to fully recover from a seed error*/
- {
- /* Writing bit CONDRST=1*/
- SET_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
- /* Writing bit CONDRST=0*/
- CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
- /* Wait for conditioning reset process to be completed */
- count = RNG_TIMEOUT_VALUE;
- do
- {
- count-- ;
- if (count == 0U)
- {
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT;
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
- /* Call registered Error callback */
- hrng->ErrorCallback(hrng);
- #else
- /* Call legacy weak Error callback */
- HAL_RNG_ErrorCallback(hrng);
- #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
- return HAL_ERROR;
- }
- } while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST));
- if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
- {
- /* Clear bit SEIS */
- CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
- }
- /* Wait for SECS to be cleared */
- count = RNG_TIMEOUT_VALUE;
- do
- {
- count-- ;
- if (count == 0U)
- {
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT;
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
- /* Call registered Error callback */
- hrng->ErrorCallback(hrng);
- #else
- /* Call legacy weak Error callback */
- HAL_RNG_ErrorCallback(hrng);
- #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
- return HAL_ERROR;
- }
- } while (HAL_IS_BIT_SET(hrng->Instance->SR, RNG_FLAG_SECS));
- }
- /* Update the error code */
- hrng->ErrorCode &= ~ HAL_RNG_ERROR_SEED;
- return HAL_OK;
- }
- /**
- * @}
- */
- #endif /* RNG_CR_CONDRST */
- #endif /* HAL_RNG_MODULE_ENABLED */
- /**
- * @}
- */
- #endif /* RNG */
- /**
- * @}
- */
|