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