38
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @file stm32f4xx_hal_rng.c
|
|
4 * @author MCD Application Team
|
|
5 * @version V1.2.0
|
|
6 * @date 26-December-2014
|
|
7 * @brief RNG HAL module driver.
|
|
8 * This file provides firmware functions to manage the following
|
|
9 * functionalities of the Random Number Generator (RNG) peripheral:
|
|
10 * + Initialization/de-initialization functions
|
|
11 * + Peripheral Control functions
|
|
12 * + Peripheral State functions
|
|
13 *
|
|
14 @verbatim
|
|
15 ==============================================================================
|
|
16 ##### How to use this driver #####
|
|
17 ==============================================================================
|
|
18 [..]
|
|
19 The RNG HAL driver can be used as follows:
|
|
20
|
|
21 (#) Enable the RNG controller clock using __HAL_RCC_RNG_CLK_ENABLE() macro
|
|
22 in HAL_RNG_MspInit().
|
|
23 (#) Activate the RNG peripheral using HAL_RNG_Init() function.
|
|
24 (#) Wait until the 32 bit Random Number Generator contains a valid
|
|
25 random data using (polling/interrupt) mode.
|
|
26 (#) Get the 32 bit random number using HAL_RNG_GenerateRandomNumber() function.
|
|
27
|
|
28 @endverbatim
|
|
29 ******************************************************************************
|
|
30 * @attention
|
|
31 *
|
|
32 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
|
33 *
|
|
34 * Redistribution and use in source and binary forms, with or without modification,
|
|
35 * are permitted provided that the following conditions are met:
|
|
36 * 1. Redistributions of source code must retain the above copyright notice,
|
|
37 * this list of conditions and the following disclaimer.
|
|
38 * 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
39 * this list of conditions and the following disclaimer in the documentation
|
|
40 * and/or other materials provided with the distribution.
|
|
41 * 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
42 * may be used to endorse or promote products derived from this software
|
|
43 * without specific prior written permission.
|
|
44 *
|
|
45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
46 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
48 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
51 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
52 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
53 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
54 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
55 *
|
|
56 ******************************************************************************
|
|
57 */
|
|
58
|
|
59 /* Includes ------------------------------------------------------------------*/
|
|
60 #include "stm32f4xx_hal.h"
|
|
61
|
|
62 /** @addtogroup STM32F4xx_HAL_Driver
|
|
63 * @{
|
|
64 */
|
|
65
|
|
66 /** @addtogroup RNG
|
|
67 * @{
|
|
68 */
|
|
69
|
|
70 #ifdef HAL_RNG_MODULE_ENABLED
|
|
71
|
|
72 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
|
|
73 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
|
|
74
|
|
75
|
|
76 /* Private types -------------------------------------------------------------*/
|
|
77 /* Private defines -----------------------------------------------------------*/
|
|
78 /* Private variables ---------------------------------------------------------*/
|
|
79 /* Private constants ---------------------------------------------------------*/
|
|
80 /** @addtogroup RNG_Private_Constants
|
|
81 * @{
|
|
82 */
|
|
83 #define RNG_TIMEOUT_VALUE 2
|
|
84 /**
|
|
85 * @}
|
|
86 */
|
|
87 /* Private macros ------------------------------------------------------------*/
|
|
88 /* Private functions prototypes ----------------------------------------------*/
|
|
89 /* Private functions ---------------------------------------------------------*/
|
|
90 /* Exported functions --------------------------------------------------------*/
|
|
91
|
|
92 /** @addtogroup RNG_Exported_Functions
|
|
93 * @{
|
|
94 */
|
|
95
|
|
96 /** @addtogroup RNG_Exported_Functions_Group1
|
|
97 * @brief Initialization and de-initialization functions
|
|
98 *
|
|
99 @verbatim
|
|
100 ===============================================================================
|
|
101 ##### Initialization and de-initialization functions #####
|
|
102 ===============================================================================
|
|
103 [..] This section provides functions allowing to:
|
|
104 (+) Initialize the RNG according to the specified parameters
|
|
105 in the RNG_InitTypeDef and create the associated handle
|
|
106 (+) DeInitialize the RNG peripheral
|
|
107 (+) Initialize the RNG MSP
|
|
108 (+) DeInitialize RNG MSP
|
|
109
|
|
110 @endverbatim
|
|
111 * @{
|
|
112 */
|
|
113
|
|
114 /**
|
|
115 * @brief Initializes the RNG peripheral and creates the associated handle.
|
|
116 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
117 * the configuration information for RNG.
|
|
118 * @retval HAL status
|
|
119 */
|
|
120 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
|
|
121 {
|
|
122 /* Check the RNG handle allocation */
|
|
123 if(hrng == NULL)
|
|
124 {
|
|
125 return HAL_ERROR;
|
|
126 }
|
|
127
|
|
128 __HAL_LOCK(hrng);
|
|
129
|
|
130 if(hrng->State == HAL_RNG_STATE_RESET)
|
|
131 {
|
|
132 /* Init the low level hardware */
|
|
133 HAL_RNG_MspInit(hrng);
|
|
134 }
|
|
135
|
|
136 /* Change RNG peripheral state */
|
|
137 hrng->State = HAL_RNG_STATE_BUSY;
|
|
138
|
|
139 /* Enable the RNG Peripheral */
|
|
140 __HAL_RNG_ENABLE(hrng);
|
|
141
|
|
142 /* Initialize the RNG state */
|
|
143 hrng->State = HAL_RNG_STATE_READY;
|
|
144
|
|
145 __HAL_UNLOCK(hrng);
|
|
146
|
|
147 /* Return function status */
|
|
148 return HAL_OK;
|
|
149 }
|
|
150
|
|
151 /**
|
|
152 * @brief DeInitializes the RNG peripheral.
|
|
153 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
154 * the configuration information for RNG.
|
|
155 * @retval HAL status
|
|
156 */
|
|
157 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
|
|
158 {
|
|
159 /* Check the RNG handle allocation */
|
|
160 if(hrng == NULL)
|
|
161 {
|
|
162 return HAL_ERROR;
|
|
163 }
|
|
164 /* Disable the RNG Peripheral */
|
|
165 CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
|
|
166
|
|
167 /* Clear RNG interrupt status flags */
|
|
168 CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
|
|
169
|
|
170 /* DeInit the low level hardware */
|
|
171 HAL_RNG_MspDeInit(hrng);
|
|
172
|
|
173 /* Update the RNG state */
|
|
174 hrng->State = HAL_RNG_STATE_RESET;
|
|
175
|
|
176 /* Release Lock */
|
|
177 __HAL_UNLOCK(hrng);
|
|
178
|
|
179 /* Return the function status */
|
|
180 return HAL_OK;
|
|
181 }
|
|
182
|
|
183 /**
|
|
184 * @brief Initializes the RNG MSP.
|
|
185 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
186 * the configuration information for RNG.
|
|
187 * @retval None
|
|
188 */
|
|
189 __weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
|
|
190 {
|
|
191 /* NOTE : This function should not be modified. When the callback is needed,
|
|
192 function HAL_RNG_MspInit must be implemented in the user file.
|
|
193 */
|
|
194 }
|
|
195
|
|
196 /**
|
|
197 * @brief DeInitializes the RNG MSP.
|
|
198 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
199 * the configuration information for RNG.
|
|
200 * @retval None
|
|
201 */
|
|
202 __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
|
|
203 {
|
|
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 /** @addtogroup RNG_Exported_Functions_Group2
|
|
214 * @brief Peripheral Control functions
|
|
215 *
|
|
216 @verbatim
|
|
217 ===============================================================================
|
|
218 ##### Peripheral Control functions #####
|
|
219 ===============================================================================
|
|
220 [..] This section provides functions allowing to:
|
|
221 (+) Get the 32 bit Random number
|
|
222 (+) Get the 32 bit Random number with interrupt enabled
|
|
223 (+) Handle RNG interrupt request
|
|
224
|
|
225 @endverbatim
|
|
226 * @{
|
|
227 */
|
|
228
|
|
229 /**
|
|
230 * @brief Generates a 32-bit random number.
|
|
231 * @note Each time the random number data is read the RNG_FLAG_DRDY flag
|
|
232 * is automatically cleared.
|
|
233 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
234 * the configuration information for RNG.
|
|
235 * @param random32bit: pointer to generated random number variable if successful.
|
|
236 * @retval HAL status
|
|
237 */
|
|
238
|
|
239 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
|
|
240 {
|
|
241 uint32_t tickstart = 0;
|
|
242 HAL_StatusTypeDef status = HAL_OK;
|
|
243
|
|
244 /* Process Locked */
|
|
245 __HAL_LOCK(hrng);
|
|
246
|
|
247 /* Check RNG peripheral state */
|
|
248 if(hrng->State == HAL_RNG_STATE_READY)
|
|
249 {
|
|
250 /* Change RNG peripheral state */
|
|
251 hrng->State = HAL_RNG_STATE_BUSY;
|
|
252
|
|
253 /* Get tick */
|
|
254 tickstart = HAL_GetTick();
|
|
255
|
|
256 /* Check if data register contains valid random data */
|
|
257 while(__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
|
|
258 {
|
|
259 if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE)
|
|
260 {
|
|
261 hrng->State = HAL_RNG_STATE_ERROR;
|
|
262
|
|
263 /* Process Unlocked */
|
|
264 __HAL_UNLOCK(hrng);
|
|
265
|
|
266 return HAL_TIMEOUT;
|
|
267 }
|
|
268 }
|
|
269
|
|
270 /* Get a 32bit Random number */
|
|
271 hrng->RandomNumber = hrng->Instance->DR;
|
|
272 *random32bit = hrng->RandomNumber;
|
|
273
|
|
274 hrng->State = HAL_RNG_STATE_READY;
|
|
275 }
|
|
276 else
|
|
277 {
|
|
278 status = HAL_ERROR;
|
|
279 }
|
|
280
|
|
281 /* Process Unlocked */
|
|
282 __HAL_UNLOCK(hrng);
|
|
283
|
|
284 return status;
|
|
285 }
|
|
286
|
|
287 /**
|
|
288 * @brief Generates a 32-bit random number in interrupt mode.
|
|
289 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
290 * the configuration information for RNG.
|
|
291 * @retval HAL status
|
|
292 */
|
|
293 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
|
|
294 {
|
|
295 HAL_StatusTypeDef status = HAL_OK;
|
|
296
|
|
297 /* Process Locked */
|
|
298 __HAL_LOCK(hrng);
|
|
299
|
|
300 /* Check RNG peripheral state */
|
|
301 if(hrng->State == HAL_RNG_STATE_READY)
|
|
302 {
|
|
303 /* Change RNG peripheral state */
|
|
304 hrng->State = HAL_RNG_STATE_BUSY;
|
|
305
|
|
306 /* Process Unlocked */
|
|
307 __HAL_UNLOCK(hrng);
|
|
308
|
|
309 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
|
|
310 __HAL_RNG_ENABLE_IT(hrng);
|
|
311 }
|
|
312 else
|
|
313 {
|
|
314 /* Process Unlocked */
|
|
315 __HAL_UNLOCK(hrng);
|
|
316
|
|
317 status = HAL_ERROR;
|
|
318 }
|
|
319
|
|
320 return status;
|
|
321 }
|
|
322
|
|
323 /**
|
|
324 * @brief Handles RNG interrupt request.
|
|
325 * @note In the case of a clock error, the RNG is no more able to generate
|
|
326 * random numbers because the PLL48CLK clock is not correct. User has
|
|
327 * to check that the clock controller is correctly configured to provide
|
|
328 * the RNG clock and clear the CEIS bit using __HAL_RNG_CLEAR_IT().
|
|
329 * The clock error has no impact on the previously generated
|
|
330 * random numbers, and the RNG_DR register contents can be used.
|
|
331 * @note In the case of a seed error, the generation of random numbers is
|
|
332 * interrupted as long as the SECS bit is '1'. If a number is
|
|
333 * available in the RNG_DR register, it must not be used because it may
|
|
334 * not have enough entropy. In this case, it is recommended to clear the
|
|
335 * SEIS bit using __HAL_RNG_CLEAR_IT(), then disable and enable
|
|
336 * the RNG peripheral to reinitialize and restart the RNG.
|
|
337 * @note User-written HAL_RNG_ErrorCallback() API is called once whether SEIS
|
|
338 * or CEIS are set.
|
|
339 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
340 * the configuration information for RNG.
|
|
341 * @retval None
|
|
342
|
|
343 */
|
|
344 void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
|
|
345 {
|
|
346 /* RNG clock error interrupt occurred */
|
|
347 if((__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET) || (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET))
|
|
348 {
|
|
349 /* Change RNG peripheral state */
|
|
350 hrng->State = HAL_RNG_STATE_ERROR;
|
|
351
|
|
352 HAL_RNG_ErrorCallback(hrng);
|
|
353
|
|
354 /* Clear the clock error flag */
|
|
355 __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI|RNG_IT_SEI);
|
|
356
|
|
357 }
|
|
358
|
|
359 /* Check RNG data ready interrupt occurred */
|
|
360 if(__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
|
|
361 {
|
|
362 /* Generate random number once, so disable the IT */
|
|
363 __HAL_RNG_DISABLE_IT(hrng);
|
|
364
|
|
365 /* Get the 32bit Random number (DRDY flag automatically cleared) */
|
|
366 hrng->RandomNumber = hrng->Instance->DR;
|
|
367
|
|
368 if(hrng->State != HAL_RNG_STATE_ERROR)
|
|
369 {
|
|
370 /* Change RNG peripheral state */
|
|
371 hrng->State = HAL_RNG_STATE_READY;
|
|
372
|
|
373 /* Data Ready callback */
|
|
374 HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
|
|
375 }
|
|
376 }
|
|
377 }
|
|
378
|
|
379 /**
|
|
380 * @brief Returns generated random number in polling mode (Obsolete)
|
|
381 * Use HAL_RNG_GenerateRandomNumber() API instead.
|
|
382 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
383 * the configuration information for RNG.
|
|
384 * @retval Random value
|
|
385 */
|
|
386 uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
|
|
387 {
|
|
388 if(HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
|
|
389 {
|
|
390 return hrng->RandomNumber;
|
|
391 }
|
|
392 else
|
|
393 {
|
|
394 return 0;
|
|
395 }
|
|
396 }
|
|
397
|
|
398 /**
|
|
399 * @brief Returns a 32-bit random number with interrupt enabled (Obsolete),
|
|
400 * Use HAL_RNG_GenerateRandomNumber_IT() API instead.
|
|
401 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
402 * the configuration information for RNG.
|
|
403 * @retval 32-bit random number
|
|
404 */
|
|
405 uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
|
|
406 {
|
|
407 uint32_t random32bit = 0;
|
|
408
|
|
409 /* Process locked */
|
|
410 __HAL_LOCK(hrng);
|
|
411
|
|
412 /* Change RNG peripheral state */
|
|
413 hrng->State = HAL_RNG_STATE_BUSY;
|
|
414
|
|
415 /* Get a 32bit Random number */
|
|
416 random32bit = hrng->Instance->DR;
|
|
417
|
|
418 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
|
|
419 __HAL_RNG_ENABLE_IT(hrng);
|
|
420
|
|
421 /* Return the 32 bit random number */
|
|
422 return random32bit;
|
|
423 }
|
|
424
|
|
425 /**
|
|
426 * @brief Read latest generated random number.
|
|
427 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
428 * the configuration information for RNG.
|
|
429 * @retval random value
|
|
430 */
|
|
431 uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
|
|
432 {
|
|
433 return(hrng->RandomNumber);
|
|
434 }
|
|
435
|
|
436 /**
|
|
437 * @brief Data Ready callback in non-blocking mode.
|
|
438 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
439 * the configuration information for RNG.
|
|
440 * @param random32bit: generated random number.
|
|
441 * @retval None
|
|
442 */
|
|
443 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
|
|
444 {
|
|
445 /* NOTE : This function should not be modified. When the callback is needed,
|
|
446 function HAL_RNG_ReadyDataCallback must be implemented in the user file.
|
|
447 */
|
|
448 }
|
|
449
|
|
450 /**
|
|
451 * @brief RNG error callbacks.
|
|
452 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
453 * the configuration information for RNG.
|
|
454 * @retval None
|
|
455 */
|
|
456 __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
|
|
457 {
|
|
458 /* NOTE : This function should not be modified. When the callback is needed,
|
|
459 function HAL_RNG_ErrorCallback must be implemented in the user file.
|
|
460 */
|
|
461 }
|
|
462 /**
|
|
463 * @}
|
|
464 */
|
|
465
|
|
466
|
|
467 /** @addtogroup RNG_Exported_Functions_Group3
|
|
468 * @brief Peripheral State functions
|
|
469 *
|
|
470 @verbatim
|
|
471 ===============================================================================
|
|
472 ##### Peripheral State functions #####
|
|
473 ===============================================================================
|
|
474 [..]
|
|
475 This subsection permits to get in run-time the status of the peripheral
|
|
476 and the data flow.
|
|
477
|
|
478 @endverbatim
|
|
479 * @{
|
|
480 */
|
|
481
|
|
482 /**
|
|
483 * @brief Returns the RNG state.
|
|
484 * @param hrng: pointer to a RNG_HandleTypeDef structure that contains
|
|
485 * the configuration information for RNG.
|
|
486 * @retval HAL state
|
|
487 */
|
|
488 HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
|
|
489 {
|
|
490 return hrng->State;
|
|
491 }
|
|
492
|
|
493 /**
|
|
494 * @}
|
|
495 */
|
|
496
|
|
497 /**
|
|
498 * @}
|
|
499 */
|
|
500
|
|
501 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
|
|
502
|
|
503 #endif /* HAL_RNG_MODULE_ENABLED */
|
|
504
|
|
505 /**
|
|
506 * @}
|
|
507 */
|
|
508
|
|
509 /**
|
|
510 * @}
|
|
511 */
|
|
512
|
|
513 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|