STM32F4xx HAL Documentation
Hardware Abstraction Layer for STM32F4 familiy
Loading...
Searching...
No Matches
stm32f4xx_hal_rng.c
Go to the documentation of this file.
1
95/* Includes ------------------------------------------------------------------*/
96#include "stm32f4xx_hal.h"
97
102#if defined (RNG)
103
109#ifdef HAL_RNG_MODULE_ENABLED
110
111/* Private types -------------------------------------------------------------*/
112/* Private defines -----------------------------------------------------------*/
113/* Private variables ---------------------------------------------------------*/
114/* Private constants ---------------------------------------------------------*/
118#define RNG_TIMEOUT_VALUE 2U
122/* Private macros ------------------------------------------------------------*/
123/* Private functions prototypes ----------------------------------------------*/
124/* Private functions ---------------------------------------------------------*/
125/* Exported functions --------------------------------------------------------*/
126
155HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
156{
157 /* Check the RNG handle allocation */
158 if (hrng == NULL)
159 {
160 return HAL_ERROR;
161 }
162 /* Check the parameters */
163 assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
164
165#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
166 if (hrng->State == HAL_RNG_STATE_RESET)
167 {
168 /* Allocate lock resource and initialize it */
169 hrng->Lock = HAL_UNLOCKED;
170
171 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
172 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
173
174 if (hrng->MspInitCallback == NULL)
175 {
176 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
177 }
178
179 /* Init the low level hardware */
180 hrng->MspInitCallback(hrng);
181 }
182#else
183 if (hrng->State == HAL_RNG_STATE_RESET)
184 {
185 /* Allocate lock resource and initialize it */
186 hrng->Lock = HAL_UNLOCKED;
187
188 /* Init the low level hardware */
189 HAL_RNG_MspInit(hrng);
190 }
191#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
192
193 /* Change RNG peripheral state */
194 hrng->State = HAL_RNG_STATE_BUSY;
195
196
197 /* Enable the RNG Peripheral */
198 __HAL_RNG_ENABLE(hrng);
199
200 /* Initialize the RNG state */
201 hrng->State = HAL_RNG_STATE_READY;
202
203 /* Initialise the error code */
204 hrng->ErrorCode = HAL_RNG_ERROR_NONE;
205
206 /* Return function status */
207 return HAL_OK;
208}
209
216HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
217{
218 /* Check the RNG handle allocation */
219 if (hrng == NULL)
220 {
221 return HAL_ERROR;
222 }
223
224 /* Disable the RNG Peripheral */
225 CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
226
227 /* Clear RNG interrupt status flags */
228 CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
229
230#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
231 if (hrng->MspDeInitCallback == NULL)
232 {
233 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
234 }
235
236 /* DeInit the low level hardware */
237 hrng->MspDeInitCallback(hrng);
238#else
239 /* DeInit the low level hardware */
240 HAL_RNG_MspDeInit(hrng);
241#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
242
243 /* Update the RNG state */
244 hrng->State = HAL_RNG_STATE_RESET;
245
246 /* Initialise the error code */
247 hrng->ErrorCode = HAL_RNG_ERROR_NONE;
248
249 /* Release Lock */
250 __HAL_UNLOCK(hrng);
251
252 /* Return the function status */
253 return HAL_OK;
254}
255
262__weak void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
263{
264 /* Prevent unused argument(s) compilation warning */
265 UNUSED(hrng);
266 /* NOTE : This function should not be modified. When the callback is needed,
267 function HAL_RNG_MspInit must be implemented in the user file.
268 */
269}
270
277__weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
278{
279 /* Prevent unused argument(s) compilation warning */
280 UNUSED(hrng);
281 /* NOTE : This function should not be modified. When the callback is needed,
282 function HAL_RNG_MspDeInit must be implemented in the user file.
283 */
284}
285
286#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
299HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID,
300 pRNG_CallbackTypeDef pCallback)
301{
302 HAL_StatusTypeDef status = HAL_OK;
303
304 if (pCallback == NULL)
305 {
306 /* Update the error code */
307 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
308 return HAL_ERROR;
309 }
310
311 if (HAL_RNG_STATE_READY == hrng->State)
312 {
313 switch (CallbackID)
314 {
315 case HAL_RNG_ERROR_CB_ID :
316 hrng->ErrorCallback = pCallback;
317 break;
318
319 case HAL_RNG_MSPINIT_CB_ID :
320 hrng->MspInitCallback = pCallback;
321 break;
322
323 case HAL_RNG_MSPDEINIT_CB_ID :
324 hrng->MspDeInitCallback = pCallback;
325 break;
326
327 default :
328 /* Update the error code */
329 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
330 /* Return error status */
331 status = HAL_ERROR;
332 break;
333 }
334 }
335 else if (HAL_RNG_STATE_RESET == hrng->State)
336 {
337 switch (CallbackID)
338 {
339 case HAL_RNG_MSPINIT_CB_ID :
340 hrng->MspInitCallback = pCallback;
341 break;
342
343 case HAL_RNG_MSPDEINIT_CB_ID :
344 hrng->MspDeInitCallback = pCallback;
345 break;
346
347 default :
348 /* Update the error code */
349 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
350 /* Return error status */
351 status = HAL_ERROR;
352 break;
353 }
354 }
355 else
356 {
357 /* Update the error code */
358 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
359 /* Return error status */
360 status = HAL_ERROR;
361 }
362
363 return status;
364}
365
377HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
378{
379 HAL_StatusTypeDef status = HAL_OK;
380
381
382 if (HAL_RNG_STATE_READY == hrng->State)
383 {
384 switch (CallbackID)
385 {
386 case HAL_RNG_ERROR_CB_ID :
387 hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
388 break;
389
390 case HAL_RNG_MSPINIT_CB_ID :
391 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
392 break;
393
394 case HAL_RNG_MSPDEINIT_CB_ID :
395 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
396 break;
397
398 default :
399 /* Update the error code */
400 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
401 /* Return error status */
402 status = HAL_ERROR;
403 break;
404 }
405 }
406 else if (HAL_RNG_STATE_RESET == hrng->State)
407 {
408 switch (CallbackID)
409 {
410 case HAL_RNG_MSPINIT_CB_ID :
411 hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
412 break;
413
414 case HAL_RNG_MSPDEINIT_CB_ID :
415 hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */
416 break;
417
418 default :
419 /* Update the error code */
420 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
421 /* Return error status */
422 status = HAL_ERROR;
423 break;
424 }
425 }
426 else
427 {
428 /* Update the error code */
429 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
430 /* Return error status */
431 status = HAL_ERROR;
432 }
433
434 return status;
435}
436
444HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
445{
446 HAL_StatusTypeDef status = HAL_OK;
447
448 if (pCallback == NULL)
449 {
450 /* Update the error code */
451 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
452 return HAL_ERROR;
453 }
454 /* Process locked */
455 __HAL_LOCK(hrng);
456
457 if (HAL_RNG_STATE_READY == hrng->State)
458 {
459 hrng->ReadyDataCallback = pCallback;
460 }
461 else
462 {
463 /* Update the error code */
464 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
465 /* Return error status */
466 status = HAL_ERROR;
467 }
468
469 /* Release Lock */
470 __HAL_UNLOCK(hrng);
471 return status;
472}
473
480HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
481{
482 HAL_StatusTypeDef status = HAL_OK;
483
484 /* Process locked */
485 __HAL_LOCK(hrng);
486
487 if (HAL_RNG_STATE_READY == hrng->State)
488 {
489 hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
490 }
491 else
492 {
493 /* Update the error code */
494 hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
495 /* Return error status */
496 status = HAL_ERROR;
497 }
498
499 /* Release Lock */
500 __HAL_UNLOCK(hrng);
501 return status;
502}
503
504#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
505
536HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
537{
538 uint32_t tickstart;
539 HAL_StatusTypeDef status = HAL_OK;
540
541 /* Process Locked */
542 __HAL_LOCK(hrng);
543
544 /* Check RNG peripheral state */
545 if (hrng->State == HAL_RNG_STATE_READY)
546 {
547 /* Change RNG peripheral state */
548 hrng->State = HAL_RNG_STATE_BUSY;
549
550 /* Get tick */
551 tickstart = HAL_GetTick();
552
553 /* Check if data register contains valid random data */
554 while (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
555 {
556 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
557 {
558 /* New check to avoid false timeout detection in case of preemption */
559 if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
560 {
561 hrng->State = HAL_RNG_STATE_READY;
562 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
563 /* Process Unlocked */
564 __HAL_UNLOCK(hrng);
565 return HAL_ERROR;
566 }
567 }
568 }
569
570 /* Get a 32bit Random number */
571 hrng->RandomNumber = hrng->Instance->DR;
572 *random32bit = hrng->RandomNumber;
573
574 hrng->State = HAL_RNG_STATE_READY;
575 }
576 else
577 {
578 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
579 status = HAL_ERROR;
580 }
581
582 /* Process Unlocked */
583 __HAL_UNLOCK(hrng);
584
585 return status;
586}
587
594HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
595{
596 HAL_StatusTypeDef status = HAL_OK;
597
598 /* Process Locked */
599 __HAL_LOCK(hrng);
600
601 /* Check RNG peripheral state */
602 if (hrng->State == HAL_RNG_STATE_READY)
603 {
604 /* Change RNG peripheral state */
605 hrng->State = HAL_RNG_STATE_BUSY;
606
607 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
608 __HAL_RNG_ENABLE_IT(hrng);
609 }
610 else
611 {
612 /* Process Unlocked */
613 __HAL_UNLOCK(hrng);
614
615 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
616 status = HAL_ERROR;
617 }
618
619 return status;
620}
621
629uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
630{
631 if (HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
632 {
633 return hrng->RandomNumber;
634 }
635 else
636 {
637 return 0U;
638 }
639}
640
648uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
649{
650 uint32_t random32bit = 0U;
651
652 /* Process locked */
653 __HAL_LOCK(hrng);
654
655 /* Change RNG peripheral state */
656 hrng->State = HAL_RNG_STATE_BUSY;
657
658 /* Get a 32bit Random number */
659 random32bit = hrng->Instance->DR;
660
661 /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
662 __HAL_RNG_ENABLE_IT(hrng);
663
664 /* Return the 32 bit random number */
665 return random32bit;
666}
667
689void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
690{
691 uint32_t rngclockerror = 0U;
692 uint32_t itflag = hrng->Instance->SR;
693
694 /* RNG clock error interrupt occurred */
695 if ((itflag & RNG_IT_CEI) == RNG_IT_CEI)
696 {
697 /* Update the error code */
698 hrng->ErrorCode = HAL_RNG_ERROR_CLOCK;
699 rngclockerror = 1U;
700 }
701 else if ((itflag & RNG_IT_SEI) == RNG_IT_SEI)
702 {
703 /* Update the error code */
704 hrng->ErrorCode = HAL_RNG_ERROR_SEED;
705 rngclockerror = 1U;
706 }
707 else
708 {
709 /* Nothing to do */
710 }
711
712 if (rngclockerror == 1U)
713 {
714 /* Change RNG peripheral state */
715 hrng->State = HAL_RNG_STATE_ERROR;
716
717#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
718 /* Call registered Error callback */
719 hrng->ErrorCallback(hrng);
720#else
721 /* Call legacy weak Error callback */
722 HAL_RNG_ErrorCallback(hrng);
723#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
724
725 /* Clear the clock error flag */
726 __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
727
728 return;
729 }
730
731 /* Check RNG data ready interrupt occurred */
732 if ((itflag & RNG_IT_DRDY) == RNG_IT_DRDY)
733 {
734 /* Generate random number once, so disable the IT */
735 __HAL_RNG_DISABLE_IT(hrng);
736
737 /* Get the 32bit Random number (DRDY flag automatically cleared) */
738 hrng->RandomNumber = hrng->Instance->DR;
739
740 if (hrng->State != HAL_RNG_STATE_ERROR)
741 {
742 /* Change RNG peripheral state */
743 hrng->State = HAL_RNG_STATE_READY;
744 /* Process Unlocked */
745 __HAL_UNLOCK(hrng);
746
747#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
748 /* Call registered Data Ready callback */
749 hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
750#else
751 /* Call legacy weak Data Ready callback */
752 HAL_RNG_ReadyDataCallback(hrng, hrng->RandomNumber);
753#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
754 }
755 }
756}
757
764uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng)
765{
766 return (hrng->RandomNumber);
767}
768
776__weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
777{
778 /* Prevent unused argument(s) compilation warning */
779 UNUSED(hrng);
780 UNUSED(random32bit);
781 /* NOTE : This function should not be modified. When the callback is needed,
782 function HAL_RNG_ReadyDataCallback must be implemented in the user file.
783 */
784}
785
792__weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
793{
794 /* Prevent unused argument(s) compilation warning */
795 UNUSED(hrng);
796 /* NOTE : This function should not be modified. When the callback is needed,
797 function HAL_RNG_ErrorCallback must be implemented in the user file.
798 */
799}
826HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng)
827{
828 return hrng->State;
829}
830
836uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng)
837{
838 /* Return RNG Error Code */
839 return hrng->ErrorCode;
840}
850#endif /* HAL_RNG_MODULE_ENABLED */
855#endif /* RNG */
856
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
#define assert_param(expr)
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef
HAL Status structures definition
@ HAL_ERROR
@ HAL_OK
#define UNUSED(X)
#define __HAL_UNLOCK(__HANDLE__)
@ HAL_UNLOCKED
#define __HAL_LOCK(__HANDLE__)