1 /**
2   *******************************************************************************************************
3   * @file    fm33lc0xx_fl_rng.c
4   * @author  FMSH Application Team
5   * @brief   Src file of RNG FL Module
6   *******************************************************************************************************
7   * @attention
8   *
9   * Copyright (c) [2021] [Fudan Microelectronics]
10   * THIS SOFTWARE is licensed under Mulan PSL v2.
11   * You can use this software according to the terms and conditions of the Mulan PSL v2.
12   * You may obtain a copy of Mulan PSL v2 at:
13   *          http://license.coscl.org.cn/MulanPSL2
14   * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
15   * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
16   * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
17   * See the Mulan PSL v2 for more details.
18   *
19   *******************************************************************************************************
20   */
21 
22 
23 /* Includes ------------------------------------------------------------------*/
24 #include "fm33lc0xx_fl.h"
25 /** @addtogroup FM33LC0XX_FL_Driver
26   * @{
27   */
28 
29 /** @addtogroup RNG
30   * @{
31   */
32 
33 #ifdef FL_RNG_DRIVER_ENABLED
34 
35 /* Private macros ------------------------------------------------------------*/
36 /** @addtogroup RNG_FL_Private_Macros
37 * @{
38 */
39 #define         IS_FL_RNG_INSTANCE(INTANCE)                         ((INTANCE) == RNG)
40 
41 #define         IS_FL_RNG_CLOCK_PRESCALER(__VALUE__)               (((__VALUE__) == FL_RCC_RNG_PSC_DIV1)||\
42                                                                      ((__VALUE__) == FL_RCC_RNG_PSC_DIV2)||\
43                                                                      ((__VALUE__) == FL_RCC_RNG_PSC_DIV4)||\
44                                                                      ((__VALUE__) == FL_RCC_RNG_PSC_DIV8)||\
45                                                                      ((__VALUE__) == FL_RCC_RNG_PSC_DIV16)||\
46                                                                      ((__VALUE__) == FL_RCC_RNG_PSC_DIV32))
47 /**
48   *@}
49   */
50 
51 /** @addtogroup RNG_FL_EF_Init
52   * @{
53   */
54 
55 /**
56   * @brief  复位RNG
57   *
58   * @param  RNGx 外设入口地址
59   *
60   * @retval 错误状态,可能值:
61   *         -FL_PASS 外设寄存器值恢复复位值
62   *         -FL_FAIL 未成功执行
63   */
FL_RNG_DeInit(RNG_Type * RNGx)64 FL_ErrorStatus FL_RNG_DeInit(RNG_Type *RNGx)
65 {
66     assert_param(IS_FL_RNG_INSTANCE(RNGx));
67     /* 使能外设复位 */
68     FL_RCC_EnablePeripheralReset();
69     /* 复位外设寄存器 */
70     FL_RCC_EnableResetAPB2Peripheral(FL_RCC_RSTAPB_RNG);
71     FL_RCC_DisableResetAPB2Peripheral(FL_RCC_RSTAPB_RNG);
72     /* 关闭外设总线始时钟和工作时钟 */
73     FL_RCC_DisableGroup2BusClock(FL_RCC_GROUP2_BUSCLK_RNG);
74     /* 锁定外设复位 */
75     FL_RCC_DisablePeripheralReset();
76     return FL_PASS;
77 }
78 
79 /**
80   * @brief  配置RNG
81   *
82   * @param  RNGx 外设入口地址
83   * @param  initStruct 指向 @ref FL_RNG_InitTypeDef 结构体的指针
84   *
85   * @note   RNG使用RCHF默认的8M作为时钟输入,经2分频后4M提供给RNG
86   *
87   * @retval 错误状态,可能值:
88   *         -FL_PASS 配置成功
89   *         -FL_FAIL 配置过程发生错误
90   */
FL_RNG_Init(RNG_Type * RNGx)91 FL_ErrorStatus FL_RNG_Init(RNG_Type *RNGx)
92 {
93     assert_param(IS_FL_RNG_INSTANCE(RNGx));
94     /* RNG 使用RCHF作为工作时钟因此必须确认RCHF使能*/
95     if(FL_RCC_RCHF_IsEnabled() != FL_SET)
96     {
97         FL_RCC_RCHF_Enable();
98     }
99     FL_RCC_EnableGroup2BusClock(FL_RCC_GROUP2_BUSCLK_RNG);
100     /* RNG 工作时钟预分频*/
101     switch(FL_RCC_RCHF_GetFrequency())
102     {
103         case FL_RCC_RCHF_FREQUENCY_8MHZ:
104             FL_RCC_SetRNGPrescaler(FL_RCC_RNG_PSC_DIV2);
105             break;
106         case FL_RCC_RCHF_FREQUENCY_16MHZ:
107             FL_RCC_SetRNGPrescaler(FL_RCC_RNG_PSC_DIV4);
108             break;
109         case FL_RCC_RCHF_FREQUENCY_24MHZ:
110             FL_RCC_SetRNGPrescaler(FL_RCC_RNG_PSC_DIV8);
111             break;
112         default:
113             FL_RCC_SetRNGPrescaler(FL_RCC_RNG_PSC_DIV2);
114             break;
115     }
116     /* RNG 工作时钟使能*/
117     FL_RCC_EnableGroup2OperationClock(FL_RCC_GROUP2_OPCLK_RNG);
118     return FL_PASS;
119 }
120 
121 /**
122   * @brief  获取一次随机数
123   *
124   * @note   如果返回值为0xFFFFFFFF 则说明随机数生成失败,请用户检查此函数的返回值,失败时重新生成
125   *
126   * @retval 生成的随机数,生成失败返回0xFFFFFFFF
127   *
128   */
GetRandomNumber(void)129 uint32_t GetRandomNumber(void)
130 {
131     uint32_t rn32;
132     FL_RNG_ClearFlag_RandomFail(RNG);
133     FL_RNG_Enable(RNGCTL);
134     /* 由于LFSR循环移位周期是32cycle,为保证随机数质量,应用应保证两次读取RNGOUT之间的间隔大于32个TRNG_CLK周期 */
135     FL_DelayUs(12);
136     FL_RNG_Disable(RNGCTL);
137     rn32 = FL_RNG_ReadData(RNG);
138     if(FL_RNG_IsActiveFlag_RandomFail(RNG))
139     {
140         FL_RNG_ClearFlag_RandomFail(RNG);
141         return 0xFFFFFFFF;
142     }
143     return rn32;
144 }
145 
146 /**
147   * @brief  获取CRC32
148   *
149   * @param  dataIn 待计算的数据
150   *
151   * @retval 计算得到的CRC32,计算失败返回0xFFFFFFFF
152   *
153   */
GetCrc32(uint32_t dataIn)154 uint32_t GetCrc32(uint32_t dataIn)
155 {
156     uint32_t i = 0;
157     uint32_t crc32 = 0;
158     FL_RNG_CRC_WriteData(RNG, dataIn);
159     FL_RNG_ClearFlag_CRCComplete(RNG);
160     FL_RNG_CRC_Enable(RNG);
161     while(0 == FL_RNG_IsActiveFlag_CRCComplete(RNG))
162     {
163         i++;
164         if(i > 600)
165         { break; }
166     }
167     if(i >= 600)
168     {
169         FL_RNG_ClearFlag_CRCComplete(RNG);
170         FL_RNG_Disable(RNGCTL);
171         return 0xFFFFFFFF;
172     }
173     FL_RNG_ClearFlag_CRCComplete(RNG);
174     crc32 = FL_RNG_ReadData(RNG);
175     FL_RNG_Disable(RNGCTL);
176     return crc32;
177 }
178 
179 /**
180   * @}
181   */
182 
183 #endif /* FL_RNG_DRIVER_ENABLED */
184 
185 /**
186   * @}
187   */
188 
189 /**
190   * @}
191   */
192 
193 /********************** (C) COPYRIGHT Fudan Microelectronics **** END OF FILE ***********************/
194