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/de-initialization 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</center></h2>
85 *
86 * Redistribution and use in source and binary forms, with or without modification,
87 * are permitted provided that the following conditions are met:
88 * 1. Redistributions of source code must retain the above copyright notice,
89 * this list of conditions and the following disclaimer.
90 * 2. Redistributions in binary form must reproduce the above copyright notice,
91 * this list of conditions and the following disclaimer in the documentation
92 * and/or other materials provided with the distribution.
93 * 3. Neither the name of STMicroelectronics nor the names of its contributors
94 * may be used to endorse or promote products derived from this software
95 * without specific prior written permission.
96 *
97 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
98 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
99 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
101 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
102 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
103 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
104 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
105 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
106 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107 *
108 ******************************************************************************
109 */
110
111 /* Includes ------------------------------------------------------------------*/
112 #include "stm32l4xx_hal.h"
113
114 /** @addtogroup STM32L4xx_HAL_Driver
115 * @{
116 */
117
118 /** @defgroup RNG RNG
119 * @brief RNG HAL module driver.
120 * @{
121 */
122
123 #ifdef HAL_RNG_MODULE_ENABLED
124
125
126
127 /* Private types -------------------------------------------------------------*/
128 /* Private defines -----------------------------------------------------------*/
129 /** @defgroup RNG_Private_Constants RNG_Private_Constants
130 * @{
131 */
132 #define RNG_TIMEOUT_VALUE 2
133 /**
134 * @}
135 */
136
137 /* Private macros ------------------------------------------------------------*/
138 /* Private variables ---------------------------------------------------------*/
139 /* Private function prototypes -----------------------------------------------*/
140 /* Private functions ---------------------------------------------------------*/
141 /* Exported functions --------------------------------------------------------*/
142
143 /** @addtogroup RNG_Exported_Functions
144 * @{
145 */
146
147 /** @addtogroup RNG_Exported_Functions_Group1
148 * @brief Initialization and de-initialization functions
149 *
150 @verbatim
151 ===============================================================================
152 ##### Initialization and de-initialization functions #####
153 ===============================================================================
154 [..] This section provides functions allowing to:
155 (+) Initialize the RNG according to the specified parameters
156 in the RNG_InitTypeDef and create the associated handle
157 (+) DeInitialize the RNG peripheral
158 (+) Initialize the RNG MSP (MCU Specific Package)
159 (+) DeInitialize the RNG MSP
160
161 @endverbatim
162 * @{
163 */
164
165 /**
166 * @brief Initialize the RNG peripheral and initialize the associated handle.
167 * @param hrng: pointer to a RNG_HandleTypeDef structure.
168 * @retval HAL status
169 */
HAL_RNG_Init(RNG_HandleTypeDef * hrng)170 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
171 {
172 /* Check the RNG handle allocation */
173 if(hrng == NULL)
174 {
175 return HAL_ERROR;
176 }
177
178 assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
179 #if defined(RNG_CR_CED)
180 assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
181 #endif /* defined(RNG_CR_CED) */
182
183 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
184 if(hrng->State == HAL_RNG_STATE_RESET)
185 {
186 /* Allocate lock resource and initialize it */
187 hrng->Lock = HAL_UNLOCKED;
188
189 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
190 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
191
192 if(hrng->MspInitCallback == NULL)
193 {
194 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
195 }
196
197 /* Init the low level hardware */
198 hrng->MspInitCallback(hrng);
199 }
200 #else
201 if(hrng->State == HAL_RNG_STATE_RESET)
202 {
203 /* Allocate lock resource and initialize it */
204 hrng->Lock = HAL_UNLOCKED;
205
206 /* Init the low level hardware */
207 HAL_RNG_MspInit(hrng);
208 }
209 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
210
211 /* Change RNG peripheral state */
212 hrng->State = HAL_RNG_STATE_BUSY;
213
214 #if defined(RNG_CR_CED)
215 /* Clock Error Detection configuration */
216 MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
217 #endif /* defined(RNG_CR_CED) */
218
219 /* Enable the RNG Peripheral */
220 __HAL_RNG_ENABLE(hrng);
221
222 /* Initialize the RNG state */
223 hrng->State = HAL_RNG_STATE_READY;
224
225 /* Initialise the error code */
226 hrng->ErrorCode = HAL_RNG_ERROR_NONE;
227
228 /* Return function status */
229 return HAL_OK;
230 }
231
232 /**
233 * @brief DeInitialize the RNG peripheral.
234 * @param hrng: pointer to a RNG_HandleTypeDef structure.
235 * @retval HAL status
236 */
HAL_RNG_DeInit(RNG_HandleTypeDef * hrng)237 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
238 {
239 /* Check the RNG handle allocation */
240 if(hrng == NULL)
241 {
242 return HAL_ERROR;
243 }
244
245 #if defined(RNG_CR_CED)
246 /* Clear Clock Error Detection bit */
247 CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
248 #endif /* defined(RNG_CR_CED) */
249
250 /* Disable the RNG Peripheral */
251 CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
252
253 /* Clear RNG interrupt status flags */
254 CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
255
256 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
257 if(hrng->MspDeInitCallback == NULL)
258 {
259 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
260 }
261
262 /* DeInit the low level hardware */
263 hrng->MspDeInitCallback(hrng);
264 #else
265 /* DeInit the low level hardware */
266 HAL_RNG_MspDeInit(hrng);
267 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
268
269 /* Update the RNG state */
270 hrng->State = HAL_RNG_STATE_RESET;
271
272 /* Initialise the error code */
273 hrng->ErrorCode = HAL_RNG_ERROR_NONE;
274
275 /* Release Lock */
276 __HAL_UNLOCK(hrng);
277
278 /* Return the function status */
279 return HAL_OK;
280 }
281
282 /**
283 * @brief Initialize the RNG MSP.
284 * @param hrng: pointer to a RNG_HandleTypeDef structure.
285 * @retval None
286 */
HAL_RNG_MspInit(RNG_HandleTypeDef * hrng)287 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
288 {
289 /* Prevent unused argument(s) compilation warning */
290 UNUSED(hrng);
291
292 /* NOTE : This function should not be modified. When the callback is needed,
293 function HAL_RNG_MspInit must be implemented in the user file.
294 */
295 }
296
297 /**
298 * @brief DeInitialize the RNG MSP.
299 * @param hrng: pointer to a RNG_HandleTypeDef structure.
300 * @retval None
301 */
HAL_RNG_MspDeInit(RNG_HandleTypeDef * hrng)302 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
303 {
304 /* Prevent unused argument(s) compilation warning */
305 UNUSED(hrng);
306
307 /* NOTE : This function should not be modified. When the callback is needed,
308 function HAL_RNG_MspDeInit must be implemented in the user file.
309 */
310 }
311
312 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
313 /**
314 * @brief Register a User RNG Callback
315 * To be used instead of the weak predefined callback
316 * @param hrng RNG handle
317 * @param CallbackID ID of the callback to be registered
318 * This parameter can be one of the following values:
319 * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
320 * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
321 * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
322 * @param pCallback pointer to the Callback function
323 * @retval HAL status
324 */
HAL_RNG_RegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID,pRNG_CallbackTypeDef pCallback)325 HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
326 {
327 HAL_StatusTypeDef status = HAL_OK;
328
329 if(pCallback == NULL)
330 {
331 /* Update the error code */
332 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
333 return HAL_ERROR;
334 }
335 /* Process locked */
336 __HAL_LOCK(hrng);
337
338 if(HAL_RNG_STATE_READY == hrng->State)
339 {
340 switch (CallbackID)
341 {
342 case HAL_RNG_ERROR_CB_ID :
343 hrng->ErrorCallback = pCallback;
344 break;
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 if(HAL_RNG_STATE_RESET == hrng->State)
363 {
364 switch (CallbackID)
365 {
366 case HAL_RNG_MSPINIT_CB_ID :
367 hrng->MspInitCallback = pCallback;
368 break;
369
370 case HAL_RNG_MSPDEINIT_CB_ID :
371 hrng->MspDeInitCallback = pCallback;
372 break;
373
374 default :
375 /* Update the error code */
376 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
377 /* Return error status */
378 status = HAL_ERROR;
379 break;
380 }
381 }
382 else
383 {
384 /* Update the error code */
385 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
386 /* Return error status */
387 status = HAL_ERROR;
388 }
389
390 /* Release Lock */
391 __HAL_UNLOCK(hrng);
392 return status;
393 }
394
395 /**
396 * @brief Unregister an RNG Callback
397 * RNG callabck is redirected to the weak predefined callback
398 * @param hrng RNG handle
399 * @param CallbackID ID of the callback to be unregistered
400 * This parameter can be one of the following values:
401 * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
402 * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
403 * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
404 * @retval HAL status
405 */
HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef * hrng,HAL_RNG_CallbackIDTypeDef CallbackID)406 HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
407 {
408 HAL_StatusTypeDef status = HAL_OK;
409
410 /* Process locked */
411 __HAL_LOCK(hrng);
412
413 if(HAL_RNG_STATE_READY == hrng->State)
414 {
415 switch (CallbackID)
416 {
417 case HAL_RNG_ERROR_CB_ID :
418 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
419 break;
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 MspDeInit */
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 if(HAL_RNG_STATE_RESET == hrng->State)
438 {
439 switch (CallbackID)
440 {
441 case HAL_RNG_MSPINIT_CB_ID :
442 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
443 break;
444
445 case HAL_RNG_MSPDEINIT_CB_ID :
446 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */
447 break;
448
449 default :
450 /* Update the error code */
451 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
452 /* Return error status */
453 status = HAL_ERROR;
454 break;
455 }
456 }
457 else
458 {
459 /* Update the error code */
460 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
461 /* Return error status */
462 status = HAL_ERROR;
463 }
464
465 /* Release Lock */
466 __HAL_UNLOCK(hrng);
467 return status;
468 }
469
470 /**
471 * @brief Register Data Ready RNG Callback
472 * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
473 * @param hrng RNG handle
474 * @param pCallback pointer to the Data Ready Callback function
475 * @retval HAL status
476 */
HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef * hrng,pRNG_ReadyDataCallbackTypeDef pCallback)477 HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
478 {
479 HAL_StatusTypeDef status = HAL_OK;
480
481 if(pCallback == NULL)
482 {
483 /* Update the error code */
484 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
485 return HAL_ERROR;
486 }
487 /* Process locked */
488 __HAL_LOCK(hrng);
489
490 if(HAL_RNG_STATE_READY == hrng->State)
491 {
492 hrng->ReadyDataCallback = pCallback;
493 }
494 else
495 {
496 /* Update the error code */
497 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
498 /* Return error status */
499 status = HAL_ERROR;
500 }
501
502 /* Release Lock */
503 __HAL_UNLOCK(hrng);
504 return status;
505 }
506
507 /**
508 * @brief UnRegister the Data Ready RNG Callback
509 * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
510 * @param hrng RNG handle
511 * @retval HAL status
512 */
HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef * hrng)513 HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
514 {
515 HAL_StatusTypeDef status = HAL_OK;
516
517 /* Process locked */
518 __HAL_LOCK(hrng);
519
520 if(HAL_RNG_STATE_READY == hrng->State)
521 {
522 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
523 }
524 else
525 {
526 /* Update the error code */
527 hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
528 /* Return error status */
529 status = HAL_ERROR;
530 }
531
532 /* Release Lock */
533 __HAL_UNLOCK(hrng);
534 return status;
535 }
536
537 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
538
539 /**
540 * @}
541 */
542
543 /** @addtogroup RNG_Exported_Functions_Group2
544 * @brief Management functions.
545 *
546 @verbatim
547 ===============================================================================
548 ##### Peripheral Control functions #####
549 ===============================================================================
550 [..] This section provides functions allowing to:
551 (+) Get the 32 bit Random number
552 (+) Get the 32 bit Random number with interrupt enabled
553 (+) Handle RNG interrupt request
554
555 @endverbatim
556 * @{
557 */
558
559 /**
560 * @brief Generate a 32-bit random number.
561 * @note Each time the random number data is read the RNG_FLAG_DRDY flag
562 * is automatically cleared.
563 * @param hrng: pointer to a RNG_HandleTypeDef structure.
564 * @param random32bit: pointer to generated random number variable if successful.
565 * @retval HAL status
566 */
567
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef * hrng,uint32_t * random32bit)568 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
569 {
570 uint32_t tickstart = 0;
571 HAL_StatusTypeDef status = HAL_OK;
572
573 /* Process Locked */
574 __HAL_LOCK(hrng);
575
576 /* Check RNS peripheral state */
577 if(hrng->State == HAL_RNG_STATE_READY)
578 {
579 /* Change RNG peripheral state */
580 hrng->State = HAL_RNG_STATE_BUSY;
581
582 /* Get tick */
583 tickstart = HAL_GetTick();
584
585 /* Check if data register contains valid random data */
586 while(__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
587 {
588 if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE)
589 {
590 hrng->State = HAL_RNG_STATE_ERROR;
591
592 /* Process Unlocked */
593 __HAL_UNLOCK(hrng);
594
595 return HAL_TIMEOUT;
596 }
597 }
598
599 /* Get a 32bit Random number */
600 hrng->RandomNumber = hrng->Instance->DR;
601 *random32bit = hrng->RandomNumber;
602
603 hrng->State = HAL_RNG_STATE_READY;
604 }
605 else
606 {
607 status = HAL_ERROR;
608 }
609
610 /* Process Unlocked */
611 __HAL_UNLOCK(hrng);
612
613 return status;
614 }
615
616 /**
617 * @brief Generate a 32-bit random number in interrupt mode.
618 * @param hrng: pointer to a RNG_HandleTypeDef structure.
619 * @retval HAL status
620 */
HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef * hrng)621 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
622 {
623 HAL_StatusTypeDef status = HAL_OK;
624
625 /* Process Locked */
626 __HAL_LOCK(hrng);
627
628 /* Check RNG peripheral state */
629 if(hrng->State == HAL_RNG_STATE_READY)
630 {
631 /* Change RNG peripheral state */
632 hrng->State = HAL_RNG_STATE_BUSY;
633
634 /* Process Unlocked */
635 __HAL_UNLOCK(hrng);
636
637 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
638 __HAL_RNG_ENABLE_IT(hrng);
639 }
640 else
641 {
642 /* Process Unlocked */
643 __HAL_UNLOCK(hrng);
644
645 status = HAL_ERROR;
646 }
647
648 return status;
649 }
650
651 /**
652 * @brief Handle RNG interrupt request.
653 * @note In the case of a clock error, the RNG is no more able to generate
654 * random numbers because the PLL48CLK clock is not correct. User has
655 * to check that the clock controller is correctly configured to provide
656 * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
657 * The clock error has no impact on the previously generated
658 * random numbers, and the RNG_DR register contents can be used.
659 * @note In the case of a seed error, the generation of random numbers is
660 * interrupted as long as the SECS bit is '1'. If a number is
661 * available in the RNG_DR register, it must not be used because it may
662 * not have enough entropy. In this case, it is recommended to clear the
663 * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
664 * the RNG peripheral to reinitialize and restart the RNG.
665 * @note RNG ErrorCallback() API is called once whether SEIS or CEIS are set.
666 * @param hrng: pointer to a RNG_HandleTypeDef structure.
667 * @retval None
668
669 */
HAL_RNG_IRQHandler(RNG_HandleTypeDef * hrng)670 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
671 {
672 /* RNG clock error interrupt occurred */
673 if((__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET) || (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET))
674 {
675 /* Change RNG peripheral state */
676 hrng->State = HAL_RNG_STATE_ERROR;
677
678 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
679 /* Call registered Error callback */
680 hrng->ErrorCallback(hrng);
681 #else
682 /* Call legacy weak Error callback */
683 HAL_RNG_ErrorCallback(hrng);
684 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
685
686 /* Clear the clock error flag */
687 __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI|RNG_IT_SEI);
688
689 }
690
691 /* Check RNG data ready interrupt occurred */
692 if(__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
693 {
694 /* Generate random number once, so disable the IT */
695 __HAL_RNG_DISABLE_IT(hrng);
696
697 /* Get the 32bit Random number (DRDY flag automatically cleared) */
698 hrng->RandomNumber = hrng->Instance->DR;
699
700 if(hrng->State != HAL_RNG_STATE_ERROR)
701 {
702 /* Change RNG peripheral state */
703 hrng->State = HAL_RNG_STATE_READY;
704
705 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
706 /* Call registered Data Ready callback */
707 hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
708 #else
709 /* Call legacy weak Data Ready callback */
710 HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
711 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
712 }
713 }
714 }
715
716 /**
717 * @brief Return generated random number in polling mode (Obsolete).
718 * @note Use HAL_RNG_GenerateRandomNumber() API instead.
719 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
720 * the configuration information for RNG.
721 * @retval random value
722 */
HAL_RNG_GetRandomNumber(RNG_HandleTypeDef * hrng)723 uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
724 {
725 if(HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
726 {
727 return hrng->RandomNumber;
728 }
729 else
730 {
731 return 0;
732 }
733 }
734
735
736 /**
737 * @brief Return a 32-bit random number with interrupt enabled (Obsolete).
738 * @note Use HAL_RNG_GenerateRandomNumber_IT() API instead.
739 * @param hrng: RNG handle
740 * @retval 32-bit random number
741 */
HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef * hrng)742 uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
743 {
744 uint32_t random32bit = 0;
745
746 /* Process locked */
747 __HAL_LOCK(hrng);
748
749 /* Change RNG peripheral state */
750 hrng->State = HAL_RNG_STATE_BUSY;
751
752 /* Get a 32bit Random number */
753 random32bit = hrng->Instance->DR;
754
755 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
756 __HAL_RNG_ENABLE_IT(hrng);
757
758 /* Return the 32 bit random number */
759 return random32bit;
760 }
761
762
763
764 /**
765 * @brief Read latest generated random number.
766 * @param hrng: pointer to a RNG_HandleTypeDef structure.
767 * @retval random value
768 */
HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef * hrng)769 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
770 {
771 return(hrng->RandomNumber);
772 }
773
774 /**
775 * @brief Data Ready callback in non-blocking mode.
776 * @param hrng: pointer to a RNG_HandleTypeDef structure.
777 * @param random32bit: generated random value
778 * @retval None
779 */
HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef * hrng,uint32_t random32bit)780 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
781 {
782 /* Prevent unused argument(s) compilation warning */
783 UNUSED(hrng);
784 UNUSED(random32bit);
785
786 /* NOTE : This function should not be modified. When the callback is needed,
787 function HAL_RNG_ReadyDataCallback must be implemented in the user file.
788 */
789 }
790
791 /**
792 * @brief RNG error callback.
793 * @param hrng: pointer to a RNG_HandleTypeDef structure.
794 * @retval None
795 */
HAL_RNG_ErrorCallback(RNG_HandleTypeDef * hrng)796 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
797 {
798 /* Prevent unused argument(s) compilation warning */
799 UNUSED(hrng);
800
801 /* NOTE : This function should not be modified. When the callback is needed,
802 function HAL_RNG_ErrorCallback must be implemented in the user file.
803 */
804 }
805
806 /**
807 * @}
808 */
809
810 /** @addtogroup RNG_Exported_Functions_Group3
811 * @brief Peripheral State functions.
812 *
813 @verbatim
814 ===============================================================================
815 ##### Peripheral State and Error functions #####
816 ===============================================================================
817 [..]
818 This subsection permits to :
819 (+) Return in run-time the status of the peripheral.
820 (+) Return the RNG handle error code
821
822 @endverbatim
823 * @{
824 */
825
826 /**
827 * @brief Return the RNG handle state.
828 * @param hrng: pointer to a RNG_HandleTypeDef structure.
829 * @retval HAL state
830 */
HAL_RNG_GetState(RNG_HandleTypeDef * hrng)831 HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
832 {
833 /* Return RNG handle state */
834 return hrng->State;
835 }
836
837 /**
838 * @brief Return the RNG handle error code.
839 * @param hrng: pointer to a RNG_HandleTypeDef structure.
840 * @retval RNG Error Code
841 */
HAL_RNG_GetError(RNG_HandleTypeDef * hrng)842 uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
843 {
844 /* Return RNG Error Code */
845 return hrng->ErrorCode;
846 }
847 /**
848 * @}
849 */
850
851 /**
852 * @}
853 */
854
855
856 #endif /* HAL_RNG_MODULE_ENABLED */
857 /**
858 * @}
859 */
860
861 /**
862 * @}
863 */
864
865 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
866