stm32l4xx_hal_rng.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. /**
  2. ******************************************************************************
  3. * @file stm32l4xx_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 (surcharged) 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 (surcharged) functions:
  63. example HAL_RNG_ErrorCallback().
  64. Exception done for MspInit and MspDeInit functions that are respectively
  65. reset to the legacy weak (surcharged) 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 (surcharged) callbacks are used.
  81. @endverbatim
  82. ******************************************************************************
  83. */
  84. /* Includes ------------------------------------------------------------------*/
  85. #include "stm32l4xx_hal.h"
  86. /** @addtogroup STM32L4xx_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. /* Private variables ---------------------------------------------------------*/
  98. /* Private constants ---------------------------------------------------------*/
  99. /** @defgroup RNG_Private_Constants RNG Private Constants
  100. * @{
  101. */
  102. #define RNG_TIMEOUT_VALUE 2U
  103. /**
  104. * @}
  105. */
  106. /* Private macros ------------------------------------------------------------*/
  107. /* Private functions prototypes ----------------------------------------------*/
  108. /* Private functions ---------------------------------------------------------*/
  109. /* Exported functions --------------------------------------------------------*/
  110. /** @addtogroup RNG_Exported_Functions
  111. * @{
  112. */
  113. /** @addtogroup RNG_Exported_Functions_Group1
  114. * @brief Initialization and configuration functions
  115. *
  116. @verbatim
  117. ===============================================================================
  118. ##### Initialization and configuration functions #####
  119. ===============================================================================
  120. [..] This section provides functions allowing to:
  121. (+) Initialize the RNG according to the specified parameters
  122. in the RNG_InitTypeDef and create the associated handle
  123. (+) DeInitialize the RNG peripheral
  124. (+) Initialize the RNG MSP
  125. (+) DeInitialize RNG MSP
  126. @endverbatim
  127. * @{
  128. */
  129. /**
  130. * @brief Initializes the RNG peripheral and creates the associated handle.
  131. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  132. * the configuration information for RNG.
  133. * @retval HAL status
  134. */
  135. HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
  136. {
  137. uint32_t tickstart;
  138. #if defined(RNG_CR_CONDRST)
  139. uint32_t cr_value;
  140. #endif /* RNG_CR_CONDRST */
  141. /* Check the RNG handle allocation */
  142. if (hrng == NULL)
  143. {
  144. return HAL_ERROR;
  145. }
  146. /* Check the parameters */
  147. assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
  148. #if defined(RNG_CR_CED)
  149. assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
  150. #endif /* defined(RNG_CR_CED) */
  151. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  152. if (hrng->State == HAL_RNG_STATE_RESET)
  153. {
  154. /* Allocate lock resource and initialize it */
  155. hrng->Lock = HAL_UNLOCKED;
  156. hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
  157. hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
  158. if (hrng->MspInitCallback == NULL)
  159. {
  160. hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
  161. }
  162. /* Init the low level hardware */
  163. hrng->MspInitCallback(hrng);
  164. }
  165. #else
  166. if (hrng->State == HAL_RNG_STATE_RESET)
  167. {
  168. /* Allocate lock resource and initialize it */
  169. hrng->Lock = HAL_UNLOCKED;
  170. /* Init the low level hardware */
  171. HAL_RNG_MspInit(hrng);
  172. }
  173. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  174. /* Change RNG peripheral state */
  175. hrng->State = HAL_RNG_STATE_BUSY;
  176. #if defined(RNG_CR_CONDRST)
  177. /* Disable RNG */
  178. __HAL_RNG_DISABLE(hrng);
  179. /* RNG CR register configuration. Set value in CR register for CONFIG 1, CONFIG 2 and CONFIG 3 values */
  180. cr_value = (uint32_t) (RNG_CR_CONFIG_VAL);
  181. /* Configuration of
  182. - Clock Error Detection
  183. - CONFIG1, CONFIG2, CONFIG3 fields
  184. when CONDRT bit is set to 1 */
  185. MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST | RNG_CR_RNG_CONFIG1
  186. | RNG_CR_RNG_CONFIG2 | RNG_CR_RNG_CONFIG3,
  187. (uint32_t) (RNG_CR_CONDRST | hrng->Init.ClockErrorDetection | cr_value));
  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 bits 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. #if defined(RNG_CR_CED)
  214. /* Clock Error Detection Configuration */
  215. MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
  216. #endif /* defined(RNG_CR_CED) */
  217. #endif /* end of RNG_CR_CONDRST */
  218. /* Enable the RNG Peripheral */
  219. __HAL_RNG_ENABLE(hrng);
  220. /* verify that no seed error */
  221. if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
  222. {
  223. hrng->State = HAL_RNG_STATE_ERROR;
  224. return HAL_ERROR;
  225. }
  226. /* Get tick */
  227. tickstart = HAL_GetTick();
  228. /* Check if data register contains valid random data */
  229. while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
  230. {
  231. if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
  232. {
  233. /* New check to avoid false timeout detection in case of preemption */
  234. if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
  235. {
  236. hrng->State = HAL_RNG_STATE_ERROR;
  237. hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
  238. return HAL_ERROR;
  239. }
  240. }
  241. }
  242. /* Initialize the RNG state */
  243. hrng->State = HAL_RNG_STATE_READY;
  244. /* Initialise the error code */
  245. hrng->ErrorCode = HAL_RNG_ERROR_NONE;
  246. /* Return function status */
  247. return HAL_OK;
  248. }
  249. /**
  250. * @brief DeInitializes the RNG peripheral.
  251. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  252. * the configuration information for RNG.
  253. * @retval HAL status
  254. */
  255. HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
  256. {
  257. #if defined(RNG_CR_CONDRST)
  258. uint32_t tickstart;
  259. #endif
  260. /* Check the RNG handle allocation */
  261. if (hrng == NULL)
  262. {
  263. return HAL_ERROR;
  264. }
  265. #if defined(RNG_CR_CONDRST)
  266. /* Clear Clock Error Detection bit when CONDRT bit is set to 1 */
  267. MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST);
  268. /* Writing bits CONDRST=0*/
  269. CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
  270. /* Get tick */
  271. tickstart = HAL_GetTick();
  272. /* Wait for conditioning reset process to be completed */
  273. while(HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
  274. {
  275. if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE)
  276. {
  277. /* New check to avoid false timeout detection in case of preemption */
  278. if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
  279. {
  280. hrng->State = HAL_RNG_STATE_READY;
  281. hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
  282. /* Process Unlocked */
  283. __HAL_UNLOCK(hrng);
  284. return HAL_ERROR;
  285. }
  286. }
  287. }
  288. #else
  289. #if defined(RNG_CR_CED)
  290. /* Clear Clock Error Detection bit */
  291. CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
  292. #endif /* RNG_CR_CED */
  293. #endif /* RNG_CR_CONDRST */
  294. /* Disable the RNG Peripheral */
  295. CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
  296. /* Clear RNG interrupt status flags */
  297. CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
  298. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  299. if (hrng->MspDeInitCallback == NULL)
  300. {
  301. hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
  302. }
  303. /* DeInit the low level hardware */
  304. hrng->MspDeInitCallback(hrng);
  305. #else
  306. /* DeInit the low level hardware */
  307. HAL_RNG_MspDeInit(hrng);
  308. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  309. /* Update the RNG state */
  310. hrng->State = HAL_RNG_STATE_RESET;
  311. /* Initialise the error code */
  312. hrng->ErrorCode = HAL_RNG_ERROR_NONE;
  313. /* Release Lock */
  314. __HAL_UNLOCK(hrng);
  315. /* Return the function status */
  316. return HAL_OK;
  317. }
  318. /**
  319. * @brief Initializes the RNG MSP.
  320. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  321. * the configuration information for RNG.
  322. * @retval None
  323. */
  324. __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
  325. {
  326. /* Prevent unused argument(s) compilation warning */
  327. UNUSED(hrng);
  328. /* NOTE : This function should not be modified. When the callback is needed,
  329. function HAL_RNG_MspInit must be implemented in the user file.
  330. */
  331. }
  332. /**
  333. * @brief DeInitializes the RNG MSP.
  334. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  335. * the configuration information for RNG.
  336. * @retval None
  337. */
  338. __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
  339. {
  340. /* Prevent unused argument(s) compilation warning */
  341. UNUSED(hrng);
  342. /* NOTE : This function should not be modified. When the callback is needed,
  343. function HAL_RNG_MspDeInit must be implemented in the user file.
  344. */
  345. }
  346. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  347. /**
  348. * @brief Register a User RNG Callback
  349. * To be used instead of the weak predefined callback
  350. * @param hrng RNG handle
  351. * @param CallbackID ID of the callback to be registered
  352. * This parameter can be one of the following values:
  353. * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
  354. * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
  355. * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
  356. * @param pCallback pointer to the Callback function
  357. * @retval HAL status
  358. */
  359. HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
  360. {
  361. HAL_StatusTypeDef status = HAL_OK;
  362. if (pCallback == NULL)
  363. {
  364. /* Update the error code */
  365. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  366. return HAL_ERROR;
  367. }
  368. /* Process locked */
  369. __HAL_LOCK(hrng);
  370. if (HAL_RNG_STATE_READY == hrng->State)
  371. {
  372. switch (CallbackID)
  373. {
  374. case HAL_RNG_ERROR_CB_ID :
  375. hrng->ErrorCallback = pCallback;
  376. break;
  377. case HAL_RNG_MSPINIT_CB_ID :
  378. hrng->MspInitCallback = pCallback;
  379. break;
  380. case HAL_RNG_MSPDEINIT_CB_ID :
  381. hrng->MspDeInitCallback = pCallback;
  382. break;
  383. default :
  384. /* Update the error code */
  385. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  386. /* Return error status */
  387. status = HAL_ERROR;
  388. break;
  389. }
  390. }
  391. else if (HAL_RNG_STATE_RESET == hrng->State)
  392. {
  393. switch (CallbackID)
  394. {
  395. case HAL_RNG_MSPINIT_CB_ID :
  396. hrng->MspInitCallback = pCallback;
  397. break;
  398. case HAL_RNG_MSPDEINIT_CB_ID :
  399. hrng->MspDeInitCallback = pCallback;
  400. break;
  401. default :
  402. /* Update the error code */
  403. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  404. /* Return error status */
  405. status = HAL_ERROR;
  406. break;
  407. }
  408. }
  409. else
  410. {
  411. /* Update the error code */
  412. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  413. /* Return error status */
  414. status = HAL_ERROR;
  415. }
  416. /* Release Lock */
  417. __HAL_UNLOCK(hrng);
  418. return status;
  419. }
  420. /**
  421. * @brief Unregister an RNG Callback
  422. * RNG callabck is redirected to the weak predefined callback
  423. * @param hrng RNG handle
  424. * @param CallbackID ID of the callback to be unregistered
  425. * This parameter can be one of the following values:
  426. * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
  427. * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
  428. * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
  429. * @retval HAL status
  430. */
  431. HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
  432. {
  433. HAL_StatusTypeDef status = HAL_OK;
  434. /* Process locked */
  435. __HAL_LOCK(hrng);
  436. if (HAL_RNG_STATE_READY == hrng->State)
  437. {
  438. switch (CallbackID)
  439. {
  440. case HAL_RNG_ERROR_CB_ID :
  441. hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
  442. break;
  443. case HAL_RNG_MSPINIT_CB_ID :
  444. hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
  445. break;
  446. case HAL_RNG_MSPDEINIT_CB_ID :
  447. hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
  448. break;
  449. default :
  450. /* Update the error code */
  451. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  452. /* Return error status */
  453. status = HAL_ERROR;
  454. break;
  455. }
  456. }
  457. else if (HAL_RNG_STATE_RESET == hrng->State)
  458. {
  459. switch (CallbackID)
  460. {
  461. case HAL_RNG_MSPINIT_CB_ID :
  462. hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
  463. break;
  464. case HAL_RNG_MSPDEINIT_CB_ID :
  465. hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */
  466. break;
  467. default :
  468. /* Update the error code */
  469. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  470. /* Return error status */
  471. status = HAL_ERROR;
  472. break;
  473. }
  474. }
  475. else
  476. {
  477. /* Update the error code */
  478. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  479. /* Return error status */
  480. status = HAL_ERROR;
  481. }
  482. /* Release Lock */
  483. __HAL_UNLOCK(hrng);
  484. return status;
  485. }
  486. /**
  487. * @brief Register Data Ready RNG Callback
  488. * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
  489. * @param hrng RNG handle
  490. * @param pCallback pointer to the Data Ready Callback function
  491. * @retval HAL status
  492. */
  493. HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
  494. {
  495. HAL_StatusTypeDef status = HAL_OK;
  496. if (pCallback == NULL)
  497. {
  498. /* Update the error code */
  499. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  500. return HAL_ERROR;
  501. }
  502. /* Process locked */
  503. __HAL_LOCK(hrng);
  504. if (HAL_RNG_STATE_READY == hrng->State)
  505. {
  506. hrng->ReadyDataCallback = pCallback;
  507. }
  508. else
  509. {
  510. /* Update the error code */
  511. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  512. /* Return error status */
  513. status = HAL_ERROR;
  514. }
  515. /* Release Lock */
  516. __HAL_UNLOCK(hrng);
  517. return status;
  518. }
  519. /**
  520. * @brief UnRegister the Data Ready RNG Callback
  521. * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
  522. * @param hrng RNG handle
  523. * @retval HAL status
  524. */
  525. HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
  526. {
  527. HAL_StatusTypeDef status = HAL_OK;
  528. /* Process locked */
  529. __HAL_LOCK(hrng);
  530. if (HAL_RNG_STATE_READY == hrng->State)
  531. {
  532. hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
  533. }
  534. else
  535. {
  536. /* Update the error code */
  537. hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
  538. /* Return error status */
  539. status = HAL_ERROR;
  540. }
  541. /* Release Lock */
  542. __HAL_UNLOCK(hrng);
  543. return status;
  544. }
  545. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  546. /**
  547. * @}
  548. */
  549. /** @addtogroup RNG_Exported_Functions_Group2
  550. * @brief Peripheral Control functions
  551. *
  552. @verbatim
  553. ===============================================================================
  554. ##### Peripheral Control functions #####
  555. ===============================================================================
  556. [..] This section provides functions allowing to:
  557. (+) Get the 32 bit Random number
  558. (+) Get the 32 bit Random number with interrupt enabled
  559. (+) Handle RNG interrupt request
  560. @endverbatim
  561. * @{
  562. */
  563. /**
  564. * @brief Generates a 32-bit random number.
  565. * @note When several random data are output at the same time in an output buffer,
  566. * this function checks value of RNG_FLAG_DRDY flag to know if valid
  567. * random number is available in the DR register (RNG_FLAG_DRDY flag set
  568. * whenever a random number is available through the RNG_DR register).
  569. * After transitioning from 0 to 1 (random number available),
  570. * RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading
  571. * four words from the RNG_DR register, i.e. further function calls
  572. * will immediately return a new u32 random number (additional words are
  573. * available and can be read by the application, till RNG_FLAG_DRDY flag remains high).
  574. * When no more random number data is available in DR register, RNG_FLAG_DRDY
  575. * flag is automatically cleared.
  576. * When random number are out on a single sample basis, each time the random
  577. * number data is read the RNG_FLAG_DRDY flag is automatically cleared.
  578. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  579. * the configuration information for RNG.
  580. * @param random32bit pointer to generated random number variable if successful.
  581. * @retval HAL status
  582. */
  583. HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
  584. {
  585. uint32_t tickstart;
  586. HAL_StatusTypeDef status = HAL_OK;
  587. /* Process Locked */
  588. __HAL_LOCK(hrng);
  589. /* Check RNG peripheral state */
  590. if (hrng->State == HAL_RNG_STATE_READY)
  591. {
  592. /* Change RNG peripheral state */
  593. hrng->State = HAL_RNG_STATE_BUSY;
  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. hrng->State = HAL_RNG_STATE_READY;
  602. hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
  603. /* Process Unlocked */
  604. __HAL_UNLOCK(hrng);
  605. return HAL_ERROR;
  606. }
  607. }
  608. /* Get a 32bit Random number */
  609. hrng->RandomNumber = hrng->Instance->DR;
  610. *random32bit = hrng->RandomNumber;
  611. hrng->State = HAL_RNG_STATE_READY;
  612. }
  613. else
  614. {
  615. hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
  616. status = HAL_ERROR;
  617. }
  618. /* Process Unlocked */
  619. __HAL_UNLOCK(hrng);
  620. return status;
  621. }
  622. /**
  623. * @brief Generates a 32-bit random number in interrupt mode.
  624. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  625. * the configuration information for RNG.
  626. * @retval HAL status
  627. */
  628. HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
  629. {
  630. HAL_StatusTypeDef status = HAL_OK;
  631. /* Process Locked */
  632. __HAL_LOCK(hrng);
  633. /* Check RNG peripheral state */
  634. if (hrng->State == HAL_RNG_STATE_READY)
  635. {
  636. /* Change RNG peripheral state */
  637. hrng->State = HAL_RNG_STATE_BUSY;
  638. /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
  639. __HAL_RNG_ENABLE_IT(hrng);
  640. }
  641. else
  642. {
  643. /* Process Unlocked */
  644. __HAL_UNLOCK(hrng);
  645. hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
  646. status = HAL_ERROR;
  647. }
  648. return status;
  649. }
  650. /**
  651. * @brief Returns generated random number in polling mode (Obsolete)
  652. * Use HAL_RNG_GenerateRandomNumber() API instead.
  653. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  654. * the configuration information for RNG.
  655. * @retval Random value
  656. */
  657. uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
  658. {
  659. if(HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
  660. {
  661. return hrng->RandomNumber;
  662. }
  663. else
  664. {
  665. return 0U;
  666. }
  667. }
  668. /**
  669. * @brief Returns a 32-bit random number with interrupt enabled (Obsolete),
  670. * Use HAL_RNG_GenerateRandomNumber_IT() API instead.
  671. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  672. * the configuration information for RNG.
  673. * @retval 32-bit random number
  674. */
  675. uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
  676. {
  677. uint32_t random32bit = 0U;
  678. /* Process locked */
  679. __HAL_LOCK(hrng);
  680. /* Change RNG peripheral state */
  681. hrng->State = HAL_RNG_STATE_BUSY;
  682. /* Get a 32bit Random number */
  683. random32bit = hrng->Instance->DR;
  684. /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
  685. __HAL_RNG_ENABLE_IT(hrng);
  686. /* Return the 32 bit random number */
  687. return random32bit;
  688. }
  689. /**
  690. * @brief Handles RNG interrupt request.
  691. * @note In the case of a clock error, the RNG is no more able to generate
  692. * random numbers because the PLL48CLK clock is not correct. User has
  693. * to check that the clock controller is correctly configured to provide
  694. * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
  695. * The clock error has no impact on the previously generated
  696. * random numbers, and the RNG_DR register contents can be used.
  697. * @note In the case of a seed error, the generation of random numbers is
  698. * interrupted as long as the SECS bit is '1'. If a number is
  699. * available in the RNG_DR register, it must not be used because it may
  700. * not have enough entropy. In this case, it is recommended to clear the
  701. * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
  702. * the RNG peripheral to reinitialize and restart the RNG.
  703. * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
  704. * or CEIS are set.
  705. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  706. * the configuration information for RNG.
  707. * @retval None
  708. */
  709. void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
  710. {
  711. uint32_t rngclockerror = 0U;
  712. /* RNG clock error interrupt occurred */
  713. if (__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET)
  714. {
  715. /* Update the error code */
  716. hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
  717. rngclockerror = 1U;
  718. }
  719. else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
  720. {
  721. /* Update the error code */
  722. hrng->ErrorCode = HAL_RNG_ERROR_SEED;
  723. rngclockerror = 1U;
  724. }
  725. else
  726. {
  727. /* Nothing to do */
  728. }
  729. if (rngclockerror == 1U)
  730. {
  731. /* Change RNG peripheral state */
  732. hrng->State = HAL_RNG_STATE_ERROR;
  733. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  734. /* Call registered Error callback */
  735. hrng->ErrorCallback(hrng);
  736. #else
  737. /* Call legacy weak Error callback */
  738. HAL_RNG_ErrorCallback(hrng);
  739. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  740. /* Clear the clock error flag */
  741. __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
  742. }
  743. /* Check RNG data ready interrupt occurred */
  744. if (__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
  745. {
  746. /* Generate random number once, so disable the IT */
  747. __HAL_RNG_DISABLE_IT(hrng);
  748. /* Get the 32bit Random number (DRDY flag automatically cleared) */
  749. hrng->RandomNumber = hrng->Instance->DR;
  750. if (hrng->State != HAL_RNG_STATE_ERROR)
  751. {
  752. /* Change RNG peripheral state */
  753. hrng->State = HAL_RNG_STATE_READY;
  754. /* Process Unlocked */
  755. __HAL_UNLOCK(hrng);
  756. #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
  757. /* Call registered Data Ready callback */
  758. hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
  759. #else
  760. /* Call legacy weak Data Ready callback */
  761. HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
  762. #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
  763. }
  764. }
  765. }
  766. /**
  767. * @brief Read latest generated random number.
  768. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  769. * the configuration information for RNG.
  770. * @retval random value
  771. */
  772. uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
  773. {
  774. return (hrng->RandomNumber);
  775. }
  776. /**
  777. * @brief Data Ready callback in non-blocking mode.
  778. * @note When several random data are output at the same time in an output buffer,
  779. * When RNG_FLAG_DRDY flag value is set, first random number has been read
  780. * from DR register in IRQ Handler and is provided as callback parameter.
  781. * Depending on valid data available in the conditioning output buffer,
  782. * additional words can be read by the application from DR register till
  783. * DRDY bit remains high.
  784. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  785. * the configuration information for RNG.
  786. * @param random32bit generated random number.
  787. * @retval None
  788. */
  789. __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
  790. {
  791. /* Prevent unused argument(s) compilation warning */
  792. UNUSED(hrng);
  793. UNUSED(random32bit);
  794. /* NOTE : This function should not be modified. When the callback is needed,
  795. function HAL_RNG_ReadyDataCallback must be implemented in the user file.
  796. */
  797. }
  798. /**
  799. * @brief RNG error callbacks.
  800. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  801. * the configuration information for RNG.
  802. * @retval None
  803. */
  804. __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
  805. {
  806. /* Prevent unused argument(s) compilation warning */
  807. UNUSED(hrng);
  808. /* NOTE : This function should not be modified. When the callback is needed,
  809. function HAL_RNG_ErrorCallback must be implemented in the user file.
  810. */
  811. }
  812. /**
  813. * @}
  814. */
  815. /** @addtogroup RNG_Exported_Functions_Group3
  816. * @brief Peripheral State functions
  817. *
  818. @verbatim
  819. ===============================================================================
  820. ##### Peripheral State functions #####
  821. ===============================================================================
  822. [..]
  823. This subsection permits to get in run-time the status of the peripheral
  824. and the data flow.
  825. @endverbatim
  826. * @{
  827. */
  828. /**
  829. * @brief Returns the RNG state.
  830. * @param hrng pointer to a RNG_HandleTypeDef structure that contains
  831. * the configuration information for RNG.
  832. * @retval HAL state
  833. */
  834. HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
  835. {
  836. return hrng->State;
  837. }
  838. /**
  839. * @brief Return the RNG handle error code.
  840. * @param hrng pointer to a RNG_HandleTypeDef structure.
  841. * @retval RNG Error Code
  842. */
  843. uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
  844. {
  845. /* Return RNG Error Code */
  846. return hrng->ErrorCode;
  847. }
  848. /**
  849. * @}
  850. */
  851. /**
  852. * @}
  853. */
  854. #endif /* HAL_RNG_MODULE_ENABLED */
  855. /**
  856. * @}
  857. */
  858. #endif /* RNG */
  859. /**
  860. * @}
  861. */