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 and configuration functions
9   *           + Peripheral Control functions
10   *           + Peripheral State functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2017 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                      ##### How to use this driver #####
26   ==============================================================================
27   [..]
28       The RNG HAL driver can be used as follows:
29 
30       (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro
31           in HAL_RNG_MspInit().
32       (#) Activate the RNG peripheral using HAL_RNG_Init() function.
33       (#) Wait until the 32 bit Random Number Generator contains a valid
34           random data using (polling/interrupt) mode.
35       (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function.
36 
37     ##### Callback registration #####
38     ==================================
39 
40     [..]
41     The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1
42     allows the user to configure dynamically the driver callbacks.
43 
44     [..]
45     Use Function HAL_RNG_RegisterCallback() to register a user callback.
46     Function HAL_RNG_RegisterCallback() allows to register following callbacks:
47     (+) ErrorCallback             : RNG Error Callback.
48     (+) MspInitCallback           : RNG MspInit.
49     (+) MspDeInitCallback         : RNG MspDeInit.
50     This function takes as parameters the HAL peripheral handle, the Callback ID
51     and a pointer to the user callback function.
52 
53     [..]
54     Use function HAL_RNG_UnRegisterCallback() to reset a callback to the default
55     weak (surcharged) function.
56     HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle,
57     and the Callback ID.
58     This function allows to reset following callbacks:
59     (+) ErrorCallback             : RNG Error Callback.
60     (+) MspInitCallback           : RNG MspInit.
61     (+) MspDeInitCallback         : RNG MspDeInit.
62 
63     [..]
64     For specific callback ReadyDataCallback, use dedicated register callbacks:
65     respectively HAL_RNG_RegisterReadyDataCallback() , HAL_RNG_UnRegisterReadyDataCallback().
66 
67     [..]
68     By default, after the HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET
69     all callbacks are set to the corresponding weak (surcharged) functions:
70     example HAL_RNG_ErrorCallback().
71     Exception done for MspInit and MspDeInit functions that are respectively
72     reset to the legacy weak (surcharged) functions in the HAL_RNG_Init()
73     and HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand).
74     If not, MspInit or MspDeInit are not null, the HAL_RNG_Init() and HAL_RNG_DeInit()
75     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
76 
77     [..]
78     Callbacks can be registered/unregistered in HAL_RNG_STATE_READY state only.
79     Exception done MspInit/MspDeInit that can be registered/unregistered
80     in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user)
81     MspInit/DeInit callbacks can be used during the Init/DeInit.
82     In that case first register the MspInit/MspDeInit user callbacks
83     using  HAL_RNG_RegisterCallback() before calling HAL_RNG_DeInit()
84     or HAL_RNG_Init() function.
85 
86     [..]
87     When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or
88     not defined, the callback registration feature is not available
89     and weak (surcharged) callbacks are used.
90 
91   @endverbatim
92   ******************************************************************************
93   */
94 
95 /* Includes ------------------------------------------------------------------*/
96 #include "stm32l4xx_hal.h"
97 
98 /** @addtogroup STM32L4xx_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   uint32_t tickstart;
158 #if defined(RNG_CR_CONDRST)
159   uint32_t cr_value;
160 #endif  /* RNG_CR_CONDRST */
161   /* Check the RNG handle allocation */
162   if (hrng == NULL)
163   {
164     return HAL_ERROR;
165   }
166   /* Check the parameters */
167   assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
168 #if defined(RNG_CR_CED)
169   assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
170 #endif /* defined(RNG_CR_CED) */
171 
172 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
173   if (hrng->State == HAL_RNG_STATE_RESET)
174   {
175     /* Allocate lock resource and initialize it */
176     hrng->Lock = HAL_UNLOCKED;
177 
178     hrng->ReadyDataCallback  = HAL_RNG_ReadyDataCallback;  /* Legacy weak ReadyDataCallback  */
179     hrng->ErrorCallback      = HAL_RNG_ErrorCallback;      /* Legacy weak ErrorCallback      */
180 
181     if (hrng->MspInitCallback == NULL)
182     {
183       hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit  */
184     }
185 
186     /* Init the low level hardware */
187     hrng->MspInitCallback(hrng);
188   }
189 #else
190   if (hrng->State == HAL_RNG_STATE_RESET)
191   {
192     /* Allocate lock resource and initialize it */
193     hrng->Lock = HAL_UNLOCKED;
194 
195     /* Init the low level hardware */
196     HAL_RNG_MspInit(hrng);
197   }
198 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
199 
200   /* Change RNG peripheral state */
201   hrng->State = HAL_RNG_STATE_BUSY;
202 
203 #if defined(RNG_CR_CONDRST)
204   /* Disable RNG */
205   __HAL_RNG_DISABLE(hrng);
206 
207   /* RNG CR register configuration. Set value in CR register for CONFIG 1, CONFIG 2 and CONFIG 3 values */
208   cr_value = (uint32_t) (RNG_CR_CONFIG_VAL);
209 
210   /* Configuration of
211      - Clock Error Detection
212      - CONFIG1, CONFIG2, CONFIG3 fields
213      when CONDRT bit is set to 1 */
214   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST | RNG_CR_RNG_CONFIG1
215                                  | RNG_CR_RNG_CONFIG2 | RNG_CR_RNG_CONFIG3,
216                                  (uint32_t) (RNG_CR_CONDRST | hrng->Init.ClockErrorDetection | cr_value));
217 
218 #if defined(RNG_VER_3_2) || defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
219   /*!< magic number must be written immediately before to RNG_HTCRG */
220   WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG_1);
221   /* for best latency and to be compliant with NIST */
222   WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG);
223 #endif /* RNG_VER_3_2 || RNG_VER_3_1 || RNG_VER_3_0 */
224 
225   /* Writing bits CONDRST=0*/
226   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
227 
228   /* Get tick */
229   tickstart = HAL_GetTick();
230 
231   /* Wait for conditioning reset process to be completed */
232   while(HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
233   {
234     if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE)
235     {
236       /* New check to avoid false timeout detection in case of preemption */
237       if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
238       {
239         hrng->State = HAL_RNG_STATE_READY;
240         hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
241         return HAL_ERROR;
242       }
243     }
244   }
245 #else
246 #if defined(RNG_CR_CED)
247   /* Clock Error Detection Configuration */
248   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
249 #endif /* defined(RNG_CR_CED) */
250 #endif /* end of RNG_CR_CONDRST */
251 
252   /* Enable the RNG Peripheral */
253   __HAL_RNG_ENABLE(hrng);
254 
255   /* verify that no seed error */
256   if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
257   {
258     hrng->State = HAL_RNG_STATE_ERROR;
259     return HAL_ERROR;
260   }
261   /* Get tick */
262   tickstart = HAL_GetTick();
263   /* Check if data register contains valid random data */
264   while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
265   {
266     if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
267     {
268       /* New check to avoid false timeout detection in case of preemption */
269       if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
270       {
271         hrng->State = HAL_RNG_STATE_ERROR;
272         hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
273         return HAL_ERROR;
274       }
275     }
276   }
277 
278   /* Initialize the RNG state */
279   hrng->State = HAL_RNG_STATE_READY;
280 
281   /* Initialise the error code */
282   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
283 
284   /* Return function status */
285   return HAL_OK;
286 }
287 
288 /**
289   * @brief  DeInitializes the RNG peripheral.
290   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
291   *                the configuration information for RNG.
292   * @retval HAL status
293   */
HAL_RNG_DeInit(RNG_HandleTypeDef * hrng)294 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
295 {
296 #if defined(RNG_CR_CONDRST)
297   uint32_t tickstart;
298 #endif
299   /* Check the RNG handle allocation */
300   if (hrng == NULL)
301   {
302     return HAL_ERROR;
303   }
304 
305 #if defined(RNG_CR_CONDRST)
306   /* Clear Clock Error Detection bit when CONDRT bit is set to 1 */
307   MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST);
308 
309   /* Writing bits CONDRST=0*/
310   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
311 
312   /* Get tick */
313   tickstart = HAL_GetTick();
314 
315   /* Wait for conditioning reset process to be completed */
316   while(HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
317   {
318     if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE)
319     {
320       /* New check to avoid false timeout detection in case of preemption */
321       if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
322       {
323         hrng->State = HAL_RNG_STATE_READY;
324         hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
325         /* Process Unlocked */
326         __HAL_UNLOCK(hrng);
327         return HAL_ERROR;
328       }
329     }
330   }
331 #else
332 #if defined(RNG_CR_CED)
333   /* Clear Clock Error Detection bit */
334   CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
335 #endif /* RNG_CR_CED */
336 #endif /* RNG_CR_CONDRST */
337   /* Disable the RNG Peripheral */
338   CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
339 
340   /* Clear RNG interrupt status flags */
341   CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
342 
343 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
344   if (hrng->MspDeInitCallback == NULL)
345   {
346     hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit  */
347   }
348 
349   /* DeInit the low level hardware */
350   hrng->MspDeInitCallback(hrng);
351 #else
352   /* DeInit the low level hardware */
353   HAL_RNG_MspDeInit(hrng);
354 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
355 
356   /* Update the RNG state */
357   hrng->State = HAL_RNG_STATE_RESET;
358 
359   /* Initialise the error code */
360   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
361 
362   /* Release Lock */
363   __HAL_UNLOCK(hrng);
364 
365   /* Return the function status */
366   return HAL_OK;
367 }
368 
369 /**
370   * @brief  Initializes the RNG MSP.
371   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
372   *                the configuration information for RNG.
373   * @retval None
374   */
HAL_RNG_MspInit(RNG_HandleTypeDef * hrng)375 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
376 {
377   /* Prevent unused argument(s) compilation warning */
378   UNUSED(hrng);
379   /* NOTE : This function should not be modified. When the callback is needed,
380             function HAL_RNG_MspInit must be implemented in the user file.
381    */
382 }
383 
384 /**
385   * @brief  DeInitializes the RNG MSP.
386   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
387   *                the configuration information for RNG.
388   * @retval None
389   */
HAL_RNG_MspDeInit(RNG_HandleTypeDef * hrng)390 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
391 {
392   /* Prevent unused argument(s) compilation warning */
393   UNUSED(hrng);
394   /* NOTE : This function should not be modified. When the callback is needed,
395             function HAL_RNG_MspDeInit must be implemented in the user file.
396    */
397 }
398 
399 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
400 /**
401   * @brief  Register a User RNG Callback
402   *         To be used instead of the weak predefined callback
403   * @param  hrng RNG handle
404   * @param  CallbackID ID of the callback to be registered
405   *         This parameter can be one of the following values:
406   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
407   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
408   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
409   * @param  pCallback pointer to the Callback function
410   * @retval HAL status
411   */
HAL_RNG_RegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID,pRNG_CallbackTypeDef pCallback)412 HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
413 {
414   HAL_StatusTypeDef status = HAL_OK;
415 
416   if (pCallback == NULL)
417   {
418     /* Update the error code */
419     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
420     return HAL_ERROR;
421   }
422   /* Process locked */
423   __HAL_LOCK(hrng);
424 
425   if (HAL_RNG_STATE_READY == hrng->State)
426   {
427     switch (CallbackID)
428     {
429     case HAL_RNG_ERROR_CB_ID :
430       hrng->ErrorCallback = pCallback;
431       break;
432 
433     case HAL_RNG_MSPINIT_CB_ID :
434       hrng->MspInitCallback = pCallback;
435       break;
436 
437     case HAL_RNG_MSPDEINIT_CB_ID :
438       hrng->MspDeInitCallback = pCallback;
439       break;
440 
441     default :
442       /* Update the error code */
443       hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
444      /* Return error status */
445       status =  HAL_ERROR;
446       break;
447     }
448   }
449   else if (HAL_RNG_STATE_RESET == hrng->State)
450   {
451     switch (CallbackID)
452     {
453     case HAL_RNG_MSPINIT_CB_ID :
454       hrng->MspInitCallback = pCallback;
455       break;
456 
457     case HAL_RNG_MSPDEINIT_CB_ID :
458       hrng->MspDeInitCallback = pCallback;
459       break;
460 
461     default :
462       /* Update the error code */
463       hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
464      /* Return error status */
465       status =  HAL_ERROR;
466       break;
467     }
468   }
469   else
470   {
471     /* Update the error code */
472     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
473     /* Return error status */
474     status =  HAL_ERROR;
475   }
476 
477   /* Release Lock */
478   __HAL_UNLOCK(hrng);
479   return status;
480 }
481 
482 /**
483   * @brief  Unregister an RNG Callback
484   *         RNG callabck is redirected to the weak predefined callback
485   * @param  hrng RNG handle
486   * @param  CallbackID ID of the callback to be unregistered
487   *         This parameter can be one of the following values:
488   *          @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
489   *          @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
490   *          @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
491   * @retval HAL status
492   */
HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID)493 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
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     switch (CallbackID)
503     {
504     case HAL_RNG_ERROR_CB_ID :
505       hrng->ErrorCallback = HAL_RNG_ErrorCallback;          /* Legacy weak ErrorCallback  */
506       break;
507 
508     case HAL_RNG_MSPINIT_CB_ID :
509       hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
510       break;
511 
512     case HAL_RNG_MSPDEINIT_CB_ID :
513       hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspDeInit  */
514       break;
515 
516     default :
517       /* Update the error code */
518       hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
519      /* Return error status */
520       status =  HAL_ERROR;
521       break;
522     }
523   }
524   else if (HAL_RNG_STATE_RESET == hrng->State)
525   {
526     switch (CallbackID)
527     {
528     case HAL_RNG_MSPINIT_CB_ID :
529       hrng->MspInitCallback = HAL_RNG_MspInit;              /* Legacy weak MspInit  */
530       break;
531 
532     case HAL_RNG_MSPDEINIT_CB_ID :
533       hrng->MspDeInitCallback = HAL_RNG_MspDeInit;          /* Legacy weak MspInit  */
534       break;
535 
536     default :
537       /* Update the error code */
538       hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
539      /* Return error status */
540       status =  HAL_ERROR;
541       break;
542     }
543   }
544   else
545   {
546     /* Update the error code */
547     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
548     /* Return error status */
549     status =  HAL_ERROR;
550   }
551 
552   /* Release Lock */
553   __HAL_UNLOCK(hrng);
554   return status;
555 }
556 
557 /**
558   * @brief  Register Data Ready RNG Callback
559   *         To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
560   * @param  hrng RNG handle
561   * @param  pCallback pointer to the Data Ready Callback function
562   * @retval HAL status
563   */
HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef * hrng,pRNG_ReadyDataCallbackTypeDef pCallback)564 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
565 {
566   HAL_StatusTypeDef status = HAL_OK;
567 
568   if (pCallback == NULL)
569   {
570     /* Update the error code */
571     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
572     return HAL_ERROR;
573   }
574   /* Process locked */
575   __HAL_LOCK(hrng);
576 
577   if (HAL_RNG_STATE_READY == hrng->State)
578   {
579     hrng->ReadyDataCallback = pCallback;
580   }
581   else
582   {
583     /* Update the error code */
584     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
585     /* Return error status */
586     status =  HAL_ERROR;
587   }
588 
589   /* Release Lock */
590   __HAL_UNLOCK(hrng);
591   return status;
592 }
593 
594 /**
595   * @brief  UnRegister the Data Ready RNG Callback
596   *         Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
597   * @param  hrng RNG handle
598   * @retval HAL status
599   */
HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef * hrng)600 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
601 {
602   HAL_StatusTypeDef status = HAL_OK;
603 
604   /* Process locked */
605   __HAL_LOCK(hrng);
606 
607   if (HAL_RNG_STATE_READY == hrng->State)
608   {
609     hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback  */
610   }
611   else
612   {
613     /* Update the error code */
614     hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
615     /* Return error status */
616     status =  HAL_ERROR;
617   }
618 
619   /* Release Lock */
620   __HAL_UNLOCK(hrng);
621   return status;
622 }
623 
624 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
625 
626 /**
627   * @}
628   */
629 
630 /** @addtogroup RNG_Exported_Functions_Group2
631  *  @brief   Peripheral Control functions
632  *
633 @verbatim
634  ===============================================================================
635                       ##### Peripheral Control functions #####
636  ===============================================================================
637     [..]  This section provides functions allowing to:
638       (+) Get the 32 bit Random number
639       (+) Get the 32 bit Random number with interrupt enabled
640       (+) Handle RNG interrupt request
641 
642 @endverbatim
643   * @{
644   */
645 
646 /**
647   * @brief  Generates a 32-bit random number.
648   * @note   When several random data are output at the same time in an output buffer,
649   *         this function checks value of RNG_FLAG_DRDY flag to know if valid
650   *         random number is available in the DR register (RNG_FLAG_DRDY flag set
651   *         whenever a random number is available through the RNG_DR register).
652   *         After transitioning from 0 to 1 (random number available),
653   *         RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading
654   *         four words from the RNG_DR register, i.e. further function calls
655   *         will immediately return a new u32 random number (additional words are
656   *         available and can be read by the application, till RNG_FLAG_DRDY flag remains high).
657   *         When no more random number data is available in DR register, RNG_FLAG_DRDY
658   *         flag is automatically cleared.
659   *         When random number are out on a single sample basis, each time the random
660   *         number data is read the RNG_FLAG_DRDY flag is automatically cleared.
661   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
662   *                the configuration information for RNG.
663   * @param  random32bit pointer to generated random number variable if successful.
664   * @retval HAL status
665   */
666 
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef * hrng,uint32_t * random32bit)667 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
668 {
669   uint32_t tickstart;
670   HAL_StatusTypeDef status = HAL_OK;
671 
672   /* Process Locked */
673   __HAL_LOCK(hrng);
674 
675   /* Check RNG peripheral state */
676   if (hrng->State == HAL_RNG_STATE_READY)
677   {
678     /* Change RNG peripheral state */
679     hrng->State = HAL_RNG_STATE_BUSY;
680 
681     /* Get tick */
682     tickstart = HAL_GetTick();
683 
684     /* Check if data register contains valid random data */
685     while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
686     {
687       if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
688       {
689         hrng->State = HAL_RNG_STATE_READY;
690         hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
691         /* Process Unlocked */
692         __HAL_UNLOCK(hrng);
693         return HAL_ERROR;
694       }
695     }
696 
697     /* Get a 32bit Random number */
698     hrng->RandomNumber = hrng->Instance->DR;
699     *random32bit = hrng->RandomNumber;
700 
701     hrng->State = HAL_RNG_STATE_READY;
702   }
703   else
704   {
705     hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
706     status = HAL_ERROR;
707   }
708 
709   /* Process Unlocked */
710   __HAL_UNLOCK(hrng);
711 
712   return status;
713 }
714 
715 /**
716   * @brief  Generates a 32-bit random number in interrupt mode.
717   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
718   *                the configuration information for RNG.
719   * @retval HAL status
720   */
HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef * hrng)721 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
722 {
723   HAL_StatusTypeDef status = HAL_OK;
724 
725   /* Process Locked */
726   __HAL_LOCK(hrng);
727 
728   /* Check RNG peripheral state */
729   if (hrng->State == HAL_RNG_STATE_READY)
730   {
731     /* Change RNG peripheral state */
732     hrng->State = HAL_RNG_STATE_BUSY;
733 
734     /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
735     __HAL_RNG_ENABLE_IT(hrng);
736   }
737   else
738   {
739     /* Process Unlocked */
740     __HAL_UNLOCK(hrng);
741 
742     hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
743     status = HAL_ERROR;
744   }
745 
746   return status;
747 }
748 
749 /**
750   * @brief  Returns generated random number in polling mode (Obsolete)
751   *         Use HAL_RNG_GenerateRandomNumber() API instead.
752   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
753   *                the configuration information for RNG.
754   * @retval Random value
755   */
HAL_RNG_GetRandomNumber(RNG_HandleTypeDef * hrng)756 uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
757 {
758   if(HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
759   {
760     return hrng->RandomNumber;
761   }
762   else
763   {
764     return 0U;
765   }
766 }
767 
768 /**
769   * @brief  Returns a 32-bit random number with interrupt enabled (Obsolete),
770   *         Use HAL_RNG_GenerateRandomNumber_IT() API instead.
771   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
772   *                the configuration information for RNG.
773   * @retval 32-bit random number
774   */
HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef * hrng)775 uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
776 {
777   uint32_t random32bit = 0U;
778 
779   /* Process locked */
780   __HAL_LOCK(hrng);
781 
782   /* Change RNG peripheral state */
783   hrng->State = HAL_RNG_STATE_BUSY;
784 
785   /* Get a 32bit Random number */
786   random32bit = hrng->Instance->DR;
787 
788   /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
789   __HAL_RNG_ENABLE_IT(hrng);
790 
791   /* Return the 32 bit random number */
792   return random32bit;
793 }
794 
795 /**
796   * @brief  Handles RNG interrupt request.
797   * @note   In the case of a clock error, the RNG is no more able to generate
798   *         random numbers because the PLL48CLK clock is not correct. User has
799   *         to check that the clock controller is correctly configured to provide
800   *         the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
801   *         The clock error has no impact on the previously generated
802   *         random numbers, and the RNG_DR register contents can be used.
803   * @note   In the case of a seed error, the generation of random numbers is
804   *         interrupted as long as the SECS bit is '1'. If a number is
805   *         available in the RNG_DR register, it must not be used because it may
806   *         not have enough entropy. In this case, it is recommended to clear the
807   *         SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
808   *         the RNG peripheral to reinitialize and restart the RNG.
809   * @note   User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
810   *         or CEIS are set.
811   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
812   *                the configuration information for RNG.
813   * @retval None
814 
815   */
HAL_RNG_IRQHandler(RNG_HandleTypeDef * hrng)816 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
817 {
818   uint32_t rngclockerror = 0U;
819 
820   /* RNG clock error interrupt occurred */
821   if (__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET)
822   {
823     /* Update the error code */
824     hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
825     rngclockerror = 1U;
826   }
827   else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
828   {
829     /* Update the error code */
830     hrng->ErrorCode = HAL_RNG_ERROR_SEED;
831     rngclockerror = 1U;
832   }
833   else
834   {
835     /* Nothing to do */
836   }
837 
838   if (rngclockerror == 1U)
839   {
840     /* Change RNG peripheral state */
841     hrng->State = HAL_RNG_STATE_ERROR;
842 
843 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
844     /* Call registered Error callback */
845     hrng->ErrorCallback(hrng);
846 #else
847     /* Call legacy weak Error callback */
848     HAL_RNG_ErrorCallback(hrng);
849 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
850 
851     /* Clear the clock error flag */
852     __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
853   }
854 
855   /* Check RNG data ready interrupt occurred */
856   if (__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
857   {
858     /* Generate random number once, so disable the IT */
859     __HAL_RNG_DISABLE_IT(hrng);
860 
861     /* Get the 32bit Random number (DRDY flag automatically cleared) */
862     hrng->RandomNumber = hrng->Instance->DR;
863 
864     if (hrng->State != HAL_RNG_STATE_ERROR)
865     {
866       /* Change RNG peripheral state */
867       hrng->State = HAL_RNG_STATE_READY;
868       /* Process Unlocked */
869       __HAL_UNLOCK(hrng);
870 
871 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
872       /* Call registered Data Ready callback */
873       hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
874 #else
875       /* Call legacy weak Data Ready callback */
876       HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
877 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
878     }
879   }
880 }
881 
882 /**
883   * @brief  Read latest generated random number.
884   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
885   *                the configuration information for RNG.
886   * @retval random value
887   */
HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef * hrng)888 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
889 {
890   return (hrng->RandomNumber);
891 }
892 
893 /**
894   * @brief  Data Ready callback in non-blocking mode.
895   * @note   When several random data are output at the same time in an output buffer,
896   *         When RNG_FLAG_DRDY flag value is set, first random number has been read
897   *         from DR register in IRQ Handler and is provided as callback parameter.
898   *         Depending on valid data available in the conditioning output buffer,
899   *         additional words can be read by the application from DR register till
900   *         DRDY bit remains high.
901   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
902   *                the configuration information for RNG.
903   * @param  random32bit generated random number.
904   * @retval None
905   */
HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef * hrng,uint32_t random32bit)906 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
907 {
908   /* Prevent unused argument(s) compilation warning */
909   UNUSED(hrng);
910   UNUSED(random32bit);
911   /* NOTE : This function should not be modified. When the callback is needed,
912             function HAL_RNG_ReadyDataCallback must be implemented in the user file.
913    */
914 }
915 
916 /**
917   * @brief  RNG error callbacks.
918   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
919   *                the configuration information for RNG.
920   * @retval None
921   */
HAL_RNG_ErrorCallback(RNG_HandleTypeDef * hrng)922 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
923 {
924   /* Prevent unused argument(s) compilation warning */
925   UNUSED(hrng);
926   /* NOTE : This function should not be modified. When the callback is needed,
927             function HAL_RNG_ErrorCallback must be implemented in the user file.
928    */
929 }
930 /**
931   * @}
932   */
933 
934 
935 /** @addtogroup RNG_Exported_Functions_Group3
936  *  @brief   Peripheral State functions
937  *
938 @verbatim
939  ===============================================================================
940                       ##### Peripheral State functions #####
941  ===============================================================================
942     [..]
943     This subsection permits to get in run-time the status of the peripheral
944     and the data flow.
945 
946 @endverbatim
947   * @{
948   */
949 
950 /**
951   * @brief  Returns the RNG state.
952   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
953   *                the configuration information for RNG.
954   * @retval HAL state
955   */
HAL_RNG_GetState(RNG_HandleTypeDef * hrng)956 HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
957 {
958   return hrng->State;
959 }
960 
961 /**
962   * @brief  Return the RNG handle error code.
963   * @param  hrng pointer to a RNG_HandleTypeDef structure.
964   * @retval RNG Error Code
965 */
HAL_RNG_GetError(RNG_HandleTypeDef * hrng)966 uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
967 {
968   /* Return RNG Error Code */
969   return hrng->ErrorCode;
970 }
971 /**
972   * @}
973   */
974 
975 /**
976   * @}
977   */
978 
979 
980 #endif /* HAL_RNG_MODULE_ENABLED */
981 /**
982   * @}
983   */
984 
985 #endif /* RNG */
986 
987 /**
988   * @}
989   */
990