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