1 /**
2 ******************************************************************************
3 * @file stm32f7xx_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 "stm32f7xx_hal.h"
97
98 /** @addtogroup STM32F7xx_HAL_Driver
99 * @{
100 */
101
102 #if defined (RNG)
103
104 /** @addtogroup RNG
105 * @brief RNG HAL module driver.
106 * @{
107 */
108
109 #ifdef HAL_RNG_MODULE_ENABLED
110
111 /* Private types -------------------------------------------------------------*/
112 /* Private defines -----------------------------------------------------------*/
113 /* Private variables ---------------------------------------------------------*/
114 /* Private constants ---------------------------------------------------------*/
115 /** @defgroup RNG_Private_Constants RNG Private Constants
116 * @{
117 */
118 #define RNG_TIMEOUT_VALUE 2U
119 /**
120 * @}
121 */
122 /* Private macros ------------------------------------------------------------*/
123 /* Private functions prototypes ----------------------------------------------*/
124 /* Private functions ---------------------------------------------------------*/
125 /* Exported functions --------------------------------------------------------*/
126
127 /** @addtogroup RNG_Exported_Functions
128 * @{
129 */
130
131 /** @addtogroup RNG_Exported_Functions_Group1
132 * @brief Initialization and configuration functions
133 *
134 @verbatim
135 ===============================================================================
136 ##### Initialization and configuration functions #####
137 ===============================================================================
138 [..] This section provides functions allowing to:
139 (+) Initialize the RNG according to the specified parameters
140 in the RNG_InitTypeDef and create the associated handle
141 (+) DeInitialize the RNG peripheral
142 (+) Initialize the RNG MSP
143 (+) DeInitialize RNG MSP
144
145 @endverbatim
146 * @{
147 */
148
149 /**
150 * @brief Initializes the RNG peripheral and creates the associated handle.
151 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
152 * the configuration information for RNG.
153 * @retval HAL status
154 */
HAL_RNG_Init(RNG_HandleTypeDef * hrng)155 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
156 {
157 /* Check the RNG handle allocation */
158 if (hrng == NULL)
159 {
160 return HAL_ERROR;
161 }
162 /* Check the parameters */
163 assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
164
165 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
166 if (hrng->State == HAL_RNG_STATE_RESET)
167 {
168 /* Allocate lock resource and initialize it */
169 hrng->Lock = HAL_UNLOCKED;
170
171 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
172 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
173
174 if (hrng->MspInitCallback == NULL)
175 {
176 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
177 }
178
179 /* Init the low level hardware */
180 hrng->MspInitCallback(hrng);
181 }
182 #else
183 if (hrng->State == HAL_RNG_STATE_RESET)
184 {
185 /* Allocate lock resource and initialize it */
186 hrng->Lock = HAL_UNLOCKED;
187
188 /* Init the low level hardware */
189 HAL_RNG_MspInit(hrng);
190 }
191 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
192
193 /* Change RNG peripheral state */
194 hrng->State = HAL_RNG_STATE_BUSY;
195
196
197 /* Enable the RNG Peripheral */
198 __HAL_RNG_ENABLE(hrng);
199
200 /* Initialize the RNG state */
201 hrng->State = HAL_RNG_STATE_READY;
202
203 /* Initialise the error code */
204 hrng->ErrorCode = HAL_RNG_ERROR_NONE;
205
206 /* Return function status */
207 return HAL_OK;
208 }
209
210 /**
211 * @brief DeInitializes the RNG peripheral.
212 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
213 * the configuration information for RNG.
214 * @retval HAL status
215 */
HAL_RNG_DeInit(RNG_HandleTypeDef * hrng)216 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
217 {
218 /* Check the RNG handle allocation */
219 if (hrng == NULL)
220 {
221 return HAL_ERROR;
222 }
223
224 /* Disable the RNG Peripheral */
225 CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
226
227 /* Clear RNG interrupt status flags */
228 CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
229
230 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
231 if (hrng->MspDeInitCallback == NULL)
232 {
233 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
234 }
235
236 /* DeInit the low level hardware */
237 hrng->MspDeInitCallback(hrng);
238 #else
239 /* DeInit the low level hardware */
240 HAL_RNG_MspDeInit(hrng);
241 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
242
243 /* Update the RNG state */
244 hrng->State = HAL_RNG_STATE_RESET;
245
246 /* Initialise the error code */
247 hrng->ErrorCode = HAL_RNG_ERROR_NONE;
248
249 /* Release Lock */
250 __HAL_UNLOCK(hrng);
251
252 /* Return the function status */
253 return HAL_OK;
254 }
255
256 /**
257 * @brief Initializes the RNG MSP.
258 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
259 * the configuration information for RNG.
260 * @retval None
261 */
HAL_RNG_MspInit(RNG_HandleTypeDef * hrng)262 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
263 {
264 /* Prevent unused argument(s) compilation warning */
265 UNUSED(hrng);
266 /* NOTE : This function should not be modified. When the callback is needed,
267 function HAL_RNG_MspInit must be implemented in the user file.
268 */
269 }
270
271 /**
272 * @brief DeInitializes the RNG MSP.
273 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
274 * the configuration information for RNG.
275 * @retval None
276 */
HAL_RNG_MspDeInit(RNG_HandleTypeDef * hrng)277 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
278 {
279 /* Prevent unused argument(s) compilation warning */
280 UNUSED(hrng);
281 /* NOTE : This function should not be modified. When the callback is needed,
282 function HAL_RNG_MspDeInit must be implemented in the user file.
283 */
284 }
285
286 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
287 /**
288 * @brief Register a User RNG Callback
289 * To be used instead of the weak predefined callback
290 * @param hrng RNG handle
291 * @param CallbackID ID of the callback to be registered
292 * This parameter can be one of the following values:
293 * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
294 * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
295 * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
296 * @param pCallback pointer to the Callback function
297 * @retval HAL status
298 */
HAL_RNG_RegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID,pRNG_CallbackTypeDef pCallback)299 HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID,
300 pRNG_CallbackTypeDef pCallback)
301 {
302 HAL_StatusTypeDef status = HAL_OK;
303
304 if (pCallback == NULL)
305 {
306 /* Update the error code */
307 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
308 return HAL_ERROR;
309 }
310 /* Process locked */
311 __HAL_LOCK(hrng);
312
313 if (HAL_RNG_STATE_READY == hrng->State)
314 {
315 switch (CallbackID)
316 {
317 case HAL_RNG_ERROR_CB_ID :
318 hrng->ErrorCallback = pCallback;
319 break;
320
321 case HAL_RNG_MSPINIT_CB_ID :
322 hrng->MspInitCallback = pCallback;
323 break;
324
325 case HAL_RNG_MSPDEINIT_CB_ID :
326 hrng->MspDeInitCallback = pCallback;
327 break;
328
329 default :
330 /* Update the error code */
331 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
332 /* Return error status */
333 status = HAL_ERROR;
334 break;
335 }
336 }
337 else if (HAL_RNG_STATE_RESET == hrng->State)
338 {
339 switch (CallbackID)
340 {
341 case HAL_RNG_MSPINIT_CB_ID :
342 hrng->MspInitCallback = pCallback;
343 break;
344
345 case HAL_RNG_MSPDEINIT_CB_ID :
346 hrng->MspDeInitCallback = pCallback;
347 break;
348
349 default :
350 /* Update the error code */
351 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
352 /* Return error status */
353 status = HAL_ERROR;
354 break;
355 }
356 }
357 else
358 {
359 /* Update the error code */
360 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
361 /* Return error status */
362 status = HAL_ERROR;
363 }
364
365 /* Release Lock */
366 __HAL_UNLOCK(hrng);
367 return status;
368 }
369
370 /**
371 * @brief Unregister an RNG Callback
372 * RNG callback is redirected to the weak predefined callback
373 * @param hrng RNG handle
374 * @param CallbackID ID of the callback to be unregistered
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 * @retval HAL status
380 */
HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID)381 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
382 {
383 HAL_StatusTypeDef status = HAL_OK;
384
385 /* Process locked */
386 __HAL_LOCK(hrng);
387
388 if (HAL_RNG_STATE_READY == hrng->State)
389 {
390 switch (CallbackID)
391 {
392 case HAL_RNG_ERROR_CB_ID :
393 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
394 break;
395
396 case HAL_RNG_MSPINIT_CB_ID :
397 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
398 break;
399
400 case HAL_RNG_MSPDEINIT_CB_ID :
401 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
402 break;
403
404 default :
405 /* Update the error code */
406 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
407 /* Return error status */
408 status = HAL_ERROR;
409 break;
410 }
411 }
412 else if (HAL_RNG_STATE_RESET == hrng->State)
413 {
414 switch (CallbackID)
415 {
416 case HAL_RNG_MSPINIT_CB_ID :
417 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
418 break;
419
420 case HAL_RNG_MSPDEINIT_CB_ID :
421 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */
422 break;
423
424 default :
425 /* Update the error code */
426 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
427 /* Return error status */
428 status = HAL_ERROR;
429 break;
430 }
431 }
432 else
433 {
434 /* Update the error code */
435 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
436 /* Return error status */
437 status = HAL_ERROR;
438 }
439
440 /* Release Lock */
441 __HAL_UNLOCK(hrng);
442 return status;
443 }
444
445 /**
446 * @brief Register Data Ready RNG Callback
447 * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
448 * @param hrng RNG handle
449 * @param pCallback pointer to the Data Ready Callback function
450 * @retval HAL status
451 */
HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef * hrng,pRNG_ReadyDataCallbackTypeDef pCallback)452 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
453 {
454 HAL_StatusTypeDef status = HAL_OK;
455
456 if (pCallback == NULL)
457 {
458 /* Update the error code */
459 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
460 return HAL_ERROR;
461 }
462 /* Process locked */
463 __HAL_LOCK(hrng);
464
465 if (HAL_RNG_STATE_READY == hrng->State)
466 {
467 hrng->ReadyDataCallback = pCallback;
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 the Data Ready RNG Callback
484 * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
485 * @param hrng RNG handle
486 * @retval HAL status
487 */
HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef * hrng)488 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
489 {
490 HAL_StatusTypeDef status = HAL_OK;
491
492 /* Process locked */
493 __HAL_LOCK(hrng);
494
495 if (HAL_RNG_STATE_READY == hrng->State)
496 {
497 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
498 }
499 else
500 {
501 /* Update the error code */
502 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
503 /* Return error status */
504 status = HAL_ERROR;
505 }
506
507 /* Release Lock */
508 __HAL_UNLOCK(hrng);
509 return status;
510 }
511
512 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
513
514 /**
515 * @}
516 */
517
518 /** @addtogroup RNG_Exported_Functions_Group2
519 * @brief Peripheral Control functions
520 *
521 @verbatim
522 ===============================================================================
523 ##### Peripheral Control functions #####
524 ===============================================================================
525 [..] This section provides functions allowing to:
526 (+) Get the 32 bit Random number
527 (+) Get the 32 bit Random number with interrupt enabled
528 (+) Handle RNG interrupt request
529
530 @endverbatim
531 * @{
532 */
533
534 /**
535 * @brief Generates a 32-bit random number.
536 * @note This function checks value of RNG_FLAG_DRDY flag to know if valid
537 * random number is available in the DR register (RNG_FLAG_DRDY flag set
538 * whenever a random number is available through the RNG_DR register).
539 * After transitioning from 0 to 1 (random number available),
540 * RNG_FLAG_DRDY flag remains high until output buffer becomes empty after reading
541 * four words from the RNG_DR register, i.e. further function calls
542 * will immediately return a new u32 random number (additional words are
543 * available and can be read by the application, till RNG_FLAG_DRDY flag remains high).
544 * @note When no more random number data is available in DR register, RNG_FLAG_DRDY
545 * flag is automatically cleared.
546 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
547 * the configuration information for RNG.
548 * @param random32bit pointer to generated random number variable if successful.
549 * @retval HAL status
550 */
551
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef * hrng,uint32_t * random32bit)552 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
553 {
554 uint32_t tickstart;
555 HAL_StatusTypeDef status = HAL_OK;
556
557 /* Process Locked */
558 __HAL_LOCK(hrng);
559
560 /* Check RNG peripheral state */
561 if (hrng->State == HAL_RNG_STATE_READY)
562 {
563 /* Change RNG peripheral state */
564 hrng->State = HAL_RNG_STATE_BUSY;
565
566 /* Get tick */
567 tickstart = HAL_GetTick();
568
569 /* Check if data register contains valid random data */
570 while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
571 {
572 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
573 {
574 /* New check to avoid false timeout detection in case of preemption */
575 if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
576 {
577 hrng->State = HAL_RNG_STATE_READY;
578 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
579 /* Process Unlocked */
580 __HAL_UNLOCK(hrng);
581 return HAL_ERROR;
582 }
583 }
584 }
585
586 /* Get a 32bit Random number */
587 hrng->RandomNumber = hrng->Instance->DR;
588 *random32bit = hrng->RandomNumber;
589
590 hrng->State = HAL_RNG_STATE_READY;
591 }
592 else
593 {
594 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
595 status = HAL_ERROR;
596 }
597
598 /* Process Unlocked */
599 __HAL_UNLOCK(hrng);
600
601 return status;
602 }
603
604 /**
605 * @brief Generates a 32-bit random number in interrupt mode.
606 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
607 * the configuration information for RNG.
608 * @retval HAL status
609 */
HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef * hrng)610 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
611 {
612 HAL_StatusTypeDef status = HAL_OK;
613
614 /* Process Locked */
615 __HAL_LOCK(hrng);
616
617 /* Check RNG peripheral state */
618 if (hrng->State == HAL_RNG_STATE_READY)
619 {
620 /* Change RNG peripheral state */
621 hrng->State = HAL_RNG_STATE_BUSY;
622
623 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
624 __HAL_RNG_ENABLE_IT(hrng);
625 }
626 else
627 {
628 /* Process Unlocked */
629 __HAL_UNLOCK(hrng);
630
631 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
632 status = HAL_ERROR;
633 }
634
635 return status;
636 }
637
638 /**
639 * @brief Returns generated random number in polling mode (Obsolete)
640 * Use HAL_RNG_GenerateRandomNumber() API instead.
641 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
642 * the configuration information for RNG.
643 * @retval Random value
644 */
HAL_RNG_GetRandomNumber(RNG_HandleTypeDef * hrng)645 uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
646 {
647 if (HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
648 {
649 return hrng->RandomNumber;
650 }
651 else
652 {
653 return 0U;
654 }
655 }
656
657 /**
658 * @brief Returns a 32-bit random number with interrupt enabled (Obsolete),
659 * Use HAL_RNG_GenerateRandomNumber_IT() API instead.
660 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
661 * the configuration information for RNG.
662 * @retval 32-bit random number
663 */
HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef * hrng)664 uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
665 {
666 uint32_t random32bit = 0U;
667
668 /* Process locked */
669 __HAL_LOCK(hrng);
670
671 /* Change RNG peripheral state */
672 hrng->State = HAL_RNG_STATE_BUSY;
673
674 /* Get a 32bit Random number */
675 random32bit = hrng->Instance->DR;
676
677 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
678 __HAL_RNG_ENABLE_IT(hrng);
679
680 /* Return the 32 bit random number */
681 return random32bit;
682 }
683
684 /**
685 * @brief Handles RNG interrupt request.
686 * @note In the case of a clock error, the RNG is no more able to generate
687 * random numbers because the PLL48CLK clock is not correct. User has
688 * to check that the clock controller is correctly configured to provide
689 * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
690 * The clock error has no impact on the previously generated
691 * random numbers, and the RNG_DR register contents can be used.
692 * @note In the case of a seed error, the generation of random numbers is
693 * interrupted as long as the SECS bit is '1'. If a number is
694 * available in the RNG_DR register, it must not be used because it may
695 * not have enough entropy. In this case, it is recommended to clear the
696 * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
697 * the RNG peripheral to reinitialize and restart the RNG.
698 * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
699 * or CEIS are set.
700 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
701 * the configuration information for RNG.
702 * @retval None
703
704 */
HAL_RNG_IRQHandler(RNG_HandleTypeDef * hrng)705 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
706 {
707 uint32_t rngclockerror = 0U;
708
709 /* RNG clock error interrupt occurred */
710 if (__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET)
711 {
712 /* Update the error code */
713 hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
714 rngclockerror = 1U;
715 }
716 else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
717 {
718 /* Update the error code */
719 hrng->ErrorCode = HAL_RNG_ERROR_SEED;
720 rngclockerror = 1U;
721 }
722 else
723 {
724 /* Nothing to do */
725 }
726
727 if (rngclockerror == 1U)
728 {
729 /* Change RNG peripheral state */
730 hrng->State = HAL_RNG_STATE_ERROR;
731
732 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
733 /* Call registered Error callback */
734 hrng->ErrorCallback(hrng);
735 #else
736 /* Call legacy weak Error callback */
737 HAL_RNG_ErrorCallback(hrng);
738 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
739
740 /* Clear the clock error flag */
741 __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
742
743 return;
744 }
745
746 /* Check RNG data ready interrupt occurred */
747 if (__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
748 {
749 /* Generate random number once, so disable the IT */
750 __HAL_RNG_DISABLE_IT(hrng);
751
752 /* Get the 32bit Random number (DRDY flag automatically cleared) */
753 hrng->RandomNumber = hrng->Instance->DR;
754
755 if (hrng->State != HAL_RNG_STATE_ERROR)
756 {
757 /* Change RNG peripheral state */
758 hrng->State = HAL_RNG_STATE_READY;
759 /* Process Unlocked */
760 __HAL_UNLOCK(hrng);
761
762 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
763 /* Call registered Data Ready callback */
764 hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
765 #else
766 /* Call legacy weak Data Ready callback */
767 HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
768 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
769 }
770 }
771 }
772
773 /**
774 * @brief Read latest generated random number.
775 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
776 * the configuration information for RNG.
777 * @retval random value
778 */
HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef * hrng)779 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
780 {
781 return (hrng->RandomNumber);
782 }
783
784 /**
785 * @brief Data Ready callback in non-blocking mode.
786 * @note When RNG_FLAG_DRDY flag value is set, first random number has been read
787 * from DR register in IRQ Handler and is provided as callback parameter.
788 * Depending on valid data available in the conditioning output buffer,
789 * additional words can be read by the application from DR register till
790 * DRDY bit remains high.
791 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
792 * the configuration information for RNG.
793 * @param random32bit generated random number.
794 * @retval None
795 */
HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef * hrng,uint32_t random32bit)796 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
797 {
798 /* Prevent unused argument(s) compilation warning */
799 UNUSED(hrng);
800 UNUSED(random32bit);
801 /* NOTE : This function should not be modified. When the callback is needed,
802 function HAL_RNG_ReadyDataCallback must be implemented in the user file.
803 */
804 }
805
806 /**
807 * @brief RNG error callbacks.
808 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
809 * the configuration information for RNG.
810 * @retval None
811 */
HAL_RNG_ErrorCallback(RNG_HandleTypeDef * hrng)812 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
813 {
814 /* Prevent unused argument(s) compilation warning */
815 UNUSED(hrng);
816 /* NOTE : This function should not be modified. When the callback is needed,
817 function HAL_RNG_ErrorCallback must be implemented in the user file.
818 */
819 }
820 /**
821 * @}
822 */
823
824
825 /** @addtogroup RNG_Exported_Functions_Group3
826 * @brief Peripheral State functions
827 *
828 @verbatim
829 ===============================================================================
830 ##### Peripheral State functions #####
831 ===============================================================================
832 [..]
833 This subsection permits to get in run-time the status of the peripheral
834 and the data flow.
835
836 @endverbatim
837 * @{
838 */
839
840 /**
841 * @brief Returns the RNG state.
842 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
843 * the configuration information for RNG.
844 * @retval HAL state
845 */
HAL_RNG_GetState(RNG_HandleTypeDef * hrng)846 HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
847 {
848 return hrng->State;
849 }
850
851 /**
852 * @brief Return the RNG handle error code.
853 * @param hrng: pointer to a RNG_HandleTypeDef structure.
854 * @retval RNG Error Code
855 */
HAL_RNG_GetError(RNG_HandleTypeDef * hrng)856 uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
857 {
858 /* Return RNG Error Code */
859 return hrng->ErrorCode;
860 }
861 /**
862 * @}
863 */
864
865 /**
866 * @}
867 */
868
869
870 #endif /* HAL_RNG_MODULE_ENABLED */
871 /**
872 * @}
873 */
874
875 #endif /* RNG */
876
877 /**
878 * @}
879 */
880
881