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