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
13 ==============================================================================
14 ##### How to use this driver #####
15 ==============================================================================
17 The RNG HAL driver can be used as follows:
19 (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro
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.
26 ##### Callback registration #####
27 ==================================
30 The compilation define USE_HAL_RNG_REGISTER_CALLBACKS when set to 1
31 allows the user to configure dynamically the driver callbacks.
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.
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,
47 This function allows to reset following callbacks:
48 (+) ErrorCallback : RNG Error Callback.
49 (+) MspInitCallback : RNG MspInit.
50 (+) MspDeInitCallback : RNG MspDeInit.
53 For specific callback ReadyDataCallback, use dedicated register callbacks:
54 respectively @ref HAL_RNG_RegisterReadyDataCallback() , @ref HAL_RNG_UnRegisterReadyDataCallback().
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).
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.
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.
81 ******************************************************************************
84 * <h2><center>© Copyright (c) 2018 STMicroelectronics.
85 * All rights reserved.</center></h2>
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
92 ******************************************************************************
95 /* Includes ------------------------------------------------------------------*/
96 #include "stm32g4xx_hal.h"
98 /** @addtogroup STM32G4xx_HAL_Driver
105 * @brief RNG HAL module driver.
109 #ifdef HAL_RNG_MODULE_ENABLED
111 /* Private types -------------------------------------------------------------*/
112 /* Private defines -----------------------------------------------------------*/
113 /* Private variables ---------------------------------------------------------*/
114 /* Private constants ---------------------------------------------------------*/
115 /** @defgroup RNG_Private_Constants RNG Private Constants
118 #define RNG_TIMEOUT_VALUE 2U
122 /* Private macros ------------------------------------------------------------*/
123 /* Private functions prototypes ----------------------------------------------*/
124 /* Private functions ---------------------------------------------------------*/
125 /* Exported functions --------------------------------------------------------*/
127 /** @addtogroup RNG_Exported_Functions
131 /** @addtogroup RNG_Exported_Functions_Group1
132 * @brief Initialization and configuration functions
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
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.
155 HAL_StatusTypeDef
HAL_RNG_Init(RNG_HandleTypeDef
*hrng
)
157 /* Check the RNG handle allocation */
162 /* Check the parameters */
163 assert_param(IS_RNG_ALL_INSTANCE(hrng
->Instance
));
164 assert_param(IS_RNG_CED(hrng
->Init
.ClockErrorDetection
));
166 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
167 if (hrng
->State
== HAL_RNG_STATE_RESET
)
169 /* Allocate lock resource and initialize it */
170 hrng
->Lock
= HAL_UNLOCKED
;
172 hrng
->ReadyDataCallback
= HAL_RNG_ReadyDataCallback
; /* Legacy weak ReadyDataCallback */
173 hrng
->ErrorCallback
= HAL_RNG_ErrorCallback
; /* Legacy weak ErrorCallback */
175 if (hrng
->MspInitCallback
== NULL
)
177 hrng
->MspInitCallback
= HAL_RNG_MspInit
; /* Legacy weak MspInit */
180 /* Init the low level hardware */
181 hrng
->MspInitCallback(hrng
);
184 if (hrng
->State
== HAL_RNG_STATE_RESET
)
186 /* Allocate lock resource and initialize it */
187 hrng
->Lock
= HAL_UNLOCKED
;
189 /* Init the low level hardware */
190 HAL_RNG_MspInit(hrng
);
192 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
194 /* Change RNG peripheral state */
195 hrng
->State
= HAL_RNG_STATE_BUSY
;
197 /* Clock Error Detection Configuration */
198 MODIFY_REG(hrng
->Instance
->CR
, RNG_CR_CED
, hrng
->Init
.ClockErrorDetection
);
200 /* Enable the RNG Peripheral */
201 __HAL_RNG_ENABLE(hrng
);
203 /* Initialize the RNG state */
204 hrng
->State
= HAL_RNG_STATE_READY
;
206 /* Initialise the error code */
207 hrng
->ErrorCode
= HAL_RNG_ERROR_NONE
;
209 /* Return function status */
214 * @brief DeInitializes the RNG peripheral.
215 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
216 * the configuration information for RNG.
219 HAL_StatusTypeDef
HAL_RNG_DeInit(RNG_HandleTypeDef
*hrng
)
221 /* Check the RNG handle allocation */
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
);
232 /* Clear RNG interrupt status flags */
233 CLEAR_BIT(hrng
->Instance
->SR
, RNG_SR_CEIS
| RNG_SR_SEIS
);
235 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
236 if (hrng
->MspDeInitCallback
== NULL
)
238 hrng
->MspDeInitCallback
= HAL_RNG_MspDeInit
; /* Legacy weak MspDeInit */
241 /* DeInit the low level hardware */
242 hrng
->MspDeInitCallback(hrng
);
244 /* DeInit the low level hardware */
245 HAL_RNG_MspDeInit(hrng
);
246 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
248 /* Update the RNG state */
249 hrng
->State
= HAL_RNG_STATE_RESET
;
251 /* Initialise the error code */
252 hrng
->ErrorCode
= HAL_RNG_ERROR_NONE
;
257 /* Return the function status */
262 * @brief Initializes the RNG MSP.
263 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
264 * the configuration information for RNG.
267 __weak
void HAL_RNG_MspInit(RNG_HandleTypeDef
*hrng
)
269 /* Prevent unused argument(s) compilation warning */
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.
277 * @brief DeInitializes the RNG MSP.
278 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
279 * the configuration information for RNG.
282 __weak
void HAL_RNG_MspDeInit(RNG_HandleTypeDef
*hrng
)
284 /* Prevent unused argument(s) compilation warning */
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.
291 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
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
304 HAL_StatusTypeDef
HAL_RNG_RegisterCallback(RNG_HandleTypeDef
*hrng
, HAL_RNG_CallbackIDTypeDef CallbackID
, pRNG_CallbackTypeDef pCallback
)
306 HAL_StatusTypeDef status
= HAL_OK
;
308 if (pCallback
== NULL
)
310 /* Update the error code */
311 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
317 if (HAL_RNG_STATE_READY
== hrng
->State
)
321 case HAL_RNG_ERROR_CB_ID
:
322 hrng
->ErrorCallback
= pCallback
;
325 case HAL_RNG_MSPINIT_CB_ID
:
326 hrng
->MspInitCallback
= pCallback
;
329 case HAL_RNG_MSPDEINIT_CB_ID
:
330 hrng
->MspDeInitCallback
= pCallback
;
334 /* Update the error code */
335 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
336 /* Return error status */
341 else if (HAL_RNG_STATE_RESET
== hrng
->State
)
345 case HAL_RNG_MSPINIT_CB_ID
:
346 hrng
->MspInitCallback
= pCallback
;
349 case HAL_RNG_MSPDEINIT_CB_ID
:
350 hrng
->MspDeInitCallback
= pCallback
;
354 /* Update the error code */
355 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
356 /* Return error status */
363 /* Update the error code */
364 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
365 /* Return error status */
375 * @brief Unregister an RNG Callback
376 * RNG callabck is redirected to the weak predefined callback
377 * @param hrng RNG handle
378 * @param CallbackID ID of the callback to be unregistered
379 * This parameter can be one of the following values:
380 * @arg @ref HAL_RNG_ERROR_CB_ID Error callback ID
381 * @arg @ref HAL_RNG_MSPINIT_CB_ID MspInit callback ID
382 * @arg @ref HAL_RNG_MSPDEINIT_CB_ID MspDeInit callback ID
385 HAL_StatusTypeDef
HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef
*hrng
, HAL_RNG_CallbackIDTypeDef CallbackID
)
387 HAL_StatusTypeDef status
= HAL_OK
;
392 if (HAL_RNG_STATE_READY
== hrng
->State
)
396 case HAL_RNG_ERROR_CB_ID
:
397 hrng
->ErrorCallback
= HAL_RNG_ErrorCallback
; /* Legacy weak ErrorCallback */
400 case HAL_RNG_MSPINIT_CB_ID
:
401 hrng
->MspInitCallback
= HAL_RNG_MspInit
; /* Legacy weak MspInit */
404 case HAL_RNG_MSPDEINIT_CB_ID
:
405 hrng
->MspDeInitCallback
= HAL_RNG_MspDeInit
; /* Legacy weak MspDeInit */
409 /* Update the error code */
410 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
411 /* Return error status */
416 else if (HAL_RNG_STATE_RESET
== hrng
->State
)
420 case HAL_RNG_MSPINIT_CB_ID
:
421 hrng
->MspInitCallback
= HAL_RNG_MspInit
; /* Legacy weak MspInit */
424 case HAL_RNG_MSPDEINIT_CB_ID
:
425 hrng
->MspDeInitCallback
= HAL_RNG_MspDeInit
; /* Legacy weak MspInit */
429 /* Update the error code */
430 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
431 /* Return error status */
438 /* Update the error code */
439 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
440 /* Return error status */
450 * @brief Register Data Ready RNG Callback
451 * To be used instead of the weak HAL_RNG_ReadyDataCallback() predefined callback
452 * @param hrng RNG handle
453 * @param pCallback pointer to the Data Ready Callback function
456 HAL_StatusTypeDef
HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef
*hrng
, pRNG_ReadyDataCallbackTypeDef pCallback
)
458 HAL_StatusTypeDef status
= HAL_OK
;
460 if (pCallback
== NULL
)
462 /* Update the error code */
463 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
469 if (HAL_RNG_STATE_READY
== hrng
->State
)
471 hrng
->ReadyDataCallback
= pCallback
;
475 /* Update the error code */
476 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
477 /* Return error status */
487 * @brief UnRegister the Data Ready RNG Callback
488 * Data Ready RNG Callback is redirected to the weak HAL_RNG_ReadyDataCallback() predefined callback
489 * @param hrng RNG handle
492 HAL_StatusTypeDef
HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef
*hrng
)
494 HAL_StatusTypeDef status
= HAL_OK
;
499 if (HAL_RNG_STATE_READY
== hrng
->State
)
501 hrng
->ReadyDataCallback
= HAL_RNG_ReadyDataCallback
; /* Legacy weak ReadyDataCallback */
505 /* Update the error code */
506 hrng
->ErrorCode
|= HAL_RNG_ERROR_INVALID_CALLBACK
;
507 /* Return error status */
516 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
522 /** @addtogroup RNG_Exported_Functions_Group2
523 * @brief Peripheral Control functions
526 ===============================================================================
527 ##### Peripheral Control functions #####
528 ===============================================================================
529 [..] This section provides functions allowing to:
530 (+) Get the 32 bit Random number
531 (+) Get the 32 bit Random number with interrupt enabled
532 (+) Handle RNG interrupt request
539 * @brief Generates a 32-bit random number.
540 * @note Each time the random number data is read the RNG_FLAG_DRDY flag
541 * is automatically cleared.
542 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
543 * the configuration information for RNG.
544 * @param random32bit pointer to generated random number variable if successful.
548 HAL_StatusTypeDef
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef
*hrng
, uint32_t *random32bit
)
551 HAL_StatusTypeDef status
= HAL_OK
;
556 /* Check RNG peripheral state */
557 if (hrng
->State
== HAL_RNG_STATE_READY
)
559 /* Change RNG peripheral state */
560 hrng
->State
= HAL_RNG_STATE_BUSY
;
563 tickstart
= HAL_GetTick();
565 /* Check if data register contains valid random data */
566 while (__HAL_RNG_GET_FLAG(hrng
, RNG_FLAG_DRDY
) == RESET
)
568 if ((HAL_GetTick() - tickstart
) > RNG_TIMEOUT_VALUE
)
570 hrng
->State
= HAL_RNG_STATE_READY
;
571 hrng
->ErrorCode
|= HAL_RNG_ERROR_TIMEOUT
;
572 /* Process Unlocked */
578 /* Get a 32bit Random number */
579 hrng
->RandomNumber
= hrng
->Instance
->DR
;
580 *random32bit
= hrng
->RandomNumber
;
582 hrng
->State
= HAL_RNG_STATE_READY
;
589 /* Process Unlocked */
596 * @brief Generates a 32-bit random number in interrupt mode.
597 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
598 * the configuration information for RNG.
601 HAL_StatusTypeDef
HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef
*hrng
)
603 HAL_StatusTypeDef status
= HAL_OK
;
608 /* Check RNG peripheral state */
609 if (hrng
->State
== HAL_RNG_STATE_READY
)
611 /* Change RNG peripheral state */
612 hrng
->State
= HAL_RNG_STATE_BUSY
;
614 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
615 __HAL_RNG_ENABLE_IT(hrng
);
619 /* Process Unlocked */
629 * @brief Handles RNG interrupt request.
630 * @note In the case of a clock error, the RNG is no more able to generate
631 * random numbers because the PLL48CLK clock is not correct. User has
632 * to check that the clock controller is correctly configured to provide
633 * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
634 * The clock error has no impact on the previously generated
635 * random numbers, and the RNG_DR register contents can be used.
636 * @note In the case of a seed error, the generation of random numbers is
637 * interrupted as long as the SECS bit is '1'. If a number is
638 * available in the RNG_DR register, it must not be used because it may
639 * not have enough entropy. In this case, it is recommended to clear the
640 * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
641 * the RNG peripheral to reinitialize and restart the RNG.
642 * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
644 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
645 * the configuration information for RNG.
649 void HAL_RNG_IRQHandler(RNG_HandleTypeDef
*hrng
)
651 uint32_t rngclockerror
= 0U;
653 /* RNG clock error interrupt occurred */
654 if (__HAL_RNG_GET_IT(hrng
, RNG_IT_CEI
) != RESET
)
658 else if (__HAL_RNG_GET_IT(hrng
, RNG_IT_SEI
) != RESET
)
667 if (rngclockerror
== 1U)
669 /* Change RNG peripheral state */
670 hrng
->State
= HAL_RNG_STATE_ERROR
;
672 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
673 /* Call registered Error callback */
674 hrng
->ErrorCallback(hrng
);
676 /* Call legacy weak Error callback */
677 HAL_RNG_ErrorCallback(hrng
);
678 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
680 /* Clear the clock error flag */
681 __HAL_RNG_CLEAR_IT(hrng
, RNG_IT_CEI
| RNG_IT_SEI
);
684 /* Check RNG data ready interrupt occurred */
685 if (__HAL_RNG_GET_IT(hrng
, RNG_IT_DRDY
) != RESET
)
687 /* Generate random number once, so disable the IT */
688 __HAL_RNG_DISABLE_IT(hrng
);
690 /* Get the 32bit Random number (DRDY flag automatically cleared) */
691 hrng
->RandomNumber
= hrng
->Instance
->DR
;
693 if (hrng
->State
!= HAL_RNG_STATE_ERROR
)
695 /* Change RNG peripheral state */
696 hrng
->State
= HAL_RNG_STATE_READY
;
697 /* Process Unlocked */
700 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
701 /* Call registered Data Ready callback */
702 hrng
->ReadyDataCallback(hrng
, hrng
->RandomNumber
);
704 /* Call legacy weak Data Ready callback */
705 HAL_RNG_ReadyDataCallback(hrng
, hrng
->RandomNumber
);
706 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
712 * @brief Read latest generated random number.
713 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
714 * the configuration information for RNG.
715 * @retval random value
717 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef
*hrng
)
719 return (hrng
->RandomNumber
);
723 * @brief Data Ready callback in non-blocking mode.
724 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
725 * the configuration information for RNG.
726 * @param random32bit generated random number.
729 __weak
void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef
*hrng
, uint32_t random32bit
)
731 /* Prevent unused argument(s) compilation warning */
734 /* NOTE : This function should not be modified. When the callback is needed,
735 function HAL_RNG_ReadyDataCallback must be implemented in the user file.
740 * @brief RNG error callbacks.
741 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
742 * the configuration information for RNG.
745 __weak
void HAL_RNG_ErrorCallback(RNG_HandleTypeDef
*hrng
)
747 /* Prevent unused argument(s) compilation warning */
749 /* NOTE : This function should not be modified. When the callback is needed,
750 function HAL_RNG_ErrorCallback must be implemented in the user file.
758 /** @addtogroup RNG_Exported_Functions_Group3
759 * @brief Peripheral State functions
762 ===============================================================================
763 ##### Peripheral State functions #####
764 ===============================================================================
766 This subsection permits to get in run-time the status of the peripheral
774 * @brief Returns the RNG state.
775 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
776 * the configuration information for RNG.
779 HAL_RNG_StateTypeDef
HAL_RNG_GetState(RNG_HandleTypeDef
*hrng
)
785 * @brief Return the RNG handle error code.
786 * @param hrng: pointer to a RNG_HandleTypeDef structure.
787 * @retval RNG Error Code
789 uint32_t HAL_RNG_GetError(RNG_HandleTypeDef
*hrng
)
791 /* Return RNG Error Code */
792 return hrng
->ErrorCode
;
803 #endif /* HAL_RNG_MODULE_ENABLED */
814 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/