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