1 /**
2   ******************************************************************************
3   * @file    stm32f2xx_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) 2016 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 
30       (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro
31           in HAL_RNG_MspInit().
32       (#) Activate the RNG peripheral using HAL_RNG_Init() function.
33       (#) Wait until the 32 bit Random Number Generator contains a valid
34           random data using (polling/interrupt) mode.
35       (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function.
36 
37     ##### Callback registration #####
38     ==================================
39 
40     [..]
41     The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1
42     allows the user to configure dynamically the driver callbacks.
43 
44     [..]
45     Use Function HAL_RNG_RegisterCallback() to register a user callback.
46     Function HAL_RNG_RegisterCallback() allows to register following callbacks:
47     (+) ErrorCallback             : RNG Error Callback.
48     (+) MspInitCallback           : RNG MspInit.
49     (+) MspDeInitCallback         : RNG MspDeInit.
50     This function takes as parameters the HAL peripheral handle, the Callback ID
51     and a pointer to the user callback function.
52 
53     [..]
54     Use function HAL_RNG_UnRegisterCallback() to reset a callback to the default
55     weak (overridden) function.
56     HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle,
57     and the Callback ID.
58     This function allows to reset following callbacks:
59     (+) ErrorCallback             : RNG Error Callback.
60     (+) MspInitCallback           : RNG MspInit.
61     (+) MspDeInitCallback         : RNG MspDeInit.
62 
63     [..]
64     For specific callback ReadyDataCallback, use dedicated register callbacks:
65     respectively HAL_RNG_RegisterReadyDataCallback() , HAL_RNG_UnRegisterReadyDataCallback().
66 
67     [..]
68     By default, after the HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET
69     all callbacks are set to the corresponding weak (overridden) functions:
70     example HAL_RNG_ErrorCallback().
71     Exception done for MspInit and MspDeInit functions that are respectively
72     reset to the legacy weak (overridden) functions in the HAL_RNG_Init()
73     and HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand).
74     If not, MspInit or MspDeInit are not null, the HAL_RNG_Init() and HAL_RNG_DeInit()
75     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
76 
77     [..]
78     Callbacks can be registered/unregistered in HAL_RNG_STATE_READY state only.
79     Exception done MspInit/MspDeInit that can be registered/unregistered
80     in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user)
81     MspInit/DeInit callbacks can be used during the Init/DeInit.
82     In that case first register the MspInit/MspDeInit user callbacks
83     using HAL_RNG_RegisterCallback() before calling HAL_RNG_DeInit()
84     or HAL_RNG_Init() function.
85 
86     [..]
87     When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or
88     not defined, the callback registration feature is not available
89     and weak (overridden) callbacks are used.
90 
91   @endverbatim
92   ******************************************************************************
93   */
94 
95 /* Includes ------------------------------------------------------------------*/
96 #include "stm32f2xx_hal.h"
97 
98 /** @addtogroup STM32F2xx_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,
300                                            pRNG_CallbackTypeDef pCallback)
301 {
302   HAL_StatusTypeDef status = HAL_OK;
303 
304   if (pCallback == NULL)
305   {
306     /* Update the error code */
307     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
308     return HAL_ERROR;
309   }
310 
311   if (HAL_RNG_STATE_READY == hrng->State)
312   {
313     switch (CallbackID)
314     {
315       case HAL_RNG_ERROR_CB_ID :
316         hrng->ErrorCallback = pCallback;
317         break;
318 
319       case HAL_RNG_MSPINIT_CB_ID :
320         hrng->MspInitCallback = pCallback;
321         break;
322 
323       case HAL_RNG_MSPDEINIT_CB_ID :
324         hrng->MspDeInitCallback = pCallback;
325         break;
326 
327       default :
328         /* Update the error code */
329         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
330         /* Return error status */
331         status =  HAL_ERROR;
332         break;
333     }
334   }
335   else if (HAL_RNG_STATE_RESET == hrng->State)
336   {
337     switch (CallbackID)
338     {
339       case HAL_RNG_MSPINIT_CB_ID :
340         hrng->MspInitCallback = pCallback;
341         break;
342 
343       case HAL_RNG_MSPDEINIT_CB_ID :
344         hrng->MspDeInitCallback = pCallback;
345         break;
346 
347       default :
348         /* Update the error code */
349         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
350         /* Return error status */
351         status =  HAL_ERROR;
352         break;
353     }
354   }
355   else
356   {
357     /* Update the error code */
358     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
359     /* Return error status */
360     status =  HAL_ERROR;
361   }
362 
363   return status;
364 }
365 
366 /**
367   * @brief  Unregister an RNG Callback
368   *         RNG callback is redirected to the weak predefined callback
369   * @param  hrng RNG handle
370   * @param  CallbackID ID of the callback to be unregistered
371   *         This parameter can be one of the following values:
372   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
373   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
374   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
375   * @retval HAL status
376   */
HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID)377 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
378 {
379   HAL_StatusTypeDef status = HAL_OK;
380 
381 
382   if (HAL_RNG_STATE_READY == hrng->State)
383   {
384     switch (CallbackID)
385     {
386       case HAL_RNG_ERROR_CB_ID :
387         hrng->ErrorCallback = HAL_RNG_ErrorCallback;          /* Legacy weak ErrorCallback  */
388         break;
389 
390       case HAL_RNG_MSPINIT_CB_ID :
391         hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
392         break;
393 
394       case HAL_RNG_MSPDEINIT_CB_ID :
395         hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspDeInit  */
396         break;
397 
398       default :
399         /* Update the error code */
400         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
401         /* Return error status */
402         status =  HAL_ERROR;
403         break;
404     }
405   }
406   else if (HAL_RNG_STATE_RESET == hrng->State)
407   {
408     switch (CallbackID)
409     {
410       case HAL_RNG_MSPINIT_CB_ID :
411         hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
412         break;
413 
414       case HAL_RNG_MSPDEINIT_CB_ID :
415         hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspInit  */
416         break;
417 
418       default :
419         /* Update the error code */
420         hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
421         /* Return error status */
422         status =  HAL_ERROR;
423         break;
424     }
425   }
426   else
427   {
428     /* Update the error code */
429     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
430     /* Return error status */
431     status =  HAL_ERROR;
432   }
433 
434   return status;
435 }
436 
437 /**
438   * @brief  Register Data Ready RNG Callback
439   *         To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
440   * @param  hrng RNG handle
441   * @param  pCallback pointer to the Data Ready Callback function
442   * @retval HAL status
443   */
HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef * hrng,pRNG_ReadyDataCallbackTypeDef pCallback)444 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
445 {
446   HAL_StatusTypeDef status = HAL_OK;
447 
448   if (pCallback == NULL)
449   {
450     /* Update the error code */
451     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
452     return HAL_ERROR;
453   }
454   /* Process locked */
455   __HAL_LOCK(hrng);
456 
457   if (HAL_RNG_STATE_READY == hrng->State)
458   {
459     hrng->ReadyDataCallback = pCallback;
460   }
461   else
462   {
463     /* Update the error code */
464     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
465     /* Return error status */
466     status =  HAL_ERROR;
467   }
468 
469   /* Release Lock */
470   __HAL_UNLOCK(hrng);
471   return status;
472 }
473 
474 /**
475   * @brief  UnRegister the Data Ready RNG Callback
476   *         Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
477   * @param  hrng RNG handle
478   * @retval HAL status
479   */
HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef * hrng)480 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
481 {
482   HAL_StatusTypeDef status = HAL_OK;
483 
484   /* Process locked */
485   __HAL_LOCK(hrng);
486 
487   if (HAL_RNG_STATE_READY == hrng->State)
488   {
489     hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback  */
490   }
491   else
492   {
493     /* Update the error code */
494     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
495     /* Return error status */
496     status =  HAL_ERROR;
497   }
498 
499   /* Release Lock */
500   __HAL_UNLOCK(hrng);
501   return status;
502 }
503 
504 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
505 
506 /**
507   * @}
508   */
509 
510 /** @addtogroup RNG_Exported_Functions_Group2
511   *  @brief   Peripheral Control functions
512   *
513 @verbatim
514  ===============================================================================
515                       ##### Peripheral Control functions #####
516  ===============================================================================
517     [..]  This section provides functions allowing to:
518       (+) Get the 32 bit Random number
519       (+) Get the 32 bit Random number with interrupt enabled
520       (+) Handle RNG interrupt request
521 
522 @endverbatim
523   * @{
524   */
525 
526 /**
527   * @brief  Generates a 32-bit random number.
528   * @note   Each time the random number data is read the RNG_FLAG_DRDY flag
529   *         is automatically cleared.
530   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
531   *                the configuration information for RNG.
532   * @param  random32bit pointer to generated random number variable if successful.
533   * @retval HAL status
534   */
535 
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef * hrng,uint32_t * random32bit)536 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
537 {
538   uint32_t tickstart;
539   HAL_StatusTypeDef status = HAL_OK;
540 
541   /* Process Locked */
542   __HAL_LOCK(hrng);
543 
544   /* Check RNG peripheral state */
545   if (hrng->State == HAL_RNG_STATE_READY)
546   {
547     /* Change RNG peripheral state */
548     hrng->State = HAL_RNG_STATE_BUSY;
549 
550     /* Get tick */
551     tickstart = HAL_GetTick();
552 
553     /* Check if data register contains valid random data */
554     while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
555     {
556       if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
557       {
558         /* New check to avoid false timeout detection in case of preemption */
559         if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
560         {
561           hrng->State = HAL_RNG_STATE_READY;
562           hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
563           /* Process Unlocked */
564           __HAL_UNLOCK(hrng);
565           return HAL_ERROR;
566         }
567       }
568     }
569 
570     /* Get a 32bit Random number */
571     hrng->RandomNumber = hrng->Instance->DR;
572     *random32bit = hrng->RandomNumber;
573 
574     hrng->State = HAL_RNG_STATE_READY;
575   }
576   else
577   {
578     hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
579     status = HAL_ERROR;
580   }
581 
582   /* Process Unlocked */
583   __HAL_UNLOCK(hrng);
584 
585   return status;
586 }
587 
588 /**
589   * @brief  Generates a 32-bit random number in interrupt mode.
590   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
591   *                the configuration information for RNG.
592   * @retval HAL status
593   */
HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef * hrng)594 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
595 {
596   HAL_StatusTypeDef status = HAL_OK;
597 
598   /* Process Locked */
599   __HAL_LOCK(hrng);
600 
601   /* Check RNG peripheral state */
602   if (hrng->State == HAL_RNG_STATE_READY)
603   {
604     /* Change RNG peripheral state */
605     hrng->State = HAL_RNG_STATE_BUSY;
606 
607     /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
608     __HAL_RNG_ENABLE_IT(hrng);
609   }
610   else
611   {
612     /* Process Unlocked */
613     __HAL_UNLOCK(hrng);
614 
615     hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
616     status = HAL_ERROR;
617   }
618 
619   return status;
620 }
621 
622 /**
623   * @brief  Returns generated random number in polling mode (Obsolete)
624   *         Use HAL_RNG_GenerateRandomNumber() API instead.
625   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
626   *                the configuration information for RNG.
627   * @retval Random value
628   */
HAL_RNG_GetRandomNumber(RNG_HandleTypeDef * hrng)629 uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
630 {
631   if (HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
632   {
633     return hrng->RandomNumber;
634   }
635   else
636   {
637     return 0U;
638   }
639 }
640 
641 /**
642   * @brief  Returns a 32-bit random number with interrupt enabled (Obsolete),
643   *         Use HAL_RNG_GenerateRandomNumber_IT() API instead.
644   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
645   *                the configuration information for RNG.
646   * @retval 32-bit random number
647   */
HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef * hrng)648 uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
649 {
650   uint32_t random32bit = 0U;
651 
652   /* Process locked */
653   __HAL_LOCK(hrng);
654 
655   /* Change RNG peripheral state */
656   hrng->State = HAL_RNG_STATE_BUSY;
657 
658   /* Get a 32bit Random number */
659   random32bit = hrng->Instance->DR;
660 
661   /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
662   __HAL_RNG_ENABLE_IT(hrng);
663 
664   /* Return the 32 bit random number */
665   return random32bit;
666 }
667 
668 /**
669   * @brief  Handles RNG interrupt request.
670   * @note   In the case of a clock error, the RNG is no more able to generate
671   *         random numbers because the PLL48CLK clock is not correct. User has
672   *         to check that the clock controller is correctly configured to provide
673   *         the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
674   *         The clock error has no impact on the previously generated
675   *         random numbers, and the RNG_DR register contents can be used.
676   * @note   In the case of a seed error, the generation of random numbers is
677   *         interrupted as long as the SECS bit is '1'. If a number is
678   *         available in the RNG_DR register, it must not be used because it may
679   *         not have enough entropy. In this case, it is recommended to clear the
680   *         SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
681   *         the RNG peripheral to reinitialize and restart the RNG.
682   * @note   User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
683   *         or CEIS are set.
684   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
685   *                the configuration information for RNG.
686   * @retval None
687 
688   */
HAL_RNG_IRQHandler(RNG_HandleTypeDef * hrng)689 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
690 {
691   uint32_t rngclockerror = 0U;
692 
693   /* RNG clock error interrupt occurred */
694   if (__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET)
695   {
696     /* Update the error code */
697     hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
698     rngclockerror = 1U;
699   }
700   else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
701   {
702     /* Update the error code */
703     hrng->ErrorCode = HAL_RNG_ERROR_SEED;
704     rngclockerror = 1U;
705   }
706   else
707   {
708     /* Nothing to do */
709   }
710 
711   if (rngclockerror == 1U)
712   {
713     /* Change RNG peripheral state */
714     hrng->State = HAL_RNG_STATE_ERROR;
715 
716 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
717     /* Call registered Error callback */
718     hrng->ErrorCallback(hrng);
719 #else
720     /* Call legacy weak Error callback */
721     HAL_RNG_ErrorCallback(hrng);
722 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
723 
724     /* Clear the clock error flag */
725     __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
726 
727     return;
728   }
729 
730   /* Check RNG data ready interrupt occurred */
731   if (__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
732   {
733     /* Generate random number once, so disable the IT */
734     __HAL_RNG_DISABLE_IT(hrng);
735 
736     /* Get the 32bit Random number (DRDY flag automatically cleared) */
737     hrng->RandomNumber = hrng->Instance->DR;
738 
739     if (hrng->State != HAL_RNG_STATE_ERROR)
740     {
741       /* Change RNG peripheral state */
742       hrng->State = HAL_RNG_STATE_READY;
743       /* Process Unlocked */
744       __HAL_UNLOCK(hrng);
745 
746 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
747       /* Call registered Data Ready callback */
748       hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
749 #else
750       /* Call legacy weak Data Ready callback */
751       HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
752 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
753     }
754   }
755 }
756 
757 /**
758   * @brief  Read latest generated random number.
759   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
760   *                the configuration information for RNG.
761   * @retval random value
762   */
HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef * hrng)763 uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng)
764 {
765   return (hrng->RandomNumber);
766 }
767 
768 /**
769   * @brief  Data Ready callback in non-blocking mode.
770   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
771   *                the configuration information for RNG.
772   * @param  random32bit generated random number.
773   * @retval None
774   */
HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef * hrng,uint32_t random32bit)775 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
776 {
777   /* Prevent unused argument(s) compilation warning */
778   UNUSED(hrng);
779   UNUSED(random32bit);
780   /* NOTE : This function should not be modified. When the callback is needed,
781             function HAL_RNG_ReadyDataCallback must be implemented in the user file.
782    */
783 }
784 
785 /**
786   * @brief  RNG error callbacks.
787   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
788   *                the configuration information for RNG.
789   * @retval None
790   */
HAL_RNG_ErrorCallback(RNG_HandleTypeDef * hrng)791 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
792 {
793   /* Prevent unused argument(s) compilation warning */
794   UNUSED(hrng);
795   /* NOTE : This function should not be modified. When the callback is needed,
796             function HAL_RNG_ErrorCallback must be implemented in the user file.
797    */
798 }
799 /**
800   * @}
801   */
802 
803 
804 /** @addtogroup RNG_Exported_Functions_Group3
805   *  @brief   Peripheral State functions
806   *
807 @verbatim
808  ===============================================================================
809                       ##### Peripheral State functions #####
810  ===============================================================================
811     [..]
812     This subsection permits to get in run-time the status of the peripheral
813     and the data flow.
814 
815 @endverbatim
816   * @{
817   */
818 
819 /**
820   * @brief  Returns the RNG state.
821   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
822   *                the configuration information for RNG.
823   * @retval HAL state
824   */
HAL_RNG_GetState(const RNG_HandleTypeDef * hrng)825 HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng)
826 {
827   return hrng->State;
828 }
829 
830 /**
831   * @brief  Return the RNG handle error code.
832   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
833   * @retval RNG Error Code
834   */
HAL_RNG_GetError(const RNG_HandleTypeDef * hrng)835 uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng)
836 {
837   /* Return RNG Error Code */
838   return hrng->ErrorCode;
839 }
840 /**
841   * @}
842   */
843 
844 /**
845   * @}
846   */
847 
848 
849 #endif /* HAL_RNG_MODULE_ENABLED */
850 /**
851   * @}
852   */
853 
854 #endif /* RNG */
855 
856 /**
857   * @}
858   */
859 
860