You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

928 lines
28 KiB

  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_rng.c
  4. * @author MCD Application Team
  5. * @brief RNG HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the Random Number Generator (RNG) peripheral:
  8. * + Initialization and configuration functions
  9. * + Peripheral Control functions
  10. * + Peripheral State functions
  11. *
  12. @verbatim
  13. ==============================================================================
  14. ##### How to use this driver #####
  15. ==============================================================================
  16. [..]
  17. The RNG HAL driver can be used as follows:
  18. (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro
  19. in HAL_RNG_MspInit().
  20. (#) Activate the RNG peripheral using HAL_RNG_Init() function.
  21. (#) Wait until the 32 bit Random Number Generator contains a valid
  22. random data using (polling/interrupt) mode.
  23. (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function.
  24. ##### Callback registration #####
  25. ==================================
  26. [..]
  27. The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1
  28. allows the user to configure dynamically the driver callbacks.
  29. [..]
  30. Use Function @ref HAL_RNG_RegisterCallback() to register a user callback.
  31. Function @ref HAL_RNG_RegisterCallback() allows to register following callbacks:
  32. (+) ErrorCallback : RNG Error Callback.
  33. (+) MspInitCallback : RNG MspInit.
  34. (+) MspDeInitCallback : RNG MspDeInit.
  35. This function takes as parameters the HAL peripheral handle, the Callback ID
  36. and a pointer to the user callback function.
  37. [..]
  38. Use function @ref HAL_RNG_UnRegisterCallback() to reset a callback to the default
  39. weak (surcharged) function.
  40. @ref HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle,
  41. and the Callback ID.
  42. This function allows to reset following callbacks:
  43. (+) ErrorCallback : RNG Error Callback.
  44. (+) MspInitCallback : RNG MspInit.
  45. (+) MspDeInitCallback : RNG MspDeInit.
  46. [..]
  47. For specific callback ReadyDataCallback, use dedicated register callbacks:
  48. respectively @ref HAL_RNG_RegisterReadyDataCallback() , @ref HAL_RNG_UnRegisterReadyDataCallback().
  49. [..]
  50. By default, after the @ref HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET
  51. all callbacks are set to the corresponding weak (surcharged) functions:
  52. example @ref HAL_RNG_ErrorCallback().
  53. Exception done for MspInit and MspDeInit functions that are respectively
  54. reset to the legacy weak (surcharged) functions in the @ref HAL_RNG_Init()
  55. and @ref HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand).
  56. If not, MspInit or MspDeInit are not null, the @ref HAL_RNG_Init() and @ref HAL_RNG_DeInit()
  57. keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
  58. [..]
  59. Callbacks can be registered/unregistered in HAL_RNG_STATE_READY state only.
  60. Exception done MspInit/MspDeInit that can be registered/unregistered
  61. in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user)
  62. MspInit/DeInit callbacks can be used during the Init/DeInit.
  63. In that case first register the MspInit/MspDeInit user callbacks
  64. using @ref HAL_RNG_RegisterCallback() before calling @ref HAL_RNG_DeInit()
  65. or @ref HAL_RNG_Init() function.
  66. [..]
  67. When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or
  68. not defined, the callback registration feature is not available
  69. and weak (surcharged) callbacks are used.
  70. @endverbatim
  71. ******************************************************************************
  72. * @attention
  73. *
  74. * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
  75. * All rights reserved.</center></h2>
  76. *
  77. * This software component is licensed by ST under BSD 3-Clause license,
  78. * the "License"; You may not use this file except in compliance with the
  79. * License. You may obtain a copy of the License at:
  80. * opensource.org/licenses/BSD-3-Clause
  81. *
  82. ******************************************************************************
  83. */
  84. /* Includes ------------------------------------------------------------------*/
  85. #include "stm32h7xx_hal.h"
  86. /** @addtogroup STM32H7xx_HAL_Driver
  87. * @{
  88. */
  89. #if defined (RNG)
  90. /** @addtogroup RNG
  91. * @brief RNG HAL module driver.
  92. * @{
  93. */
  94. #ifdef HAL_RNG_MODULE_ENABLED
  95. /* Private types -------------------------------------------------------------*/
  96. /* Private defines -----------------------------------------------------------*/
  97. /** @defgroup RNG_Private_Defines
  98. * @{
  99. */
  100. /* Health test control register information to use in CCM algorithm */
  101. #define RNG_HTCFG_1 0x17590ABCU /*!< magic number */
  102. #if defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
  103. #define RNG_HTCFG 0x000CAA74U /*!< for best latency and To be compliant with NIST */
  104. #else /*RNG_VER_3_2*/
  105. #define RNG_HTCFG 0x00007274U /*!< for best latency and To be compliant with NIST */
  106. #endif
  107. /**
  108. * @}
  109. */
  110. /* Private variables ---------------------------------------------------------*/
  111. /* Private constants ---------------------------------------------------------*/
  112. /** @defgroup RNG_Private_Constants RNG Private Constants
  113. * @{
  114. */
  115. #define RNG_TIMEOUT_VALUE 2U
  116. /**
  117. * @}
  118. */
  119. /* Private macros ------------------------------------------------------------*/
  120. /* Private functions prototypes ----------------------------------------------*/
  121. /* Private functions ---------------------------------------------------------*/
  122. /* Exported functions --------------------------------------------------------*/
  123. /** @addtogroup RNG_Exported_Functions
  124. * @{
  125. */
  126. /** @addtogroup RNG_Exported_Functions_Group1
  127. * @brief Initialization and configuration functions
  128. *
  129. @verbatim
  130. ===============================================================================
  131. ##### Initialization and configuration functions #####
  132. ===============================================================================
  133. [..] This section provides functions allowing to:
  134. (+) Initialize the RNG according to the specified parameters
  135. in the RNG_InitTypeDef and create the associated handle
  136. (+) DeInitialize the RNG peripheral
  137. (+) Initialize the RNG MSP
  138. (+) DeInitialize RNG MSP
  139. @endverbatim
  140. * @{
  141. */
  142. /**
  143. * @brief Initializes the RNG peripheral and creates the associated handle.
  144. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  145. * the configuration information for RNG.
  146. * @retval HAL status
  147. */
  148. HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
  149. {
  150. uint32_t tickstart;
  151. /* Check the RNG handle allocation */
  152. if (hrng == NULL)
  153. {
  154. return HAL_ERROR;
  155. }
  156. /* Check the parameters */
  157. assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
  158. assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
  159. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  160. if (hrng->State == HAL_RNG_STATE_RESET)
  161. {
  162. /* Allocate lock resource and initialize it */
  163. hrng->Lock = HAL_UNLOCKED;
  164. hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
  165. hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
  166. if (hrng->MspInitCallback == NULL)
  167. {
  168. hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
  169. }
  170. /* Init the low level hardware */
  171. hrng->MspInitCallback(hrng);
  172. }
  173. #else
  174. if (hrng->State == HAL_RNG_STATE_RESET)
  175. {
  176. /* Allocate lock resource and initialize it */
  177. hrng->Lock = HAL_UNLOCKED;
  178. /* Init the low level hardware */
  179. HAL_RNG_MspInit(hrng);
  180. }
  181. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  182. /* Change RNG peripheral state */
  183. hrng->State = HAL_RNG_STATE_BUSY;
  184. #if defined(RNG_CR_CONDRST)
  185. /* Disable RNG */
  186. __HAL_RNG_DISABLE(hrng);
  187. /* Clock Error Detection Configuration when CONDRT bit is set to 1 */
  188. MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, hrng->Init.ClockErrorDetection | RNG_CR_CONDRST);
  189. #if defined(RNG_VER_3_2) || defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
  190. /*!< magic number must be written immediately before to RNG_HTCRG */
  191. WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG_1);
  192. /* for best latency and to be compliant with NIST */
  193. WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG);
  194. #endif
  195. /* Writing bits CONDRST=0*/
  196. CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
  197. /* Get tick */
  198. tickstart = HAL_GetTick();
  199. /* Wait for conditioning reset process to be completed */
  200. while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
  201. {
  202. if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
  203. {
  204. hrng->State = HAL_RNG_STATE_READY;
  205. hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
  206. return HAL_ERROR;
  207. }
  208. }
  209. #else
  210. /* Clock Error Detection Configuration */
  211. MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
  212. #endif /* end of RNG_CR_CONDRST */
  213. /* Enable the RNG Peripheral */
  214. __HAL_RNG_ENABLE(hrng);
  215. /* verify that no seed error */
  216. if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
  217. {
  218. hrng->State = HAL_RNG_STATE_ERROR;
  219. return HAL_ERROR;
  220. }
  221. /* Get tick */
  222. tickstart = HAL_GetTick();
  223. /* Check if data register contains valid random data */
  224. while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
  225. {
  226. if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
  227. {
  228. hrng->State = HAL_RNG_STATE_ERROR;
  229. hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
  230. return HAL_ERROR;
  231. }
  232. }
  233. /* Initialize the RNG state */
  234. hrng->State = HAL_RNG_STATE_READY;
  235. /* Initialise the error code */
  236. hrng->ErrorCode = HAL_RNG_ERROR_NONE;
  237. /* Return function status */
  238. return HAL_OK;
  239. }
  240. /**
  241. * @brief DeInitializes the RNG peripheral.
  242. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  243. * the configuration information for RNG.
  244. * @retval HAL status
  245. */
  246. HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
  247. {
  248. #if defined(RNG_CR_CONDRST)
  249. uint32_t tickstart;
  250. #endif /* RNG_CR_CONDRST */
  251. /* Check the RNG handle allocation */
  252. if (hrng == NULL)
  253. {
  254. return HAL_ERROR;
  255. }
  256. #if defined(RNG_CR_CONDRST)
  257. /* Clear Clock Error Detection bit when CONDRT bit is set to 1 */
  258. MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST);
  259. /* Writing bits CONDRST=0*/
  260. CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
  261. /* Get tick */
  262. tickstart = HAL_GetTick();
  263. /* Wait for conditioning reset process to be completed */
  264. while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
  265. {
  266. if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
  267. {
  268. hrng->State = HAL_RNG_STATE_READY;
  269. hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
  270. /* Process Unlocked */
  271. __HAL_UNLOCK(hrng);
  272. return HAL_ERROR;
  273. }
  274. }
  275. #else
  276. /* Clear Clock Error Detection bit */
  277. CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
  278. #endif /* RNG_CR_CONDRST */
  279. /* Disable the RNG Peripheral */
  280. CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
  281. /* Clear RNG interrupt status flags */
  282. CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
  283. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  284. if (hrng->MspDeInitCallback == NULL)
  285. {
  286. hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
  287. }
  288. /* DeInit the low level hardware */
  289. hrng->MspDeInitCallback(hrng);
  290. #else
  291. /* DeInit the low level hardware */
  292. HAL_RNG_MspDeInit(hrng);
  293. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  294. /* Update the RNG state */
  295. hrng->State = HAL_RNG_STATE_RESET;
  296. /* Initialise the error code */
  297. hrng->ErrorCode = HAL_RNG_ERROR_NONE;
  298. /* Release Lock */
  299. __HAL_UNLOCK(hrng);
  300. /* Return the function status */
  301. return HAL_OK;
  302. }
  303. /**
  304. * @brief Initializes the RNG MSP.
  305. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  306. * the configuration information for RNG.
  307. * @retval None
  308. */
  309. __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
  310. {
  311. /* Prevent unused argument(s) compilation warning */
  312. UNUSED(hrng);
  313. /* NOTE : This function should not be modified. When the callback is needed,
  314. function HAL_RNG_MspInit must be implemented in the user file.
  315. */
  316. }
  317. /**
  318. * @brief DeInitializes the RNG MSP.
  319. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  320. * the configuration information for RNG.
  321. * @retval None
  322. */
  323. __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
  324. {
  325. /* Prevent unused argument(s) compilation warning */
  326. UNUSED(hrng);
  327. /* NOTE : This function should not be modified. When the callback is needed,
  328. function HAL_RNG_MspDeInit must be implemented in the user file.
  329. */
  330. }
  331. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  332. /**
  333. * @brief Register a User RNG Callback
  334. * To be used instead of the weak predefined callback
  335. * @param hrng RNG handle
  336. * @param CallbackID ID of the callback to be registered
  337. * This parameter can be one of the following values:
  338. * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
  339. * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
  340. * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
  341. * @param pCallback pointer to the Callback function
  342. * @retval HAL status
  343. */
  344. HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
  345. {
  346. HAL_StatusTypeDef status = HAL_OK;
  347. if (pCallback == NULL)
  348. {
  349. /* Update the error code */
  350. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  351. return HAL_ERROR;
  352. }
  353. /* Process locked */
  354. __HAL_LOCK(hrng);
  355. if (HAL_RNG_STATE_READY == hrng->State)
  356. {
  357. switch (CallbackID)
  358. {
  359. case HAL_RNG_ERROR_CB_ID :
  360. hrng->ErrorCallback = pCallback;
  361. break;
  362. case HAL_RNG_MSPINIT_CB_ID :
  363. hrng->MspInitCallback = pCallback;
  364. break;
  365. case HAL_RNG_MSPDEINIT_CB_ID :
  366. hrng->MspDeInitCallback = pCallback;
  367. break;
  368. default :
  369. /* Update the error code */
  370. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  371. /* Return error status */
  372. status = HAL_ERROR;
  373. break;
  374. }
  375. }
  376. else if (HAL_RNG_STATE_RESET == hrng->State)
  377. {
  378. switch (CallbackID)
  379. {
  380. case HAL_RNG_MSPINIT_CB_ID :
  381. hrng->MspInitCallback = pCallback;
  382. break;
  383. case HAL_RNG_MSPDEINIT_CB_ID :
  384. hrng->MspDeInitCallback = pCallback;
  385. break;
  386. default :
  387. /* Update the error code */
  388. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  389. /* Return error status */
  390. status = HAL_ERROR;
  391. break;
  392. }
  393. }
  394. else
  395. {
  396. /* Update the error code */
  397. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  398. /* Return error status */
  399. status = HAL_ERROR;
  400. }
  401. /* Release Lock */
  402. __HAL_UNLOCK(hrng);
  403. return status;
  404. }
  405. /**
  406. * @brief Unregister an RNG Callback
  407. * RNG callabck is redirected to the weak predefined callback
  408. * @param hrng RNG handle
  409. * @param CallbackID ID of the callback to be unregistered
  410. * This parameter can be one of the following values:
  411. * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
  412. * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
  413. * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
  414. * @retval HAL status
  415. */
  416. HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
  417. {
  418. HAL_StatusTypeDef status = HAL_OK;
  419. /* Process locked */
  420. __HAL_LOCK(hrng);
  421. if (HAL_RNG_STATE_READY == hrng->State)
  422. {
  423. switch (CallbackID)
  424. {
  425. case HAL_RNG_ERROR_CB_ID :
  426. hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
  427. break;
  428. case HAL_RNG_MSPINIT_CB_ID :
  429. hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
  430. break;
  431. case HAL_RNG_MSPDEINIT_CB_ID :
  432. hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
  433. break;
  434. default :
  435. /* Update the error code */
  436. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  437. /* Return error status */
  438. status = HAL_ERROR;
  439. break;
  440. }
  441. }
  442. else if (HAL_RNG_STATE_RESET == hrng->State)
  443. {
  444. switch (CallbackID)
  445. {
  446. case HAL_RNG_MSPINIT_CB_ID :
  447. hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
  448. break;
  449. case HAL_RNG_MSPDEINIT_CB_ID :
  450. hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */
  451. break;
  452. default :
  453. /* Update the error code */
  454. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  455. /* Return error status */
  456. status = HAL_ERROR;
  457. break;
  458. }
  459. }
  460. else
  461. {
  462. /* Update the error code */
  463. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  464. /* Return error status */
  465. status = HAL_ERROR;
  466. }
  467. /* Release Lock */
  468. __HAL_UNLOCK(hrng);
  469. return status;
  470. }
  471. /**
  472. * @brief Register Data Ready RNG Callback
  473. * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
  474. * @param hrng RNG handle
  475. * @param pCallback pointer to the Data Ready Callback function
  476. * @retval HAL status
  477. */
  478. HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
  479. {
  480. HAL_StatusTypeDef status = HAL_OK;
  481. if (pCallback == NULL)
  482. {
  483. /* Update the error code */
  484. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  485. return HAL_ERROR;
  486. }
  487. /* Process locked */
  488. __HAL_LOCK(hrng);
  489. if (HAL_RNG_STATE_READY == hrng->State)
  490. {
  491. hrng->ReadyDataCallback = pCallback;
  492. }
  493. else
  494. {
  495. /* Update the error code */
  496. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  497. /* Return error status */
  498. status = HAL_ERROR;
  499. }
  500. /* Release Lock */
  501. __HAL_UNLOCK(hrng);
  502. return status;
  503. }
  504. /**
  505. * @brief UnRegister the Data Ready RNG Callback
  506. * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
  507. * @param hrng RNG handle
  508. * @retval HAL status
  509. */
  510. HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
  511. {
  512. HAL_StatusTypeDef status = HAL_OK;
  513. /* Process locked */
  514. __HAL_LOCK(hrng);
  515. if (HAL_RNG_STATE_READY == hrng->State)
  516. {
  517. hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
  518. }
  519. else
  520. {
  521. /* Update the error code */
  522. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  523. /* Return error status */
  524. status = HAL_ERROR;
  525. }
  526. /* Release Lock */
  527. __HAL_UNLOCK(hrng);
  528. return status;
  529. }
  530. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  531. /**
  532. * @}
  533. */
  534. /** @addtogroup RNG_Exported_Functions_Group2
  535. * @brief Peripheral Control functions
  536. *
  537. @verbatim
  538. ===============================================================================
  539. ##### Peripheral Control functions #####
  540. ===============================================================================
  541. [..] This section provides functions allowing to:
  542. (+) Get the 32 bit Random number
  543. (+) Get the 32 bit Random number with interrupt enabled
  544. (+) Handle RNG interrupt request
  545. @endverbatim
  546. * @{
  547. */
  548. /**
  549. * @brief Generates a 32-bit random number.
  550. * @note This function checks value of RNG_FLAG_DRDY flag to know if valid
  551. * random number is available in the DR register (RNG_FLAG_DRDY flag set
  552. * whenever a random number is available through the RNG_DR register).
  553. * After transitioning from 0 to 1 (random number available),
  554. * RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading
  555. * four words from the RNG_DR register, i.e. further function calls
  556. * will immediately return a new u32 random number (additional words are
  557. * available and can be read by the application, till RNG_FLAG_DRDY flag remains high).
  558. * @note When no more random number data is available in DR register, RNG_FLAG_DRDY
  559. * flag is automatically cleared.
  560. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  561. * the configuration information for RNG.
  562. * @param random32bit pointer to generated random number variable if successful.
  563. * @retval HAL status
  564. */
  565. HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
  566. {
  567. uint32_t tickstart;
  568. HAL_StatusTypeDef status = HAL_OK;
  569. /* Process Locked */
  570. __HAL_LOCK(hrng);
  571. /* Check RNG peripheral state */
  572. if (hrng->State == HAL_RNG_STATE_READY)
  573. {
  574. /* Change RNG peripheral state */
  575. hrng->State = HAL_RNG_STATE_BUSY;
  576. /* Get tick */
  577. tickstart = HAL_GetTick();
  578. /* Check if data register contains valid random data */
  579. while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
  580. {
  581. if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
  582. {
  583. hrng->State = HAL_RNG_STATE_READY;
  584. hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
  585. /* Process Unlocked */
  586. __HAL_UNLOCK(hrng);
  587. return HAL_ERROR;
  588. }
  589. }
  590. /* Get a 32bit Random number */
  591. hrng->RandomNumber = hrng->Instance->DR;
  592. *random32bit = hrng->RandomNumber;
  593. hrng->State = HAL_RNG_STATE_READY;
  594. }
  595. else
  596. {
  597. hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
  598. status = HAL_ERROR;
  599. }
  600. /* Process Unlocked */
  601. __HAL_UNLOCK(hrng);
  602. return status;
  603. }
  604. /**
  605. * @brief Generates a 32-bit random number in interrupt mode.
  606. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  607. * the configuration information for RNG.
  608. * @retval HAL status
  609. */
  610. HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
  611. {
  612. HAL_StatusTypeDef status = HAL_OK;
  613. /* Process Locked */
  614. __HAL_LOCK(hrng);
  615. /* Check RNG peripheral state */
  616. if (hrng->State == HAL_RNG_STATE_READY)
  617. {
  618. /* Change RNG peripheral state */
  619. hrng->State = HAL_RNG_STATE_BUSY;
  620. /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
  621. __HAL_RNG_ENABLE_IT(hrng);
  622. }
  623. else
  624. {
  625. /* Process Unlocked */
  626. __HAL_UNLOCK(hrng);
  627. hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
  628. status = HAL_ERROR;
  629. }
  630. return status;
  631. }
  632. /**
  633. * @brief Handles RNG interrupt request.
  634. * @note In the case of a clock error, the RNG is no more able to generate
  635. * random numbers because the PLL48CLK clock is not correct. User has
  636. * to check that the clock controller is correctly configured to provide
  637. * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
  638. * The clock error has no impact on the previously generated
  639. * random numbers, and the RNG_DR register contents can be used.
  640. * @note In the case of a seed error, the generation of random numbers is
  641. * interrupted as long as the SECS bit is '1'. If a number is
  642. * available in the RNG_DR register, it must not be used because it may
  643. * not have enough entropy. In this case, it is recommended to clear the
  644. * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
  645. * the RNG peripheral to reinitialize and restart the RNG.
  646. * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
  647. * or CEIS are set.
  648. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  649. * the configuration information for RNG.
  650. * @retval None
  651. */
  652. void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
  653. {
  654. uint32_t rngclockerror = 0U;
  655. /* RNG clock error interrupt occurred */
  656. if (__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET)
  657. {
  658. /* Update the error code */
  659. hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
  660. rngclockerror = 1U;
  661. }
  662. else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
  663. {
  664. /* Update the error code */
  665. hrng->ErrorCode = HAL_RNG_ERROR_SEED;
  666. rngclockerror = 1U;
  667. }
  668. else
  669. {
  670. /* Nothing to do */
  671. }
  672. if (rngclockerror == 1U)
  673. {
  674. /* Change RNG peripheral state */
  675. hrng->State = HAL_RNG_STATE_ERROR;
  676. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  677. /* Call registered Error callback */
  678. hrng->ErrorCallback(hrng);
  679. #else
  680. /* Call legacy weak Error callback */
  681. HAL_RNG_ErrorCallback(hrng);
  682. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  683. /* Clear the clock error flag */
  684. __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
  685. }
  686. /* Check RNG data ready interrupt occurred */
  687. if (__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
  688. {
  689. /* Generate random number once, so disable the IT */
  690. __HAL_RNG_DISABLE_IT(hrng);
  691. /* Get the 32bit Random number (DRDY flag automatically cleared) */
  692. hrng->RandomNumber = hrng->Instance->DR;
  693. if (hrng->State != HAL_RNG_STATE_ERROR)
  694. {
  695. /* Change RNG peripheral state */
  696. hrng->State = HAL_RNG_STATE_READY;
  697. /* Process Unlocked */
  698. __HAL_UNLOCK(hrng);
  699. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  700. /* Call registered Data Ready callback */
  701. hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
  702. #else
  703. /* Call legacy weak Data Ready callback */
  704. HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
  705. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  706. }
  707. }
  708. }
  709. /**
  710. * @brief Read latest generated random number.
  711. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  712. * the configuration information for RNG.
  713. * @retval random value
  714. */
  715. uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
  716. {
  717. return (hrng->RandomNumber);
  718. }
  719. /**
  720. * @brief Data Ready callback in non-blocking mode.
  721. * @note When RNG_FLAG_DRDY flag value is set, first random number has been read
  722. * from DR register in IRQ Handler and is provided as callback parameter.
  723. * Depending on valid data available in the conditioning output buffer,
  724. * additional words can be read by the application from DR register till
  725. * DRDY bit remains high.
  726. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  727. * the configuration information for RNG.
  728. * @param random32bit generated random number.
  729. * @retval None
  730. */
  731. __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
  732. {
  733. /* Prevent unused argument(s) compilation warning */
  734. UNUSED(hrng);
  735. UNUSED(random32bit);
  736. /* NOTE : This function should not be modified. When the callback is needed,
  737. function HAL_RNG_ReadyDataCallback must be implemented in the user file.
  738. */
  739. }
  740. /**
  741. * @brief RNG error callbacks.
  742. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  743. * the configuration information for RNG.
  744. * @retval None
  745. */
  746. __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
  747. {
  748. /* Prevent unused argument(s) compilation warning */
  749. UNUSED(hrng);
  750. /* NOTE : This function should not be modified. When the callback is needed,
  751. function HAL_RNG_ErrorCallback must be implemented in the user file.
  752. */
  753. }
  754. /**
  755. * @}
  756. */
  757. /** @addtogroup RNG_Exported_Functions_Group3
  758. * @brief Peripheral State functions
  759. *
  760. @verbatim
  761. ===============================================================================
  762. ##### Peripheral State functions #####
  763. ===============================================================================
  764. [..]
  765. This subsection permits to get in run-time the status of the peripheral
  766. and the data flow.
  767. @endverbatim
  768. * @{
  769. */
  770. /**
  771. * @brief Returns the RNG state.
  772. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  773. * the configuration information for RNG.
  774. * @retval HAL state
  775. */
  776. HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
  777. {
  778. return hrng->State;
  779. }
  780. /**
  781. * @brief Return the RNG handle error code.
  782. * @param hrng: pointer to a RNG_HandleTypeDef structure.
  783. * @retval RNG Error Code
  784. */
  785. uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
  786. {
  787. /* Return RNG Error Code */
  788. return hrng->ErrorCode;
  789. }
  790. /**
  791. * @}
  792. */
  793. /**
  794. * @}
  795. */
  796. #endif /* HAL_RNG_MODULE_ENABLED */
  797. /**
  798. * @}
  799. */
  800. #endif /* RNG */
  801. /**
  802. * @}
  803. */
  804. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/