STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_rng.c
Go to the documentation of this file.
1 
95 /* Includes ------------------------------------------------------------------*/
96 #include "stm32l4xx_hal.h"
97 
107 #ifdef HAL_RNG_MODULE_ENABLED
108 
109 
110 
111 /* Private types -------------------------------------------------------------*/
112 /* Private defines -----------------------------------------------------------*/
116 #define RNG_TIMEOUT_VALUE 2
117 
121 /* Private macros ------------------------------------------------------------*/
122 /* Private variables ---------------------------------------------------------*/
123 /* Private function prototypes -----------------------------------------------*/
124 /* Private functions ---------------------------------------------------------*/
125 /* Exported functions --------------------------------------------------------*/
126 
154 HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
155 {
156  /* Check the RNG handle allocation */
157  if(hrng == NULL)
158  {
159  return HAL_ERROR;
160  }
161 
162  assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
163 #if defined(RNG_CR_CED)
164  assert_param(IS_RNG_CED(hrng->Init.ClockErrorDetection));
165 #endif /* defined(RNG_CR_CED) */
166 
167 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
168  if(hrng->State == HAL_RNG_STATE_RESET)
169  {
170  /* Allocate lock resource and initialize it */
171  hrng->Lock = HAL_UNLOCKED;
172 
173  hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
174  hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
175 
176  if(hrng->MspInitCallback == NULL)
177  {
178  hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
179  }
180 
181  /* Init the low level hardware */
182  hrng->MspInitCallback(hrng);
183  }
184 #else
185  if(hrng->State == HAL_RNG_STATE_RESET)
186  {
187  /* Allocate lock resource and initialize it */
188  hrng->Lock = HAL_UNLOCKED;
189 
190  /* Init the low level hardware */
191  HAL_RNG_MspInit(hrng);
192  }
193 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
194 
195  /* Change RNG peripheral state */
196  hrng->State = HAL_RNG_STATE_BUSY;
197 
198 #if defined(RNG_CR_CED)
199  /* Clock Error Detection configuration */
200  MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
201 #endif /* defined(RNG_CR_CED) */
202 
203  /* Enable the RNG Peripheral */
204  __HAL_RNG_ENABLE(hrng);
205 
206  /* Initialize the RNG state */
207  hrng->State = HAL_RNG_STATE_READY;
208 
209  /* Initialise the error code */
210  hrng->ErrorCode = HAL_RNG_ERROR_NONE;
211 
212  /* Return function status */
213  return HAL_OK;
214 }
215 
221 HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
222 {
223  /* Check the RNG handle allocation */
224  if(hrng == NULL)
225  {
226  return HAL_ERROR;
227  }
228 
229 #if defined(RNG_CR_CED)
230  /* Clear Clock Error Detection bit */
231  CLEAR_BIT(hrng->Instance->CR, RNG_CR_CED);
232 #endif /* defined(RNG_CR_CED) */
233 
234  /* Disable the RNG Peripheral */
235  CLEAR_BIT(hrng->Instance->CR, RNG_CR_IE | RNG_CR_RNGEN);
236 
237  /* Clear RNG interrupt status flags */
238  CLEAR_BIT(hrng->Instance->SR, RNG_SR_CEIS | RNG_SR_SEIS);
239 
240 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
241  if(hrng->MspDeInitCallback == NULL)
242  {
243  hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
244  }
245 
246  /* DeInit the low level hardware */
247  hrng->MspDeInitCallback(hrng);
248 #else
249  /* DeInit the low level hardware */
250  HAL_RNG_MspDeInit(hrng);
251 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
252 
253  /* Update the RNG state */
254  hrng->State = HAL_RNG_STATE_RESET;
255 
256  /* Initialise the error code */
257  hrng->ErrorCode = HAL_RNG_ERROR_NONE;
258 
259  /* Release Lock */
260  __HAL_UNLOCK(hrng);
261 
262  /* Return the function status */
263  return HAL_OK;
264 }
265 
272 {
273  /* Prevent unused argument(s) compilation warning */
274  UNUSED(hrng);
275 
276  /* NOTE : This function should not be modified. When the callback is needed,
277  function HAL_RNG_MspInit must be implemented in the user file.
278  */
279 }
280 
287 {
288  /* Prevent unused argument(s) compilation warning */
289  UNUSED(hrng);
290 
291  /* NOTE : This function should not be modified. When the callback is needed,
292  function HAL_RNG_MspDeInit must be implemented in the user file.
293  */
294 }
295 
296 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
297 
310 {
311  HAL_StatusTypeDef status = HAL_OK;
312 
313  if(pCallback == NULL)
314  {
315  /* Update the error code */
316  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
317  return HAL_ERROR;
318  }
319  /* Process locked */
320  __HAL_LOCK(hrng);
321 
322  if(HAL_RNG_STATE_READY == hrng->State)
323  {
324  switch (CallbackID)
325  {
326  case HAL_RNG_ERROR_CB_ID :
327  hrng->ErrorCallback = pCallback;
328  break;
329 
330  case HAL_RNG_MSPINIT_CB_ID :
331  hrng->MspInitCallback = pCallback;
332  break;
333 
335  hrng->MspDeInitCallback = pCallback;
336  break;
337 
338  default :
339  /* Update the error code */
340  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
341  /* Return error status */
342  status = HAL_ERROR;
343  break;
344  }
345  }
346  else if(HAL_RNG_STATE_RESET == hrng->State)
347  {
348  switch (CallbackID)
349  {
350  case HAL_RNG_MSPINIT_CB_ID :
351  hrng->MspInitCallback = pCallback;
352  break;
353 
355  hrng->MspDeInitCallback = pCallback;
356  break;
357 
358  default :
359  /* Update the error code */
360  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
361  /* Return error status */
362  status = HAL_ERROR;
363  break;
364  }
365  }
366  else
367  {
368  /* Update the error code */
369  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
370  /* Return error status */
371  status = HAL_ERROR;
372  }
373 
374  /* Release Lock */
375  __HAL_UNLOCK(hrng);
376  return status;
377 }
378 
391 {
392 HAL_StatusTypeDef status = HAL_OK;
393 
394  /* Process locked */
395  __HAL_LOCK(hrng);
396 
397  if(HAL_RNG_STATE_READY == hrng->State)
398  {
399  switch (CallbackID)
400  {
401  case HAL_RNG_ERROR_CB_ID :
402  hrng->ErrorCallback = HAL_RNG_ErrorCallback; /* Legacy weak ErrorCallback */
403  break;
404 
405  case HAL_RNG_MSPINIT_CB_ID :
406  hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
407  break;
408 
410  hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspDeInit */
411  break;
412 
413  default :
414  /* Update the error code */
415  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
416  /* Return error status */
417  status = HAL_ERROR;
418  break;
419  }
420  }
421  else if(HAL_RNG_STATE_RESET == hrng->State)
422  {
423  switch (CallbackID)
424  {
425  case HAL_RNG_MSPINIT_CB_ID :
426  hrng->MspInitCallback = HAL_RNG_MspInit; /* Legacy weak MspInit */
427  break;
428 
430  hrng->MspDeInitCallback = HAL_RNG_MspDeInit; /* Legacy weak MspInit */
431  break;
432 
433  default :
434  /* Update the error code */
435  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
436  /* Return error status */
437  status = HAL_ERROR;
438  break;
439  }
440  }
441  else
442  {
443  /* Update the error code */
444  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
445  /* Return error status */
446  status = HAL_ERROR;
447  }
448 
449  /* Release Lock */
450  __HAL_UNLOCK(hrng);
451  return status;
452 }
453 
462 {
463  HAL_StatusTypeDef status = HAL_OK;
464 
465  if(pCallback == NULL)
466  {
467  /* Update the error code */
468  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
469  return HAL_ERROR;
470  }
471  /* Process locked */
472  __HAL_LOCK(hrng);
473 
474  if(HAL_RNG_STATE_READY == hrng->State)
475  {
476  hrng->ReadyDataCallback = pCallback;
477  }
478  else
479  {
480  /* Update the error code */
481  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
482  /* Return error status */
483  status = HAL_ERROR;
484  }
485 
486  /* Release Lock */
487  __HAL_UNLOCK(hrng);
488  return status;
489 }
490 
498 {
499  HAL_StatusTypeDef status = HAL_OK;
500 
501  /* Process locked */
502  __HAL_LOCK(hrng);
503 
504  if(HAL_RNG_STATE_READY == hrng->State)
505  {
506  hrng->ReadyDataCallback = HAL_RNG_ReadyDataCallback; /* Legacy weak ReadyDataCallback */
507  }
508  else
509  {
510  /* Update the error code */
511  hrng->ErrorCode |= HAL_RNG_ERROR_INVALID_CALLBACK;
512  /* Return error status */
513  status = HAL_ERROR;
514  }
515 
516  /* Release Lock */
517  __HAL_UNLOCK(hrng);
518  return status;
519 }
520 
521 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
522 
552 HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
553 {
554  uint32_t tickstart = 0;
555  HAL_StatusTypeDef status = HAL_OK;
556 
557  /* Process Locked */
558  __HAL_LOCK(hrng);
559 
560  /* Check RNS peripheral state */
561  if(hrng->State == HAL_RNG_STATE_READY)
562  {
563  /* Change RNG peripheral state */
564  hrng->State = HAL_RNG_STATE_BUSY;
565 
566  /* Get tick */
567  tickstart = HAL_GetTick();
568 
569  /* Check if data register contains valid random data */
570  while(__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
571  {
572  if((HAL_GetTick() - tickstart ) > RNG_TIMEOUT_VALUE)
573  {
574  hrng->State = HAL_RNG_STATE_ERROR;
575 
576  /* Process Unlocked */
577  __HAL_UNLOCK(hrng);
578 
579  return HAL_TIMEOUT;
580  }
581  }
582 
583  /* Get a 32bit Random number */
584  hrng->RandomNumber = hrng->Instance->DR;
585  *random32bit = hrng->RandomNumber;
586 
587  hrng->State = HAL_RNG_STATE_READY;
588  }
589  else
590  {
591  status = HAL_ERROR;
592  }
593 
594  /* Process Unlocked */
595  __HAL_UNLOCK(hrng);
596 
597  return status;
598 }
599 
606 {
607  HAL_StatusTypeDef status = HAL_OK;
608 
609  /* Process Locked */
610  __HAL_LOCK(hrng);
611 
612  /* Check RNG peripheral state */
613  if(hrng->State == HAL_RNG_STATE_READY)
614  {
615  /* Change RNG peripheral state */
616  hrng->State = HAL_RNG_STATE_BUSY;
617 
618  /* Process Unlocked */
619  __HAL_UNLOCK(hrng);
620 
621  /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
622  __HAL_RNG_ENABLE_IT(hrng);
623  }
624  else
625  {
626  /* Process Unlocked */
627  __HAL_UNLOCK(hrng);
628 
629  status = HAL_ERROR;
630  }
631 
632  return status;
633 }
634 
655 {
656  /* RNG clock error interrupt occurred */
657  if((__HAL_RNG_GET_IT(hrng, RNG_IT_CEI) != RESET) || (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET))
658  {
659  /* Change RNG peripheral state */
660  hrng->State = HAL_RNG_STATE_ERROR;
661 
662 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
663  /* Call registered Error callback */
664  hrng->ErrorCallback(hrng);
665 #else
666  /* Call legacy weak Error callback */
667  HAL_RNG_ErrorCallback(hrng);
668 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
669 
670  /* Clear the clock error flag */
671  __HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI|RNG_IT_SEI);
672 
673  }
674 
675  /* Check RNG data ready interrupt occurred */
676  if(__HAL_RNG_GET_IT(hrng, RNG_IT_DRDY) != RESET)
677  {
678  /* Generate random number once, so disable the IT */
679  __HAL_RNG_DISABLE_IT(hrng);
680 
681  /* Get the 32bit Random number (DRDY flag automatically cleared) */
682  hrng->RandomNumber = hrng->Instance->DR;
683 
684  if(hrng->State != HAL_RNG_STATE_ERROR)
685  {
686  /* Change RNG peripheral state */
687  hrng->State = HAL_RNG_STATE_READY;
688 
689 #if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
690  /* Call registered Data Ready callback */
691  hrng->ReadyDataCallback(hrng, hrng->RandomNumber);
692 #else
693  /* Call legacy weak Data Ready callback */
695 #endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
696  }
697  }
698 }
699 
708 {
709  if(HAL_RNG_GenerateRandomNumber(hrng, &(hrng->RandomNumber)) == HAL_OK)
710  {
711  return hrng->RandomNumber;
712  }
713  else
714  {
715  return 0;
716  }
717 }
718 
719 
727 {
728  uint32_t random32bit = 0;
729 
730  /* Process locked */
731  __HAL_LOCK(hrng);
732 
733  /* Change RNG peripheral state */
734  hrng->State = HAL_RNG_STATE_BUSY;
735 
736  /* Get a 32bit Random number */
737  random32bit = hrng->Instance->DR;
738 
739  /* Enable the RNG Interrupts: Data Ready, Clock error, Seed error */
740  __HAL_RNG_ENABLE_IT(hrng);
741 
742  /* Return the 32 bit random number */
743  return random32bit;
744 }
745 
746 
747 
754 {
755  return(hrng->RandomNumber);
756 }
757 
764 __weak void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
765 {
766  /* Prevent unused argument(s) compilation warning */
767  UNUSED(hrng);
768  UNUSED(random32bit);
769 
770  /* NOTE : This function should not be modified. When the callback is needed,
771  function HAL_RNG_ReadyDataCallback must be implemented in the user file.
772  */
773 }
774 
781 {
782  /* Prevent unused argument(s) compilation warning */
783  UNUSED(hrng);
784 
785  /* NOTE : This function should not be modified. When the callback is needed,
786  function HAL_RNG_ErrorCallback must be implemented in the user file.
787  */
788 }
789 
816 {
817  /* Return RNG handle state */
818  return hrng->State;
819 }
820 
827 {
828  /* Return RNG Error Code */
829  return hrng->ErrorCode;
830 }
840 #endif /* HAL_RNG_MODULE_ENABLED */
841 
849 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
void(* ErrorCallback)(struct __RNG_HandleTypeDef *hrng)
void(* pRNG_ReadyDataCallbackTypeDef)(RNG_HandleTypeDef *hrng, uint32_t random32bit)
void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
Data Ready callback in non-blocking mode.
RNG Handle Structure definition.
HAL_RNG_CallbackIDTypeDef
HAL RNG Callback ID enumeration definition.
void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
RNG error callback.
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...
__IO HAL_RNG_StateTypeDef State
This file contains all the functions prototypes for the HAL module driver.
uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
Return the RNG handle error code.
void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
Handle RNG interrupt request.
RNG_InitTypeDef Init
HAL_RNG_StateTypeDef
RNG HAL State Structure definition.
uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng)
Return generated random number in polling mode (Obsolete).
HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber_IT(RNG_HandleTypeDef *hrng)
Generate a 32-bit random number in interrupt mode.
void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
DeInitialize the RNG MSP.
uint32_t HAL_GetTick(void)
Provide a tick value in millisecond.
__HAL_UNLOCK(hrtc)
HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
DeInitialize the RNG peripheral.
void(* pRNG_CallbackTypeDef)(RNG_HandleTypeDef *hrng)
HAL RNG Callback pointer definition.
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...
uint32_t HAL_RNG_ReadLastRandomNumber(RNG_HandleTypeDef *hrng)
Read latest generated random number.
CLEAR_BIT(hrtc->Instance->CR, RTC_CR_WUTE)
HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID)
Unregister an RNG Callback RNG callabck is redirected to the weak predefined callback.
__HAL_LOCK(hrtc)
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.
void(* MspDeInitCallback)(struct __RNG_HandleTypeDef *hrng)
return HAL_OK
HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
Initialize the RNG peripheral and initialize the associated handle.
uint32_t HAL_RNG_GetRandomNumber_IT(RNG_HandleTypeDef *hrng)
Return a 32-bit random number with interrupt enabled (Obsolete).
HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
Return the RNG handle state.
void(* MspInitCallback)(struct __RNG_HandleTypeDef *hrng)
RNG_TypeDef * Instance
HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t *random32bit)
Generate a 32-bit random number.
HAL_LockTypeDef Lock
void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
Initialize the RNG MSP.
MODIFY_REG(hrtc->Instance->CR, RTC_CR_WUCKSEL,(uint32_t) WakeUpClock)
void(* ReadyDataCallback)(struct __RNG_HandleTypeDef *hrng, uint32_t random32bit)
__IO uint32_t ErrorCode
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))