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