1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_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) 2017 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 "stm32h7xx_hal.h"
97 
98 /** @addtogroup STM32H7xx_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   assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
165 
166 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
167   if (hrng->State == HAL_RNG_STATE_RESET)
168   {
169     /* Allocate lock resource and initialize it */
170     hrng->Lock = HAL_UNLOCKED;
171 
172     hrng->ReadyDataCallback  = HAL_RNG_ReadyDataCallback;  /* Legacy weak ReadyDataCallback  */
173     hrng->ErrorCallback      = HAL_RNG_ErrorCallback;      /* Legacy weak ErrorCallback      */
174 
175     if (hrng->MspInitCallback == NULL)
176     {
177       hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit  */
178     }
179 
180     /* Init the low level hardware */
181     hrng->MspInitCallback(hrng);
182   }
183 #else
184   if (hrng->State == HAL_RNG_STATE_RESET)
185   {
186     /* Allocate lock resource and initialize it */
187     hrng->Lock = HAL_UNLOCKED;
188 
189     /* Init the low level hardware */
190     HAL_RNG_MspInit(hrng);
191   }
192 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
193 
194   /* Change RNG peripheral state */
195   hrng->State = HAL_RNG_STATE_BUSY;
196 
197   /* Clock Error Detection Configuration */
198   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
199 
200   /* Enable the RNG Peripheral */
201   __HAL_RNG_ENABLE(hrng);
202 
203   /* Initialize the RNG state */
204   hrng->State = HAL_RNG_STATE_READY;
205 
206   /* Initialise the error code */
207   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
208 
209   /* Return function status */
210   return HAL_OK;
211 }
212 
213 /**
214   * @brief  DeInitializes the RNG peripheral.
215   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
216   *                the configuration information for RNG.
217   * @retval HAL status
218   */
HAL_RNG_DeInit(RNG_HandleTypeDef * hrng)219 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
220 {
221   /* Check the RNG handle allocation */
222   if (hrng == NULL)
223   {
224     return HAL_ERROR;
225   }
226 
227   /* Clear Clock Error Detection bit */
228   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
229   /* Disable the RNG Peripheral */
230   CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
231 
232   /* Clear RNG interrupt status flags */
233   CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
234 
235 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
236   if (hrng->MspDeInitCallback == NULL)
237   {
238     hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit  */
239   }
240 
241   /* DeInit the low level hardware */
242   hrng->MspDeInitCallback(hrng);
243 #else
244   /* DeInit the low level hardware */
245   HAL_RNG_MspDeInit(hrng);
246 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
247 
248   /* Update the RNG state */
249   hrng->State = HAL_RNG_STATE_RESET;
250 
251   /* Initialise the error code */
252   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
253 
254   /* Release Lock */
255   __HAL_UNLOCK(hrng);
256 
257   /* Return the function status */
258   return HAL_OK;
259 }
260 
261 /**
262   * @brief  Initializes the RNG MSP.
263   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
264   *                the configuration information for RNG.
265   * @retval None
266   */
HAL_RNG_MspInit(RNG_HandleTypeDef * hrng)267 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
268 {
269   /* Prevent unused argument(s) compilation warning */
270   UNUSED(hrng);
271   /* NOTE : This function should not be modified. When the callback is needed,
272             function HAL_RNG_MspInit must be implemented in the user file.
273    */
274 }
275 
276 /**
277   * @brief  DeInitializes the RNG MSP.
278   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
279   *                the configuration information for RNG.
280   * @retval None
281   */
HAL_RNG_MspDeInit(RNG_HandleTypeDef * hrng)282 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
283 {
284   /* Prevent unused argument(s) compilation warning */
285   UNUSED(hrng);
286   /* NOTE : This function should not be modified. When the callback is needed,
287             function HAL_RNG_MspDeInit must be implemented in the user file.
288    */
289 }
290 
291 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
292 /**
293   * @brief  Register a User RNG Callback
294   *         To be used instead of the weak predefined callback
295   * @param  hrng RNG handle
296   * @param  CallbackID ID of the callback to be registered
297   *         This parameter can be one of the following values:
298   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
299   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
300   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
301   * @param  pCallback pointer to the Callback function
302   * @retval HAL status
303   */
HAL_RNG_RegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID,pRNG_CallbackTypeDef pCallback)304 HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
305 {
306   HAL_StatusTypeDef status = HAL_OK;
307 
308   if (pCallback == NULL)
309   {
310     /* Update the error code */
311     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
312     return HAL_ERROR;
313   }
314   /* Process locked */
315   __HAL_LOCK(hrng);
316 
317   if (HAL_RNG_STATE_READY == hrng->State)
318   {
319     switch (CallbackID)
320     {
321     case HAL_RNG_ERROR_CB_ID :
322       hrng->ErrorCallback = pCallback;
323       break;
324 
325     case HAL_RNG_MSPINIT_CB_ID :
326       hrng->MspInitCallback = pCallback;
327       break;
328 
329     case HAL_RNG_MSPDEINIT_CB_ID :
330       hrng->MspDeInitCallback = pCallback;
331       break;
332 
333     default :
334       /* Update the error code */
335       hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
336      /* Return error status */
337       status =  HAL_ERROR;
338       break;
339     }
340   }
341   else if (HAL_RNG_STATE_RESET == hrng->State)
342   {
343     switch (CallbackID)
344     {
345     case HAL_RNG_MSPINIT_CB_ID :
346       hrng->MspInitCallback = pCallback;
347       break;
348 
349     case HAL_RNG_MSPDEINIT_CB_ID :
350       hrng->MspDeInitCallback = pCallback;
351       break;
352 
353     default :
354       /* Update the error code */
355       hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
356      /* Return error status */
357       status =  HAL_ERROR;
358       break;
359     }
360   }
361   else
362   {
363     /* Update the error code */
364     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
365     /* Return error status */
366     status =  HAL_ERROR;
367   }
368 
369   /* Release Lock */
370   __HAL_UNLOCK(hrng);
371   return status;
372 }
373 
374 /**
375   * @brief  Unregister an RNG Callback
376   *         RNG callabck is redirected to the weak predefined callback
377   * @param  hrng RNG handle
378   * @param  CallbackID ID of the callback to be unregistered
379   *         This parameter can be one of the following values:
380   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
381   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
382   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
383   * @retval HAL status
384   */
HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID)385 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
386 {
387   HAL_StatusTypeDef status = HAL_OK;
388 
389   /* Process locked */
390   __HAL_LOCK(hrng);
391 
392   if (HAL_RNG_STATE_READY == hrng->State)
393   {
394     switch (CallbackID)
395     {
396     case HAL_RNG_ERROR_CB_ID :
397       hrng->ErrorCallback = HAL_RNG_ErrorCallback;          /* Legacy weak ErrorCallback  */
398       break;
399 
400     case HAL_RNG_MSPINIT_CB_ID :
401       hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
402       break;
403 
404     case HAL_RNG_MSPDEINIT_CB_ID :
405       hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspDeInit  */
406       break;
407 
408     default :
409       /* Update the error code */
410       hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
411      /* Return error status */
412       status =  HAL_ERROR;
413       break;
414     }
415   }
416   else if (HAL_RNG_STATE_RESET == hrng->State)
417   {
418     switch (CallbackID)
419     {
420     case HAL_RNG_MSPINIT_CB_ID :
421       hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
422       break;
423 
424     case HAL_RNG_MSPDEINIT_CB_ID :
425       hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspInit  */
426       break;
427 
428     default :
429       /* Update the error code */
430       hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
431      /* Return error status */
432       status =  HAL_ERROR;
433       break;
434     }
435   }
436   else
437   {
438     /* Update the error code */
439     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
440     /* Return error status */
441     status =  HAL_ERROR;
442   }
443 
444   /* Release Lock */
445   __HAL_UNLOCK(hrng);
446   return status;
447 }
448 
449 /**
450   * @brief  Register Data Ready RNG Callback
451   *         To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
452   * @param  hrng RNG handle
453   * @param  pCallback pointer to the Data Ready Callback function
454   * @retval HAL status
455   */
HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef * hrng,pRNG_ReadyDataCallbackTypeDef pCallback)456 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
457 {
458   HAL_StatusTypeDef status = HAL_OK;
459 
460   if (pCallback == NULL)
461   {
462     /* Update the error code */
463     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
464     return HAL_ERROR;
465   }
466   /* Process locked */
467   __HAL_LOCK(hrng);
468 
469   if (HAL_RNG_STATE_READY == hrng->State)
470   {
471     hrng->ReadyDataCallback = pCallback;
472   }
473   else
474   {
475     /* Update the error code */
476     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
477     /* Return error status */
478     status =  HAL_ERROR;
479   }
480 
481   /* Release Lock */
482   __HAL_UNLOCK(hrng);
483   return status;
484 }
485 
486 /**
487   * @brief  UnRegister the Data Ready RNG Callback
488   *         Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
489   * @param  hrng RNG handle
490   * @retval HAL status
491   */
HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef * hrng)492 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
493 {
494   HAL_StatusTypeDef status = HAL_OK;
495 
496   /* Process locked */
497   __HAL_LOCK(hrng);
498 
499   if (HAL_RNG_STATE_READY == hrng->State)
500   {
501     hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback  */
502   }
503   else
504   {
505     /* Update the error code */
506     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
507     /* Return error status */
508     status =  HAL_ERROR;
509   }
510 
511   /* Release Lock */
512   __HAL_UNLOCK(hrng);
513   return status;
514 }
515 
516 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
517 
518 /**
519   * @}
520   */
521 
522 /** @addtogroup RNG_Exported_Functions_Group2
523  *  @brief   Peripheral Control functions
524  *
525 @verbatim
526  ===============================================================================
527                       ##### Peripheral Control functions #####
528  ===============================================================================
529     [..]  This section provides functions allowing to:
530       (+) Get the 32 bit Random number
531       (+) Get the 32 bit Random number with interrupt enabled
532       (+) Handle RNG interrupt request
533 
534 @endverbatim
535   * @{
536   */
537 
538 /**
539   * @brief  Generates a 32-bit random number.
540   * @note   Each time the random number data is read the RNG_FLAG_DRDY flag
541   *         is automatically cleared.
542   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
543   *                the configuration information for RNG.
544   * @param  random32bit pointer to generated random number variable if successful.
545   * @retval HAL status
546   */
547 
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef * hrng,uint32_t * random32bit)548 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
549 {
550   uint32_t tickstart;
551   HAL_StatusTypeDef status = HAL_OK;
552 
553   /* Process Locked */
554   __HAL_LOCK(hrng);
555 
556   /* Check RNG peripheral state */
557   if (hrng->State == HAL_RNG_STATE_READY)
558   {
559     /* Change RNG peripheral state */
560     hrng->State = HAL_RNG_STATE_BUSY;
561 
562     /* Get tick */
563     tickstart = HAL_GetTick();
564 
565     /* Check if data register contains valid random data */
566     while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
567     {
568       if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
569       {
570         hrng->State = HAL_RNG_STATE_READY;
571         hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT;
572         /* Process Unlocked */
573         __HAL_UNLOCK(hrng);
574         return HAL_ERROR;
575       }
576     }
577 
578     /* Get a 32bit Random number */
579     hrng->RandomNumber = hrng->Instance->DR;
580     *random32bit = hrng->RandomNumber;
581 
582     hrng->State = HAL_RNG_STATE_READY;
583   }
584   else
585   {
586     status = HAL_ERROR;
587   }
588 
589   /* Process Unlocked */
590   __HAL_UNLOCK(hrng);
591 
592   return status;
593 }
594 
595 /**
596   * @brief  Generates a 32-bit random number in interrupt mode.
597   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
598   *                the configuration information for RNG.
599   * @retval HAL status
600   */
HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef * hrng)601 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
602 {
603   HAL_StatusTypeDef status = HAL_OK;
604 
605   /* Process Locked */
606   __HAL_LOCK(hrng);
607 
608   /* Check RNG peripheral state */
609   if (hrng->State == HAL_RNG_STATE_READY)
610   {
611     /* Change RNG peripheral state */
612     hrng->State = HAL_RNG_STATE_BUSY;
613 
614     /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
615     __HAL_RNG_ENABLE_IT(hrng);
616   }
617   else
618   {
619     /* Process Unlocked */
620     __HAL_UNLOCK(hrng);
621 
622     status = HAL_ERROR;
623   }
624 
625   return status;
626 }
627 
628 /**
629   * @brief  Handles RNG interrupt request.
630   * @note   In the case of a clock error, the RNG is no more able to generate
631   *         random numbers because the PLL48CLK clock is not correct. User has
632   *         to check that the clock controller is correctly configured to provide
633   *         the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
634   *         The clock error has no impact on the previously generated
635   *         random numbers, and the RNG_DR register contents can be used.
636   * @note   In the case of a seed error, the generation of random numbers is
637   *         interrupted as long as the SECS bit is '1'. If a number is
638   *         available in the RNG_DR register, it must not be used because it may
639   *         not have enough entropy. In this case, it is recommended to clear the
640   *         SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
641   *         the RNG peripheral to reinitialize and restart the RNG.
642   * @note   User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
643   *         or CEIS are set.
644   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
645   *                the configuration information for RNG.
646   * @retval None
647 
648   */
HAL_RNG_IRQHandler(RNG_HandleTypeDef * hrng)649 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
650 {
651   uint32_t rngclockerror = 0U;
652 
653   /* RNG clock error interrupt occurred */
654   if (__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET)
655   {
656     rngclockerror = 1U;
657   }
658   else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
659   {
660     rngclockerror = 1U;
661   }
662   else
663   {
664     /* Nothing to do */
665   }
666 
667   if (rngclockerror == 1U)
668   {
669     /* Change RNG peripheral state */
670     hrng->State = HAL_RNG_STATE_ERROR;
671 
672 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
673     /* Call registered Error callback */
674     hrng->ErrorCallback(hrng);
675 #else
676     /* Call legacy weak Error callback */
677     HAL_RNG_ErrorCallback(hrng);
678 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
679 
680     /* Clear the clock error flag */
681     __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
682   }
683 
684   /* Check RNG data ready interrupt occurred */
685   if (__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
686   {
687     /* Generate random number once, so disable the IT */
688     __HAL_RNG_DISABLE_IT(hrng);
689 
690     /* Get the 32bit Random number (DRDY flag automatically cleared) */
691     hrng->RandomNumber = hrng->Instance->DR;
692 
693     if (hrng->State != HAL_RNG_STATE_ERROR)
694     {
695       /* Change RNG peripheral state */
696       hrng->State = HAL_RNG_STATE_READY;
697       /* Process Unlocked */
698       __HAL_UNLOCK(hrng);
699 
700 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
701       /* Call registered Data Ready callback */
702       hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
703 #else
704       /* Call legacy weak Data Ready callback */
705       HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
706 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
707     }
708   }
709 }
710 
711 /**
712   * @brief  Read latest generated random number.
713   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
714   *                the configuration information for RNG.
715   * @retval random value
716   */
HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef * hrng)717 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
718 {
719   return (hrng->RandomNumber);
720 }
721 
722 /**
723   * @brief  Data Ready callback in non-blocking mode.
724   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
725   *                the configuration information for RNG.
726   * @param  random32bit generated random number.
727   * @retval None
728   */
HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef * hrng,uint32_t random32bit)729 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
730 {
731   /* Prevent unused argument(s) compilation warning */
732   UNUSED(hrng);
733   UNUSED(random32bit);
734   /* NOTE : This function should not be modified. When the callback is needed,
735             function HAL_RNG_ReadyDataCallback must be implemented in the user file.
736    */
737 }
738 
739 /**
740   * @brief  RNG error callbacks.
741   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
742   *                the configuration information for RNG.
743   * @retval None
744   */
HAL_RNG_ErrorCallback(RNG_HandleTypeDef * hrng)745 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
746 {
747   /* Prevent unused argument(s) compilation warning */
748   UNUSED(hrng);
749   /* NOTE : This function should not be modified. When the callback is needed,
750             function HAL_RNG_ErrorCallback must be implemented in the user file.
751    */
752 }
753 /**
754   * @}
755   */
756 
757 
758 /** @addtogroup RNG_Exported_Functions_Group3
759  *  @brief   Peripheral State functions
760  *
761 @verbatim
762  ===============================================================================
763                       ##### Peripheral State functions #####
764  ===============================================================================
765     [..]
766     This subsection permits to get in run-time the status of the peripheral
767     and the data flow.
768 
769 @endverbatim
770   * @{
771   */
772 
773 /**
774   * @brief  Returns the RNG state.
775   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
776   *                the configuration information for RNG.
777   * @retval HAL state
778   */
HAL_RNG_GetState(RNG_HandleTypeDef * hrng)779 HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
780 {
781   return hrng->State;
782 }
783 
784 /**
785   * @brief  Return the RNG handle error code.
786   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
787   * @retval RNG Error Code
788 */
HAL_RNG_GetError(RNG_HandleTypeDef * hrng)789 uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
790 {
791   /* Return RNG Error Code */
792   return hrng->ErrorCode;
793 }
794 /**
795   * @}
796   */
797 
798 /**
799   * @}
800   */
801 
802 
803 #endif /* HAL_RNG_MODULE_ENABLED */
804 /**
805   * @}
806   */
807 
808 #endif /* RNG */
809 
810 /**
811   * @}
812   */
813 
814 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
815