Hi TDK
I made a test project similar to your code, but using interrupts as I am using interrupts in the Shortt clock project I am building. I don't thing using blocking or interrupts will make any difference to seed errors, but I wanted my test to be as close as possible to my application
Like you I got no errors. I used 64 bit counters to get more data, but still no errors.
The strange thing is I haven't had any more errors in my main project. I'm sure I wasn't imagining them as I put a breakpoints on the error code in the HAL RNG interrupt handler and the error happened twice.
I received an answer back on my service request. On the question of "true" randomness they said:
"The RNG output randomness is inherited from the randomness of the source.
To have a better feeling of the entropy of the RNG output, please refer to AN4320 "STM32 microcontroller random number generation validation using the NIST statistical test suite".
So I'm thinking that compared to algorithmic approximations of random number generation the numbers produced by the RNG are truly random by virtue of the fact they meet the NIST criteria.
On the question of recovering from a seed error there is a new HAL function: HAL_RNGEx_RecoverSeedError which was added in version 1.9 of the HAL Drivers. the code for this is:
/**
* @brief RNG sequence to recover from a seed error
* @param hrng: pointer to a RNG_HandleTypeDef structure.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_RNGEx_RecoverSeedError(RNG_HandleTypeDef *hrng)
{
HAL_StatusTypeDef status;
/* Check the RNG handle allocation */
if (hrng == NULL)
{
return HAL_ERROR;
}
/* Check RNG peripheral state */
if (hrng->State == HAL_RNG_STATE_READY)
{
/* Change RNG peripheral state */
hrng->State = HAL_RNG_STATE_BUSY;
/* sequence to fully recover from a seed error */
status = RNG_RecoverSeedError(hrng);
}
else
{
hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
status = HAL_ERROR;
}
/* Return the function status */
return status;
}
/**
* @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;
}
Regards
Rob