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