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