stm32l4xx_hal_rng.c 34 KB

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