![]() |
|
|||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |