1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_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/de-initialization 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</center></h2>
85   *
86   * Redistribution and use in source and binary forms, with or without modification,
87   * are permitted provided that the following conditions are met:
88   *   1. Redistributions of source code must retain the above copyright notice,
89   *      this list of conditions and the following disclaimer.
90   *   2. Redistributions in binary form must reproduce the above copyright notice,
91   *      this list of conditions and the following disclaimer in the documentation
92   *      and/or other materials provided with the distribution.
93   *   3. Neither the name of STMicroelectronics nor the names of its contributors
94   *      may be used to endorse or promote products derived from this software
95   *      without specific prior written permission.
96   *
97   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
98   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
99   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
101   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
102   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
103   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
104   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
105   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
106   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107   *
108   ******************************************************************************
109   */
110 
111 /* Includes ------------------------------------------------------------------*/
112 #include "stm32l4xx_hal.h"
113 
114 /** @addtogroup STM32L4xx_HAL_Driver
115   * @{
116   */
117 
118 /** @defgroup RNG RNG
119   * @brief RNG HAL module driver.
120   * @{
121   */
122 
123 #ifdef HAL_RNG_MODULE_ENABLED
124 
125 
126 
127 /* Private types -------------------------------------------------------------*/
128 /* Private defines -----------------------------------------------------------*/
129 /** @defgroup RNG_Private_Constants RNG_Private_Constants
130   * @{
131   */
132 #define RNG_TIMEOUT_VALUE     2
133 /**
134   * @}
135   */
136 
137 /* Private macros ------------------------------------------------------------*/
138 /* Private variables ---------------------------------------------------------*/
139 /* Private function prototypes -----------------------------------------------*/
140 /* Private functions ---------------------------------------------------------*/
141 /* Exported functions --------------------------------------------------------*/
142 
143 /** @addtogroup RNG_Exported_Functions
144   * @{
145   */
146 
147 /** @addtogroup RNG_Exported_Functions_Group1
148  *  @brief   Initialization and de-initialization functions
149  *
150 @verbatim
151  ===============================================================================
152           ##### Initialization and de-initialization functions #####
153  ===============================================================================
154     [..]  This section provides functions allowing to:
155       (+) Initialize the RNG according to the specified parameters
156           in the RNG_InitTypeDef and create the associated handle
157       (+) DeInitialize the RNG peripheral
158       (+) Initialize the RNG MSP (MCU Specific Package)
159       (+) DeInitialize the RNG MSP
160 
161 @endverbatim
162   * @{
163   */
164 
165 /**
166   * @brief  Initialize the RNG peripheral and initialize the associated handle.
167   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
168   * @retval HAL status
169   */
HAL_RNG_Init(RNG_HandleTypeDef * hrng)170 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
171 {
172   /* Check the RNG handle allocation */
173   if(hrng == NULL)
174   {
175     return HAL_ERROR;
176   }
177 
178   assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
179 #if defined(RNG_CR_CED)
180   assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
181 #endif /* defined(RNG_CR_CED) */
182 
183 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
184   if(hrng->State == HAL_RNG_STATE_RESET)
185   {
186     /* Allocate lock resource and initialize it */
187     hrng->Lock = HAL_UNLOCKED;
188 
189     hrng->ReadyDataCallback  = HAL_RNG_ReadyDataCallback;  /* Legacy weak ReadyDataCallback  */
190     hrng->ErrorCallback      = HAL_RNG_ErrorCallback;      /* Legacy weak ErrorCallback      */
191 
192     if(hrng->MspInitCallback == NULL)
193     {
194       hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit  */
195     }
196 
197     /* Init the low level hardware */
198     hrng->MspInitCallback(hrng);
199   }
200 #else
201   if(hrng->State == HAL_RNG_STATE_RESET)
202   {
203     /* Allocate lock resource and initialize it */
204     hrng->Lock = HAL_UNLOCKED;
205 
206     /* Init the low level hardware */
207     HAL_RNG_MspInit(hrng);
208   }
209 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
210 
211   /* Change RNG peripheral state */
212   hrng->State = HAL_RNG_STATE_BUSY;
213 
214 #if defined(RNG_CR_CED)
215   /* Clock Error Detection configuration */
216   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
217 #endif /* defined(RNG_CR_CED) */
218 
219   /* Enable the RNG Peripheral */
220   __HAL_RNG_ENABLE(hrng);
221 
222   /* Initialize the RNG state */
223   hrng->State = HAL_RNG_STATE_READY;
224 
225   /* Initialise the error code */
226   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
227 
228   /* Return function status */
229   return HAL_OK;
230 }
231 
232 /**
233   * @brief  DeInitialize the RNG peripheral.
234   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
235   * @retval HAL status
236   */
HAL_RNG_DeInit(RNG_HandleTypeDef * hrng)237 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
238 {
239   /* Check the RNG handle allocation */
240   if(hrng == NULL)
241   {
242     return HAL_ERROR;
243   }
244 
245 #if defined(RNG_CR_CED)
246   /* Clear Clock Error Detection bit */
247   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
248 #endif /* defined(RNG_CR_CED) */
249 
250   /* Disable the RNG Peripheral */
251   CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
252 
253   /* Clear RNG interrupt status flags */
254   CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
255 
256 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
257   if(hrng->MspDeInitCallback == NULL)
258   {
259     hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit  */
260   }
261 
262   /* DeInit the low level hardware */
263   hrng->MspDeInitCallback(hrng);
264 #else
265   /* DeInit the low level hardware */
266   HAL_RNG_MspDeInit(hrng);
267 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
268 
269   /* Update the RNG state */
270   hrng->State = HAL_RNG_STATE_RESET;
271 
272   /* Initialise the error code */
273   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
274 
275   /* Release Lock */
276   __HAL_UNLOCK(hrng);
277 
278   /* Return the function status */
279   return HAL_OK;
280 }
281 
282 /**
283   * @brief  Initialize the RNG MSP.
284   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
285   * @retval None
286   */
HAL_RNG_MspInit(RNG_HandleTypeDef * hrng)287 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
288 {
289   /* Prevent unused argument(s) compilation warning */
290   UNUSED(hrng);
291 
292   /* NOTE : This function should not be modified. When the callback is needed,
293             function HAL_RNG_MspInit must be implemented in the user file.
294    */
295 }
296 
297 /**
298   * @brief  DeInitialize the RNG MSP.
299   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
300   * @retval None
301   */
HAL_RNG_MspDeInit(RNG_HandleTypeDef * hrng)302 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
303 {
304   /* Prevent unused argument(s) compilation warning */
305   UNUSED(hrng);
306 
307   /* NOTE : This function should not be modified. When the callback is needed,
308             function HAL_RNG_MspDeInit must be implemented in the user file.
309    */
310 }
311 
312 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
313 /**
314   * @brief  Register a User RNG Callback
315   *         To be used instead of the weak predefined callback
316   * @param  hrng RNG handle
317   * @param  CallbackID ID of the callback to be registered
318   *         This parameter can be one of the following values:
319   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
320   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
321   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
322   * @param  pCallback pointer to the Callback function
323   * @retval HAL status
324   */
HAL_RNG_RegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID,pRNG_CallbackTypeDef pCallback)325 HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
326 {
327   HAL_StatusTypeDef status = HAL_OK;
328 
329   if(pCallback == NULL)
330   {
331     /* Update the error code */
332     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
333     return HAL_ERROR;
334   }
335   /* Process locked */
336   __HAL_LOCK(hrng);
337 
338   if(HAL_RNG_STATE_READY == hrng->State)
339   {
340     switch (CallbackID)
341     {
342     case HAL_RNG_ERROR_CB_ID :
343       hrng->ErrorCallback = pCallback;
344       break;
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 if(HAL_RNG_STATE_RESET == hrng->State)
363   {
364     switch (CallbackID)
365     {
366     case HAL_RNG_MSPINIT_CB_ID :
367       hrng->MspInitCallback = pCallback;
368       break;
369 
370     case HAL_RNG_MSPDEINIT_CB_ID :
371       hrng->MspDeInitCallback = pCallback;
372       break;
373 
374     default :
375       /* Update the error code */
376       hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
377      /* Return error status */
378       status =  HAL_ERROR;
379       break;
380     }
381   }
382   else
383   {
384     /* Update the error code */
385     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
386     /* Return error status */
387     status =  HAL_ERROR;
388   }
389 
390   /* Release Lock */
391   __HAL_UNLOCK(hrng);
392   return status;
393 }
394 
395 /**
396   * @brief  Unregister an RNG Callback
397   *         RNG callabck is redirected to the weak predefined callback
398   * @param  hrng RNG handle
399   * @param  CallbackID ID of the callback to be unregistered
400   *         This parameter can be one of the following values:
401   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
402   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
403   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
404   * @retval HAL status
405   */
HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID)406 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
407 {
408 HAL_StatusTypeDef status = HAL_OK;
409 
410   /* Process locked */
411   __HAL_LOCK(hrng);
412 
413   if(HAL_RNG_STATE_READY == hrng->State)
414   {
415     switch (CallbackID)
416     {
417     case HAL_RNG_ERROR_CB_ID :
418       hrng->ErrorCallback = HAL_RNG_ErrorCallback;          /* Legacy weak ErrorCallback  */
419       break;
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 MspDeInit  */
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 if(HAL_RNG_STATE_RESET == hrng->State)
438   {
439     switch (CallbackID)
440     {
441     case HAL_RNG_MSPINIT_CB_ID :
442       hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
443       break;
444 
445     case HAL_RNG_MSPDEINIT_CB_ID :
446       hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspInit  */
447       break;
448 
449     default :
450       /* Update the error code */
451       hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
452      /* Return error status */
453       status =  HAL_ERROR;
454       break;
455     }
456   }
457   else
458   {
459     /* Update the error code */
460     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
461     /* Return error status */
462     status =  HAL_ERROR;
463   }
464 
465   /* Release Lock */
466   __HAL_UNLOCK(hrng);
467   return status;
468 }
469 
470 /**
471   * @brief  Register Data Ready RNG Callback
472   *         To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
473   * @param  hrng RNG handle
474   * @param  pCallback pointer to the Data Ready Callback function
475   * @retval HAL status
476   */
HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef * hrng,pRNG_ReadyDataCallbackTypeDef pCallback)477 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
478 {
479   HAL_StatusTypeDef status = HAL_OK;
480 
481   if(pCallback == NULL)
482   {
483     /* Update the error code */
484     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
485     return HAL_ERROR;
486   }
487   /* Process locked */
488   __HAL_LOCK(hrng);
489 
490   if(HAL_RNG_STATE_READY == hrng->State)
491   {
492     hrng->ReadyDataCallback = pCallback;
493   }
494   else
495   {
496     /* Update the error code */
497     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
498     /* Return error status */
499     status =  HAL_ERROR;
500   }
501 
502   /* Release Lock */
503   __HAL_UNLOCK(hrng);
504   return status;
505 }
506 
507 /**
508   * @brief  UnRegister the Data Ready RNG Callback
509   *         Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
510   * @param  hrng RNG handle
511   * @retval HAL status
512   */
HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef * hrng)513 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
514 {
515   HAL_StatusTypeDef status = HAL_OK;
516 
517   /* Process locked */
518   __HAL_LOCK(hrng);
519 
520   if(HAL_RNG_STATE_READY == hrng->State)
521   {
522     hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback  */
523   }
524   else
525   {
526     /* Update the error code */
527     hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
528     /* Return error status */
529     status =  HAL_ERROR;
530   }
531 
532   /* Release Lock */
533   __HAL_UNLOCK(hrng);
534   return status;
535 }
536 
537 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
538 
539 /**
540   * @}
541   */
542 
543 /** @addtogroup RNG_Exported_Functions_Group2
544  *  @brief    Management functions.
545  *
546 @verbatim
547  ===============================================================================
548                       ##### Peripheral Control functions #####
549  ===============================================================================
550     [..]  This section provides functions allowing to:
551       (+) Get the 32 bit Random number
552       (+) Get the 32 bit Random number with interrupt enabled
553       (+) Handle RNG interrupt request
554 
555 @endverbatim
556   * @{
557   */
558 
559 /**
560   * @brief  Generate a 32-bit random number.
561   * @note   Each time the random number data is read the RNG_FLAG_DRDY flag
562   *         is automatically cleared.
563   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
564   * @param  random32bit: pointer to generated random number variable if successful.
565   * @retval HAL status
566   */
567 
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef * hrng,uint32_t * random32bit)568 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
569 {
570   uint32_t tickstart = 0;
571   HAL_StatusTypeDef status = HAL_OK;
572 
573   /* Process Locked */
574   __HAL_LOCK(hrng);
575 
576   /* Check RNS peripheral state */
577   if(hrng->State == HAL_RNG_STATE_READY)
578   {
579     /* Change RNG peripheral state */
580     hrng->State = HAL_RNG_STATE_BUSY;
581 
582     /* Get tick */
583     tickstart = HAL_GetTick();
584 
585     /* Check if data register contains valid random data */
586     while(__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
587     {
588       if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE)
589       {
590         hrng->State = HAL_RNG_STATE_ERROR;
591 
592         /* Process Unlocked */
593         __HAL_UNLOCK(hrng);
594 
595         return HAL_TIMEOUT;
596       }
597     }
598 
599     /* Get a 32bit Random number */
600     hrng->RandomNumber = hrng->Instance->DR;
601     *random32bit = hrng->RandomNumber;
602 
603     hrng->State = HAL_RNG_STATE_READY;
604   }
605   else
606   {
607     status = HAL_ERROR;
608   }
609 
610   /* Process Unlocked */
611   __HAL_UNLOCK(hrng);
612 
613   return status;
614 }
615 
616 /**
617   * @brief  Generate a 32-bit random number in interrupt mode.
618   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
619   * @retval HAL status
620   */
HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef * hrng)621 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
622 {
623   HAL_StatusTypeDef status = HAL_OK;
624 
625   /* Process Locked */
626   __HAL_LOCK(hrng);
627 
628   /* Check RNG peripheral state */
629   if(hrng->State == HAL_RNG_STATE_READY)
630   {
631     /* Change RNG peripheral state */
632     hrng->State = HAL_RNG_STATE_BUSY;
633 
634     /* Process Unlocked */
635     __HAL_UNLOCK(hrng);
636 
637     /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
638     __HAL_RNG_ENABLE_IT(hrng);
639   }
640   else
641   {
642     /* Process Unlocked */
643     __HAL_UNLOCK(hrng);
644 
645     status = HAL_ERROR;
646   }
647 
648   return status;
649 }
650 
651 /**
652   * @brief  Handle RNG interrupt request.
653   * @note   In the case of a clock error, the RNG is no more able to generate
654   *         random numbers because the PLL48CLK clock is not correct. User has
655   *         to check that the clock controller is correctly configured to provide
656   *         the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
657   *         The clock error has no impact on the previously generated
658   *         random numbers, and the RNG_DR register contents can be used.
659   * @note   In the case of a seed error, the generation of random numbers is
660   *         interrupted as long as the SECS bit is '1'. If a number is
661   *         available in the RNG_DR register, it must not be used because it may
662   *         not have enough entropy. In this case, it is recommended to clear the
663   *         SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
664   *         the RNG peripheral to reinitialize and restart the RNG.
665   * @note   RNG ErrorCallback() API is called once whether SEIS or CEIS are set.
666   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
667   * @retval None
668 
669   */
HAL_RNG_IRQHandler(RNG_HandleTypeDef * hrng)670 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
671 {
672   /* RNG clock error interrupt occurred */
673   if((__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET) ||  (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET))
674   {
675     /* Change RNG peripheral state */
676     hrng->State = HAL_RNG_STATE_ERROR;
677 
678 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
679     /* Call registered Error callback */
680     hrng->ErrorCallback(hrng);
681 #else
682     /* Call legacy weak Error callback */
683     HAL_RNG_ErrorCallback(hrng);
684 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
685 
686     /* Clear the clock error flag */
687     __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI|RNG_IT_SEI);
688 
689   }
690 
691   /* Check RNG data ready interrupt occurred */
692   if(__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
693   {
694     /* Generate random number once, so disable the IT */
695     __HAL_RNG_DISABLE_IT(hrng);
696 
697     /* Get the 32bit Random number (DRDY flag automatically cleared) */
698     hrng->RandomNumber = hrng->Instance->DR;
699 
700     if(hrng->State != HAL_RNG_STATE_ERROR)
701     {
702       /* Change RNG peripheral state */
703       hrng->State = HAL_RNG_STATE_READY;
704 
705 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
706       /* Call registered Data Ready callback */
707       hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
708 #else
709       /* Call legacy weak Data Ready callback */
710       HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
711 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
712     }
713   }
714 }
715 
716 /**
717   * @brief  Return generated random number in polling mode (Obsolete).
718   * @note   Use HAL_RNG_GenerateRandomNumber() API instead.
719   * @param  hrng: pointer to a RNG_HandleTypeDef structure that contains
720   *                the configuration information for RNG.
721   * @retval random value
722   */
HAL_RNG_GetRandomNumber(RNG_HandleTypeDef * hrng)723 uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
724 {
725   if(HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
726   {
727     return hrng->RandomNumber;
728   }
729   else
730   {
731     return 0;
732   }
733 }
734 
735 
736 /**
737   * @brief  Return a 32-bit random number with interrupt enabled (Obsolete).
738   * @note   Use HAL_RNG_GenerateRandomNumber_IT() API instead.
739   * @param  hrng: RNG handle
740   * @retval 32-bit random number
741   */
HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef * hrng)742 uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
743 {
744   uint32_t random32bit = 0;
745 
746   /* Process locked */
747   __HAL_LOCK(hrng);
748 
749   /* Change RNG peripheral state */
750   hrng->State = HAL_RNG_STATE_BUSY;
751 
752   /* Get a 32bit Random number */
753   random32bit = hrng->Instance->DR;
754 
755   /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
756   __HAL_RNG_ENABLE_IT(hrng);
757 
758   /* Return the 32 bit random number */
759   return random32bit;
760 }
761 
762 
763 
764 /**
765   * @brief  Read latest generated random number.
766   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
767   * @retval random value
768   */
HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef * hrng)769 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
770 {
771   return(hrng->RandomNumber);
772 }
773 
774 /**
775   * @brief  Data Ready callback in non-blocking mode.
776   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
777   * @param  random32bit: generated random value
778   * @retval None
779   */
HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef * hrng,uint32_t random32bit)780 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
781 {
782   /* Prevent unused argument(s) compilation warning */
783   UNUSED(hrng);
784   UNUSED(random32bit);
785 
786   /* NOTE : This function should not be modified. When the callback is needed,
787             function HAL_RNG_ReadyDataCallback must be implemented in the user file.
788    */
789 }
790 
791 /**
792   * @brief  RNG error callback.
793   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
794   * @retval None
795   */
HAL_RNG_ErrorCallback(RNG_HandleTypeDef * hrng)796 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
797 {
798   /* Prevent unused argument(s) compilation warning */
799   UNUSED(hrng);
800 
801   /* NOTE : This function should not be modified. When the callback is needed,
802             function HAL_RNG_ErrorCallback must be implemented in the user file.
803    */
804 }
805 
806 /**
807   * @}
808   */
809 
810 /** @addtogroup RNG_Exported_Functions_Group3
811  *  @brief    Peripheral State functions.
812  *
813 @verbatim
814  ===============================================================================
815                 ##### Peripheral State and Error functions #####
816  ===============================================================================
817     [..]
818     This subsection permits to :
819       (+) Return in run-time the status of the peripheral.
820       (+) Return the RNG handle error code
821 
822 @endverbatim
823   * @{
824   */
825 
826 /**
827   * @brief  Return the RNG handle state.
828   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
829   * @retval HAL state
830   */
HAL_RNG_GetState(RNG_HandleTypeDef * hrng)831 HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
832 {
833   /* Return RNG handle state */
834   return hrng->State;
835 }
836 
837 /**
838   * @brief  Return the RNG handle error code.
839   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
840   * @retval RNG Error Code
841 */
HAL_RNG_GetError(RNG_HandleTypeDef * hrng)842 uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
843 {
844   /* Return RNG Error Code */
845   return hrng->ErrorCode;
846 }
847 /**
848   * @}
849   */
850 
851 /**
852   * @}
853   */
854 
855 
856 #endif /* HAL_RNG_MODULE_ENABLED */
857 /**
858   * @}
859   */
860 
861 /**
862   * @}
863   */
864 
865 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
866