stm32h7xx_hal_rng.c 33 KB

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