1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132 |
- /**
- ******************************************************************************
- * @file stm32l4xx_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 "stm32l4xx_hal.h"
- /** @addtogroup STM32L4xx_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 /*!< Recommended value for NIST compliance, refer to application note AN4230 */
- #else /* RNG_VER_3_2 */
- #define RNG_HTCFG 0x00007274U /*!< Recommended value for NIST compliance, refer to application note AN4230 */
- #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;
- #if defined(RNG_CR_CONDRST)
- uint32_t cr_value;
- #endif /* RNG_CR_CONDRST */
- /* Check the RNG handle allocation */
- if (hrng == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
- #if defined(RNG_CR_CED)
- assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
- #endif /* RNG_CR_CED */
- #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);
- /* RNG CR register configuration. Set value in CR register for CONFIG 1, CONFIG 2 and CONFIG 3 values */
- cr_value = (uint32_t)(RNG_CR_CONFIG_VAL);
- /* Configuration of
- - Clock Error Detection
- - CONFIG1, CONFIG2, CONFIG3 fields
- when CONDRT bit is set to 1 */
- MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST | RNG_CR_RNG_CONFIG1
- | RNG_CR_RNG_CONFIG2 | RNG_CR_RNG_CONFIG3,
- (uint32_t)(RNG_CR_CONDRST | hrng->Init.ClockErrorDetection | cr_value));
- #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);
- /* Recommended value for NIST compliance, refer to application note AN4230 */
- 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
- #if defined(RNG_CR_CED)
- /* Clock Error Detection Configuration */
- MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
- #endif /* RNG_CR_CED */
- #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_DRDY) != SET)
- {
- 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) != SET)
- {
- 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
- #if defined(RNG_CR_CED)
- /* Clear Clock Error Detection bit */
- CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
- #endif /* 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 When several random data are output at the same time in an output buffer,
- * 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).
- * When no more random number data is available in DR register, RNG_FLAG_DRDY
- * flag is automatically cleared.
- * When random number are out on a single sample basis, each time the random
- * number data is read the 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 Returns generated random number in polling mode (Obsolete)
- * Use HAL_RNG_GenerateRandomNumber() API instead.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval Random value
- */
- uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
- {
- if (HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
- {
- return hrng->RandomNumber;
- }
- else
- {
- return 0U;
- }
- }
- /**
- * @brief Returns a 32-bit random number with interrupt enabled (Obsolete),
- * Use HAL_RNG_GenerateRandomNumber_IT() API instead.
- * @param hrng pointer to a RNG_HandleTypeDef structure that contains
- * the configuration information for RNG.
- * @retval 32-bit random number
- */
- uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
- {
- uint32_t random32bit = 0U;
- /* Process locked */
- __HAL_LOCK(hrng);
- /* Change RNG peripheral state */
- hrng->State = HAL_RNG_STATE_BUSY;
- /* Get a 32bit Random number */
- random32bit = hrng->Instance->DR;
- /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
- __HAL_RNG_ENABLE_IT(hrng);
- /* Return the 32 bit random number */
- return random32bit;
- }
- /**
- * @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 several random data are output at the same time in an output buffer,
- * 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 */
- /**
- * @}
- */
|