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>© 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