current_v/Drivers/FM33LG0xx_FL_Driver/Src/fm33lg0xx_fl_rng.c

202 lines
6.0 KiB
C
Raw Permalink Normal View History

2025-12-31 08:21:43 +08:00
/**
*******************************************************************************************************
* @file fm33lg0xx_fl_rng.c
* @author FMSH Application Team
* @brief Src file of RNG FL Module
*******************************************************************************************************
* @attention
*
* Copyright (c) [2021] [Fudan Microelectronics]
* THIS SOFTWARE is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*
*******************************************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "fm33lg0xx_fl.h"
/** @addtogroup FM33LG0XX_FL_Driver
* @{
*/
/** @addtogroup RNG
* @{
*/
#ifdef FL_RNG_DRIVER_ENABLED
/* Private macros ------------------------------------------------------------*/
/** @addtogroup RNG_FL_Private_Macros
* @{
*/
#define IS_FL_RNG_INSTANCE(INTANCE) ((INTANCE) == RNG)
#define IS_FL_RNG_CLOCK_PRESCALER(__VALUE__) (((__VALUE__) == FL_CMU_RNG_PSC_DIV1)||\
((__VALUE__) == FL_CMU_RNG_PSC_DIV2)||\
((__VALUE__) == FL_CMU_RNG_PSC_DIV4)||\
((__VALUE__) == FL_CMU_RNG_PSC_DIV8)||\
((__VALUE__) == FL_CMU_RNG_PSC_DIV16)||\
((__VALUE__) == FL_CMU_RNG_PSC_DIV32))
/**
*@}
*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup RNG_FL_EF_Init
* @{
*/
/**
* @brief RNG寄存器.
*
* @param RNGx
*
* @retval ErrorStatus枚举值
* -FL_PASS
* -FL_FAIL
*/
FL_ErrorStatus FL_RNG_DeInit(RNG_Type *RNGx)
{
assert_param(IS_FL_RNG_INSTANCE(RNGx));
/* 使能外设复位 */
FL_RMU_EnablePeripheralReset(RMU);
/* 复位外设寄存器 */
FL_RMU_EnableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_RNG);
FL_RMU_DisableResetAPBPeripheral(RMU, FL_RMU_RSTAPB_RNG);
/* 关闭外设总线始时钟和工作时钟 */
FL_CMU_DisableGroup2BusClock(FL_CMU_GROUP2_BUSCLK_RNG);
/* 锁定外设复位 */
FL_RMU_DisablePeripheralReset(RMU);
return FL_PASS;
}
/**
* @brief InitStruct .
* @param RNGx
*
* @param initStruct @ref FL_RNG_InitTypeDef .
*
* @note RNG使用RCHF默认的8M作为时钟输入24M提供给RNG
*
* @retval ErrorStatus枚举值
* -FL_PASS
* -FL_FAIL
*/
FL_ErrorStatus FL_RNG_Init(RNG_Type *RNGx)
{
assert_param(IS_FL_RNG_INSTANCE(RNGx));
/* RNG 使用RCHF作为工作时钟因此必须确认RCHF使能*/
if(FL_CMU_RCHF_IsEnabled() != FL_SET)
{
FL_CMU_RCHF_Enable();
}
/* RNG 总线时钟使能 */
FL_CMU_EnableGroup2BusClock(FL_CMU_GROUP2_BUSCLK_RNG);
/* RNG 工作时钟预分频*/
switch(FL_CMU_GetRCHFClockFreq())
{
case FL_CMU_RCHF_FREQUENCY_8MHZ:
FL_CMU_SetRNGPrescaler(FL_CMU_RNG_PSC_DIV2);
break;
case FL_CMU_RCHF_FREQUENCY_16MHZ:
FL_CMU_SetRNGPrescaler(FL_CMU_RNG_PSC_DIV4);
break;
case FL_CMU_RCHF_FREQUENCY_24MHZ:
FL_CMU_SetRNGPrescaler(FL_CMU_RNG_PSC_DIV8);
break;
case FL_CMU_RCHF_FREQUENCY_32MHZ:
FL_CMU_SetRNGPrescaler(FL_CMU_RNG_PSC_DIV8);
break;
default:
FL_CMU_SetRNGPrescaler(FL_CMU_RNG_PSC_DIV2);
break;
}
/* RNG 工作时钟使能*/
FL_CMU_EnableGroup3OperationClock(FL_CMU_GROUP3_OPCLK_RNG);
return FL_PASS;
}
/**
* @brief
*
* @param None
*
* @note 0xFFFFFFFF
*
* @retval 0xFFFFFFFF
*
*/
uint32_t GetRandomNumber(void)
{
uint32_t rn32;
FL_RNG_ClearFlag_RandomFail(RNG);
FL_RNG_Enable(RNG);
/* 由于LFSR循环移位周期是32cycle为保证随机数质量应用应保证两次读取RNGOUT之间的间隔大于32个TRNG_CLK周期 */
FL_DelayUs(12);
FL_RNG_Disable(RNG);
rn32 = FL_RNG_ReadData(RNG);
if(FL_RNG_IsActiveFlag_RandomFail(RNG))
{
FL_RNG_ClearFlag_RandomFail(RNG);
return 0xFFFFFFFF;
}
return rn32;
}
/**
* @brief CRC32
*
* @param dataIn
*
* @note None
*
* @retval CRC320xFFFFFFFF
*
*/
uint32_t GetCrc32(uint32_t dataIn)
{
uint32_t i = 0;
uint32_t crc32 = 0;
FL_RNG_CRC_WriteData(RNG, dataIn);
FL_RNG_ClearFlag_CRCComplete(RNG);
FL_RNG_CRC_Enable(RNG);
while(0 == FL_RNG_IsActiveFlag_CRCComplete(RNG))
{
i++;
if(i > 600)
{ break; }
}
if(i >= 600)
{
FL_RNG_ClearFlag_CRCComplete(RNG);
FL_RNG_Disable(RNG);
return 0xFFFFFFFF;
}
FL_RNG_ClearFlag_CRCComplete(RNG);
crc32 = FL_RNG_ReadData(RNG);
FL_RNG_Disable(RNG);
return crc32;
}
/**
* @}
*/
#endif /* FL_RNG_DRIVER_ENABLED */
/**
* @}
*/
/**
* @}
*/
/*************************(C) COPYRIGHT Fudan Microelectronics **** END OF FILE*************************/