1 /**
2   ******************************************************************************
3   * @file    stm32wb0x_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) 2024 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 16/32 bit Random Number Generator contains a valid
34           random data using polling mode.
35       (#) Get the 16/32 bit random number using HAL_RNG_GenerateRandomNumber() function.
36 
37   @endverbatim
38   ******************************************************************************
39   */
40 
41 /* Includes ------------------------------------------------------------------*/
42 #include "stm32wb0x_hal.h"
43 
44 /** @addtogroup STM32WB0x_HAL_Driver
45   * @{
46   */
47 
48 #if defined (RNG)
49 
50 /** @addtogroup RNG
51   * @brief RNG HAL module driver.
52   * @{
53   */
54 
55 #ifdef HAL_RNG_MODULE_ENABLED
56 
57 /* Private types -------------------------------------------------------------*/
58 /* Private defines -----------------------------------------------------------*/
59 /* Private variables ---------------------------------------------------------*/
60 /* Private constants ---------------------------------------------------------*/
61 /** @defgroup RNG_Private_Constants RNG Private Constants
62   * @{
63   */
64 #define RNG_TIMEOUT_VALUE     2U
65 /**
66   * @}
67   */
68 /* Private macros ------------------------------------------------------------*/
69 /* Private functions prototypes ----------------------------------------------*/
70 /* Private functions ---------------------------------------------------------*/
71 /* Exported functions --------------------------------------------------------*/
72 
73 /** @addtogroup RNG_Exported_Functions
74   * @{
75   */
76 
77 /** @addtogroup RNG_Exported_Functions_Group1
78   *  @brief   Initialization and configuration functions
79   *
80 @verbatim
81  ===============================================================================
82           ##### Initialization and configuration functions #####
83  ===============================================================================
84     [..]  This section provides functions allowing to:
85       (+) Initialize the RNG according to the specified parameters
86           in the RNG_InitTypeDef and create the associated handle
87       (+) DeInitialize the RNG peripheral
88       (+) Initialize the RNG MSP
89       (+) DeInitialize RNG MSP
90 
91 @endverbatim
92   * @{
93   */
94 
95 /**
96   * @brief  Initializes the RNG peripheral and creates the associated handle.
97   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
98   *                the configuration information for RNG.
99   * @retval HAL status
100   */
HAL_RNG_Init(RNG_HandleTypeDef * hrng)101 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
102 {
103   /* Check the RNG handle allocation */
104   if (hrng == NULL)
105   {
106     return HAL_ERROR;
107   }
108   /* Check the parameters */
109   assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
110 #if defined (RNG_CR_TST_CLK)
111   assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
112 #endif /* RNG_CR_TST_CLK */
113 
114   if (hrng->State == HAL_RNG_STATE_RESET)
115   {
116     /* Allocate lock resource and initialize it */
117     hrng->Lock = HAL_UNLOCKED;
118 
119     /* Init the low level hardware */
120     HAL_RNG_MspInit(hrng);
121   }
122 
123   /* Change RNG peripheral state */
124   hrng->State = HAL_RNG_STATE_BUSY;
125 
126   /* Reset the CR */
127   hrng->Instance->CR = 0U;
128 
129 #if defined (RNG_CR_TST_CLK)
130   /* Clock Error Detection Configuration */
131   MODIFY_REG(hrng->Instance->CR, RNG_CR_TST_CLK, hrng->Init.ClockErrorDetection);
132 #endif /* RNG_CR_TST_CLK */
133 
134   /* Enable the RNG Peripheral */
135   __HAL_RNG_ENABLE(hrng);
136 
137   /* Initialize the RNG state */
138   hrng->State = HAL_RNG_STATE_READY;
139 
140   /* Initialise the error code */
141   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
142 
143   /* Return function status */
144   return HAL_OK;
145 }
146 
147 /**
148   * @brief  DeInitializes the RNG peripheral.
149   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
150   *                the configuration information for RNG.
151   * @retval HAL status
152   */
HAL_RNG_DeInit(RNG_HandleTypeDef * hrng)153 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
154 {
155   /* Check the RNG handle allocation */
156   if (hrng == NULL)
157   {
158     return HAL_ERROR;
159   }
160 
161   /* Disable the RNG Peripheral */
162   __HAL_RNG_DISABLE(hrng);
163   /* DeInit the low level hardware */
164   HAL_RNG_MspDeInit(hrng);
165 
166   /* Update the RNG state */
167   hrng->State = HAL_RNG_STATE_RESET;
168 
169   /* Initialise the error code */
170   hrng->ErrorCode = HAL_RNG_ERROR_NONE;
171 
172   /* Release Lock */
173   __HAL_UNLOCK(hrng);
174 
175   /* Return the function status */
176   return HAL_OK;
177 }
178 
179 /**
180   * @brief  Initializes the RNG MSP.
181   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
182   *                the configuration information for RNG.
183   * @retval None
184   */
HAL_RNG_MspInit(RNG_HandleTypeDef * hrng)185 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
186 {
187   /* Prevent unused argument(s) compilation warning */
188   UNUSED(hrng);
189   /* NOTE : This function should not be modified. When the callback is needed,
190             function HAL_RNG_MspInit must be implemented in the user file.
191    */
192 }
193 
194 /**
195   * @brief  DeInitializes the RNG MSP.
196   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
197   *                the configuration information for RNG.
198   * @retval None
199   */
HAL_RNG_MspDeInit(RNG_HandleTypeDef * hrng)200 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
201 {
202   /* Prevent unused argument(s) compilation warning */
203   UNUSED(hrng);
204   /* NOTE : This function should not be modified. When the callback is needed,
205             function HAL_RNG_MspDeInit must be implemented in the user file.
206    */
207 }
208 
209 
210 /**
211   * @}
212   */
213 
214 /** @addtogroup RNG_Exported_Functions_Group2
215   *  @brief   Peripheral Control functions
216   *
217 @verbatim
218  ===============================================================================
219                       ##### Peripheral Control functions #####
220  ===============================================================================
221     [..]  This section provides functions allowing to:
222       (+) Get the 16/32 bit Random number
223 
224 @endverbatim
225   * @{
226   */
227 
228 /**
229   * @brief  Generates a 16/32-bit random number.
230   * @note   Each time the random number data is read the RNG_FLAG_DRDY flag
231   *         is automatically cleared.
232   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
233   *                the configuration information for RNG.
234   * @param  random_number random 16/32bit pointer to generated random number variable if successful.
235   * @retval HAL status
236   */
237 
HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef * hrng,uint32_t * random_number)238 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random_number)
239 {
240   uint32_t tickstart;
241   HAL_StatusTypeDef status = HAL_OK;
242 
243   /* Process Locked */
244   __HAL_LOCK(hrng);
245 
246   /* Check RNG peripheral state */
247   if (hrng->State == HAL_RNG_STATE_READY)
248   {
249     /* Change RNG peripheral state */
250     hrng->State = HAL_RNG_STATE_BUSY;
251 
252     /* Get tick */
253     tickstart = HAL_GetTick();
254 
255     /* Check if data register contains valid random data */
256     while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
257     {
258       if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
259       {
260         /* New check to avoid false timeout detection in case of preemption */
261         if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
262         {
263           hrng->State = HAL_RNG_STATE_READY;
264           hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
265           /* Process Unlocked */
266           __HAL_UNLOCK(hrng);
267           return HAL_ERROR;
268         }
269       }
270     }
271 
272     /* Get a 16/32bit Random number */
273     hrng->RandomNumber = hrng->Instance->VAL;
274     *random_number = hrng->RandomNumber;
275     hrng->State = HAL_RNG_STATE_READY;
276   }
277   else
278   {
279     hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
280     status = HAL_ERROR;
281   }
282 
283   /* Process Unlocked */
284   __HAL_UNLOCK(hrng);
285 
286   return status;
287 }
288 
289 
290 /**
291   * @brief  Read latest generated random number.
292   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
293   *                the configuration information for RNG.
294   * @retval random value
295   */
HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef * hrng)296 uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng)
297 {
298   return (hrng->RandomNumber);
299 }
300 
301 /**
302   * @}
303   */
304 
305 
306 /** @addtogroup RNG_Exported_Functions_Group3
307   *  @brief   Peripheral State functions
308   *
309 @verbatim
310  ===============================================================================
311                       ##### Peripheral State functions #####
312  ===============================================================================
313     [..]
314     This subsection permits to get in run-time the status of the peripheral
315     and the data flow.
316 
317 @endverbatim
318   * @{
319   */
320 
321 /**
322   * @brief  Returns the RNG state.
323   * @param  hrng pointer to a RNG_HandleTypeDef structure that contains
324   *                the configuration information for RNG.
325   * @retval HAL state
326   */
HAL_RNG_GetState(const RNG_HandleTypeDef * hrng)327 HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng)
328 {
329   return hrng->State;
330 }
331 
332 /**
333   * @brief  Return the RNG handle error code.
334   * @param  hrng: pointer to a RNG_HandleTypeDef structure.
335   * @retval RNG Error Code
336   */
HAL_RNG_GetError(const RNG_HandleTypeDef * hrng)337 uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng)
338 {
339   /* Return RNG Error Code */
340   return hrng->ErrorCode;
341 }
342 /**
343   * @}
344   */
345 
346 /**
347   * @}
348   */
349 
350 
351 #endif /* HAL_RNG_MODULE_ENABLED */
352 /**
353   * @}
354   */
355 
356 #endif /* RNG */
357 
358 /**
359   * @}
360   */
361