STM32F4xx_HAL_Driver  1.8.3
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 
155 HAL_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 
216 HAL_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)
299 HAL_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 
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 
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 
377 HAL_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 
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 
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 
444 HAL_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 
480 HAL_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 
536 HAL_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 
594 HAL_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 
629 uint32_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 
648 uint32_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 
689 void 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 
764 uint32_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 }
826 HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng)
827 {
828  return hrng->State;
829 }
830 
836 uint32_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.
HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
UnRegister the Data Ready RNG Callback Data Ready RNG Callback is redirected to the weak HAL_RNG_Read...
HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
Register a User RNG Callback To be used instead of the weak predefined callback.
HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
Unregister an RNG Callback RNG callback is redirected to the weak predefined callback.
void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
DeInitializes the RNG MSP.
HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
DeInitializes the RNG peripheral.
HAL_StatusTypeDef HAL_RNG_RegisterReadyDataCallback(RNG_HandleTypeDef *hrng, pRNG_ReadyDataCallbackTypeDef pCallback)
Register Data Ready RNG Callback To be used instead of the weak HAL_RNG_ReadyDataCallback() predefine...
HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
Initializes the RNG peripheral and creates the associated handle.
void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
Initializes the RNG MSP.
HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
Generates a 32-bit random number in interrupt mode.
void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
Data Ready callback in non-blocking mode.
void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
Handles RNG interrupt request.
void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
RNG error callbacks.
HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
Generates a 32-bit random number.
uint32_t HAL_RNG_ReadLastRandomNumber(const RNG_HandleTypeDef *hrng)
Read latest generated random number.
uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
Returns generated random number in polling mode (Obsolete) Use HAL_RNG_GenerateRandomNumber() API ins...
uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
Returns a 32-bit random number with interrupt enabled (Obsolete), Use HAL_RNG_GenerateRandomNumber_IT...
uint32_t HAL_RNG_GetError(const RNG_HandleTypeDef *hrng)
Return the RNG handle error code.
HAL_RNG_StateTypeDef HAL_RNG_GetState(const RNG_HandleTypeDef *hrng)
Returns the RNG state.
HAL_RNG_StateTypeDef
@ HAL_RNG_STATE_READY
@ HAL_RNG_STATE_RESET
@ HAL_RNG_STATE_ERROR
@ HAL_RNG_STATE_BUSY
HAL_RNG_CallbackIDTypeDef
HAL RNG Callback ID enumeration definition.
void(* pRNG_ReadyDataCallbackTypeDef)(RNG_HandleTypeDef *hrng, uint32_t random32bit)
void(* pRNG_CallbackTypeDef)(RNG_HandleTypeDef *hrng)
HAL RNG Callback pointer definition.
@ HAL_RNG_MSPINIT_CB_ID
@ HAL_RNG_MSPDEINIT_CB_ID
@ HAL_RNG_ERROR_CB_ID
This file contains all the functions prototypes for the HAL module driver.