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