summaryrefslogtreecommitdiffstats
path: root/bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c')
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c282
1 files changed, 211 insertions, 71 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c
index 294847fc68..f0ab693db7 100644
--- a/bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_rng.c
@@ -9,6 +9,17 @@
* + Peripheral Control functions
* + Peripheral State functions
*
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
@verbatim
==============================================================================
##### How to use this driver #####
@@ -31,8 +42,8 @@
allows the user to configure dynamically the driver callbacks.
[..]
- Use Function @ref HAL_RNG_RegisterCallback() to register a user callback.
- Function @ref HAL_RNG_RegisterCallback() allows to register following callbacks:
+ Use Function HAL_RNG_RegisterCallback() to register a user callback.
+ Function HAL_RNG_RegisterCallback() allows to register following callbacks:
(+) ErrorCallback : RNG Error Callback.
(+) MspInitCallback : RNG MspInit.
(+) MspDeInitCallback : RNG MspDeInit.
@@ -40,9 +51,9 @@
and a pointer to the user callback function.
[..]
- Use function @ref HAL_RNG_UnRegisterCallback() to reset a callback to the default
+ Use function HAL_RNG_UnRegisterCallback() to reset a callback to the default
weak (surcharged) function.
- @ref HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle,
+ HAL_RNG_UnRegisterCallback() takes as parameters the HAL peripheral handle,
and the Callback ID.
This function allows to reset following callbacks:
(+) ErrorCallback : RNG Error Callback.
@@ -51,16 +62,16 @@
[..]
For specific callback ReadyDataCallback, use dedicated register callbacks:
- respectively @ref HAL_RNG_RegisterReadyDataCallback() , @ref HAL_RNG_UnRegisterReadyDataCallback().
+ respectively HAL_RNG_RegisterReadyDataCallback() , HAL_RNG_UnRegisterReadyDataCallback().
[..]
- By default, after the @ref HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET
+ By default, after the HAL_RNG_Init() and when the state is HAL_RNG_STATE_RESET
all callbacks are set to the corresponding weak (surcharged) functions:
- example @ref HAL_RNG_ErrorCallback().
+ example HAL_RNG_ErrorCallback().
Exception done for MspInit and MspDeInit functions that are respectively
- reset to the legacy weak (surcharged) functions in the @ref HAL_RNG_Init()
- and @ref HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand).
- If not, MspInit or MspDeInit are not null, the @ref HAL_RNG_Init() and @ref HAL_RNG_DeInit()
+ reset to the legacy weak (surcharged) functions in the HAL_RNG_Init()
+ and HAL_RNG_DeInit() only when these callbacks are null (not registered beforehand).
+ If not, MspInit or MspDeInit are not null, the HAL_RNG_Init() and HAL_RNG_DeInit()
keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
[..]
@@ -69,8 +80,8 @@
in HAL_RNG_STATE_READY or HAL_RNG_STATE_RESET state, thus registered (user)
MspInit/DeInit callbacks can be used during the Init/DeInit.
In that case first register the MspInit/MspDeInit user callbacks
- using @ref HAL_RNG_RegisterCallback() before calling @ref HAL_RNG_DeInit()
- or @ref HAL_RNG_Init() function.
+ using HAL_RNG_RegisterCallback() before calling HAL_RNG_DeInit()
+ or HAL_RNG_Init() function.
[..]
When The compilation define USE_HAL_RNG_REGISTER_CALLBACKS is set to 0 or
@@ -79,17 +90,6 @@
@endverbatim
******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * This software component is licensed by ST under BSD 3-Clause license,
- * the "License"; You may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- * opensource.org/licenses/BSD-3-Clause
- *
- ******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
@@ -110,17 +110,17 @@
/* Private types -------------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
-/** @defgroup RNG_Private_Defines
+/** @defgroup RNG_Private_Defines RNG Private Defines
* @ingroup RTEMSBSPsARMSTM32H7
* @{
*/
/* Health test control register information to use in CCM algorithm */
-#define RNG_HTCFG_1 0x17590ABCU /*!< magic number */
+#define RNG_HTCFG_1 0x17590ABCU /*!< Magic number */
#if defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
-#define RNG_HTCFG 0x000CAA74U /*!< for best latency and To be compliant with NIST */
-#else /*RNG_VER_3_2*/
-#define RNG_HTCFG 0x00007274U /*!< for best latency and To be compliant with NIST */
-#endif
+#define RNG_HTCFG 0x000CAA74U /*!< For best latency and to be compliant with NIST */
+#else /* RNG_VER_3_2 */
+#define RNG_HTCFG 0x00007274U /*!< For best latency and to be compliant with NIST */
+#endif /* RNG_VER_3_1 || RNG_VER_3_0 */
/**
* @}
*/
@@ -136,7 +136,6 @@
*/
/* Private macros ------------------------------------------------------------*/
/* Private functions prototypes ----------------------------------------------*/
-/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup RNG_Exported_Functions
@@ -144,8 +143,8 @@
*/
/** @addtogroup RNG_Exported_Functions_Group1
- * @brief Initialization and configuration functions
- *
+ * @brief Initialization and configuration functions
+ *
@verbatim
===============================================================================
##### Initialization and configuration functions #####
@@ -222,9 +221,9 @@ HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG_1);
/* for best latency and to be compliant with NIST */
WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG);
-#endif
+#endif /* RNG_VER_3_2 || RNG_VER_3_1 || RNG_VER_3_0 */
- /* Writing bits CONDRST=0*/
+ /* Writing bit CONDRST=0 */
CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
/* Get tick */
@@ -235,15 +234,19 @@ HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
{
if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
{
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- return HAL_ERROR;
+ /* New check to avoid false timeout detection in case of preemption */
+ if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
+ {
+ hrng->State = HAL_RNG_STATE_READY;
+ hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
+ return HAL_ERROR;
+ }
}
}
#else
/* Clock Error Detection Configuration */
MODIFY_REG(hrng->Instance->CR, RNG_CR_CED, hrng->Init.ClockErrorDetection);
-#endif /* end of RNG_CR_CONDRST */
+#endif /* RNG_CR_CONDRST */
/* Enable the RNG Peripheral */
__HAL_RNG_ENABLE(hrng);
@@ -261,9 +264,13 @@ HAL_StatusTypeDef HAL_RNG_Init(RNG_HandleTypeDef *hrng)
{
if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
{
- hrng->State = HAL_RNG_STATE_ERROR;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- return HAL_ERROR;
+ /* New check to avoid false timeout detection in case of preemption */
+ if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) != RESET)
+ {
+ hrng->State = HAL_RNG_STATE_ERROR;
+ hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
+ return HAL_ERROR;
+ }
}
}
@@ -299,7 +306,7 @@ HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
/* Clear Clock Error Detection bit when CONDRT bit is set to 1 */
MODIFY_REG(hrng->Instance->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CED_ENABLE | RNG_CR_CONDRST);
- /* Writing bits CONDRST=0*/
+ /* Writing bit CONDRST=0 */
CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
/* Get tick */
@@ -310,11 +317,15 @@ HAL_StatusTypeDef HAL_RNG_DeInit(RNG_HandleTypeDef *hrng)
{
if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
{
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- return HAL_ERROR;
+ /* New check to avoid false timeout detection in case of preemption */
+ if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
+ {
+ hrng->State = HAL_RNG_STATE_READY;
+ hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrng);
+ return HAL_ERROR;
+ }
}
}
@@ -397,7 +408,8 @@ __weak void HAL_RNG_MspDeInit(RNG_HandleTypeDef *hrng)
* @param pCallback pointer to the Callback function
* @retval HAL status
*/
-HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID, pRNG_CallbackTypeDef pCallback)
+HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_CallbackIDTypeDef CallbackID,
+ pRNG_CallbackTypeDef pCallback)
{
HAL_StatusTypeDef status = HAL_OK;
@@ -407,8 +419,6 @@ HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_Call
hrng->ErrorCode = HAL_RNG_ERROR_INVALID_CALLBACK;
return HAL_ERROR;
}
- /* Process locked */
- __HAL_LOCK(hrng);
if (HAL_RNG_STATE_READY == hrng->State)
{
@@ -462,14 +472,12 @@ HAL_StatusTypeDef HAL_RNG_RegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_Call
status = HAL_ERROR;
}
- /* Release Lock */
- __HAL_UNLOCK(hrng);
return status;
}
/**
* @brief Unregister an RNG Callback
- * RNG callabck is redirected to the weak predefined callback
+ * RNG callback is redirected to the weak predefined callback
* @param hrng RNG handle
* @param CallbackID ID of the callback to be unregistered
* This parameter can be one of the following values:
@@ -482,8 +490,6 @@ HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_Ca
{
HAL_StatusTypeDef status = HAL_OK;
- /* Process locked */
- __HAL_LOCK(hrng);
if (HAL_RNG_STATE_READY == hrng->State)
{
@@ -537,8 +543,6 @@ HAL_StatusTypeDef HAL_RNG_UnRegisterCallback(RNG_HandleTypeDef *hrng, HAL_RNG_Ca
status = HAL_ERROR;
}
- /* Release Lock */
- __HAL_UNLOCK(hrng);
return status;
}
@@ -616,8 +620,8 @@ HAL_StatusTypeDef HAL_RNG_UnRegisterReadyDataCallback(RNG_HandleTypeDef *hrng)
*/
/** @addtogroup RNG_Exported_Functions_Group2
- * @brief Peripheral Control functions
- *
+ * @brief Peripheral Control functions
+ *
@verbatim
===============================================================================
##### Peripheral Control functions #####
@@ -662,6 +666,20 @@ HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t
{
/* Change RNG peripheral state */
hrng->State = HAL_RNG_STATE_BUSY;
+#if defined(RNG_CR_CONDRST)
+ /* Check if there is a seed error */
+ if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
+ {
+ /* Update the error code */
+ hrng->ErrorCode = HAL_RNG_ERROR_SEED;
+ /* Reset from seed error */
+ status = RNG_RecoverSeedError(hrng);
+ if (status == HAL_ERROR)
+ {
+ return status;
+ }
+ }
+#endif /* RNG_CR_CONDRST */
/* Get tick */
tickstart = HAL_GetTick();
@@ -671,18 +689,39 @@ HAL_StatusTypeDef HAL_RNG_GenerateRandomNumber(RNG_HandleTypeDef *hrng, uint32_t
{
if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
{
- hrng->State = HAL_RNG_STATE_READY;
- hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
- /* Process Unlocked */
- __HAL_UNLOCK(hrng);
- return HAL_ERROR;
+ /* New check to avoid false timeout detection in case of preemption */
+ if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_DRDY) == RESET)
+ {
+ hrng->State = HAL_RNG_STATE_READY;
+ hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrng);
+ return HAL_ERROR;
+ }
}
}
/* Get a 32bit Random number */
hrng->RandomNumber = hrng->Instance->DR;
+#if defined(RNG_CR_CONDRST)
+ /* In case of seed error, the value available in the RNG_DR register must not
+ be used as it may not have enough entropy */
+ if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
+ {
+ /* Update the error code and status */
+ hrng->ErrorCode = HAL_RNG_ERROR_SEED;
+ status = HAL_ERROR;
+ /* Clear bit DRDY */
+ CLEAR_BIT(hrng->Instance->SR, RNG_FLAG_DRDY);
+ }
+ else /* No seed error */
+ {
+ *random32bit = hrng->RandomNumber;
+ }
+#else
*random32bit = hrng->RandomNumber;
+#endif /* RNG_CR_CONDRST */
hrng->State = HAL_RNG_STATE_READY;
}
else
@@ -765,9 +804,21 @@ void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
}
else if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
{
- /* Update the error code */
- hrng->ErrorCode = HAL_RNG_ERROR_SEED;
- rngclockerror = 1U;
+ /* Check if Seed Error Current Status (SECS) is set */
+ if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) == RESET)
+ {
+ /* RNG IP performed the reset automatically (auto-reset) */
+ /* Clear bit SEIS */
+ CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
+ }
+ else
+ {
+ /* Seed Error has not been recovered : Update the error code */
+ hrng->ErrorCode = HAL_RNG_ERROR_SEED;
+ rngclockerror = 1U;
+ /* Disable the IT */
+ __HAL_RNG_DISABLE_IT(hrng);
+ }
}
else
{
@@ -789,6 +840,8 @@ void HAL_RNG_IRQHandler(RNG_HandleTypeDef *hrng)
/* Clear the clock error flag */
__HAL_RNG_CLEAR_IT(hrng, RNG_IT_CEI | RNG_IT_SEI);
+
+ return;
}
/* Check RNG data ready interrupt occurred */
@@ -871,8 +924,8 @@ __weak void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
/** @addtogroup RNG_Exported_Functions_Group3
- * @brief Peripheral State functions
- *
+ * @brief Peripheral State functions
+ *
@verbatim
===============================================================================
##### Peripheral State functions #####
@@ -900,7 +953,7 @@ HAL_RNG_StateTypeDef HAL_RNG_GetState(RNG_HandleTypeDef *hrng)
* @brief Return the RNG handle error code.
* @param hrng: pointer to a RNG_HandleTypeDef structure.
* @retval RNG Error Code
-*/
+ */
uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
{
/* Return RNG Error Code */
@@ -913,6 +966,94 @@ uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
/**
* @}
*/
+#if defined(RNG_CR_CONDRST)
+/* Private functions ---------------------------------------------------------*/
+/** @addtogroup RNG_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief RNG sequence to recover from a seed error
+ * @param hrng pointer to a RNG_HandleTypeDef structure.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef RNG_RecoverSeedError(RNG_HandleTypeDef *hrng)
+{
+ __IO uint32_t count = 0U;
+
+ /*Check if seed error current status (SECS)is set */
+ if (__HAL_RNG_GET_FLAG(hrng, RNG_FLAG_SECS) == RESET)
+ {
+ /* RNG performed the reset automatically (auto-reset) */
+ /* Clear bit SEIS */
+ CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
+ }
+ else /* Sequence to fully recover from a seed error*/
+ {
+ /* Writing bit CONDRST=1*/
+ SET_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
+ /* Writing bit CONDRST=0*/
+ CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
+
+ /* Wait for conditioning reset process to be completed */
+ count = RNG_TIMEOUT_VALUE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ hrng->State = HAL_RNG_STATE_READY;
+ hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrng);
+#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
+ /* Call registered Error callback */
+ hrng->ErrorCallback(hrng);
+#else
+ /* Call legacy weak Error callback */
+ HAL_RNG_ErrorCallback(hrng);
+#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
+ return HAL_ERROR;
+ }
+ } while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST));
+
+ if (__HAL_RNG_GET_IT(hrng, RNG_IT_SEI) != RESET)
+ {
+ /* Clear bit SEIS */
+ CLEAR_BIT(hrng->Instance->SR, RNG_IT_SEI);
+ }
+
+ /* Wait for SECS to be cleared */
+ count = RNG_TIMEOUT_VALUE;
+ do
+ {
+ count-- ;
+ if (count == 0U)
+ {
+ hrng->State = HAL_RNG_STATE_READY;
+ hrng->ErrorCode |= HAL_RNG_ERROR_TIMEOUT;
+ /* Process Unlocked */
+ __HAL_UNLOCK(hrng);
+#if (USE_HAL_RNG_REGISTER_CALLBACKS == 1)
+ /* Call registered Error callback */
+ hrng->ErrorCallback(hrng);
+#else
+ /* Call legacy weak Error callback */
+ HAL_RNG_ErrorCallback(hrng);
+#endif /* USE_HAL_RNG_REGISTER_CALLBACKS */
+ return HAL_ERROR;
+ }
+ } while (HAL_IS_BIT_SET(hrng->Instance->SR, RNG_FLAG_SECS));
+ }
+ /* Update the error code */
+ hrng->ErrorCode &= ~ HAL_RNG_ERROR_SEED;
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+#endif /* RNG_CR_CONDRST */
#endif /* HAL_RNG_MODULE_ENABLED */
@@ -926,4 +1067,3 @@ uint32_t HAL_RNG_GetError(RNG_HandleTypeDef *hrng)
* @}
*/
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/