1 /**
2 ******************************************************************************
3 * @file stm32h7xx_hal_rng_ex.c
4 * @author MCD Application Team
5 * @brief Extended RNG HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Random Number Generator (RNG) peripheral:
8 * + Lock configuration functions
9 * + Reset the RNG
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2017 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 */
23
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32h7xx_hal.h"
26
27 /** @addtogroup STM32H7xx_HAL_Driver
28 * @{
29 */
30
31 #if defined(RNG)
32
33 /** @addtogroup RNG_Ex
34 * @brief RNG Extended HAL module driver.
35 * @{
36 */
37
38 #ifdef HAL_RNG_MODULE_ENABLED
39 #if defined(RNG_CR_CONDRST)
40 /* Private types -------------------------------------------------------------*/
41 /* Private defines -----------------------------------------------------------*/
42 /** @defgroup RNG_Ex_Private_Defines RNGEx Private Defines
43 * @{
44 */
45 /* Health test control register information to use in CCM algorithm */
46 #define RNG_HTCFG_1 0x17590ABCU /*!< Magic number */
47 #if defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
48 #define RNG_HTCFG 0x000CAA74U /*!< For best latency and to be compliant with NIST */
49 #else /* RNG_VER_3_2 */
50 #define RNG_HTCFG 0x00007274U /*!< For best latency and to be compliant with NIST */
51 #endif /* RNG_VER_3_1 || RNG_VER_3_0 */
52 /**
53 * @}
54 */
55 /* Private variables ---------------------------------------------------------*/
56 /* Private constants ---------------------------------------------------------*/
57 /** @addtogroup RNG_Ex_Private_Constants
58 * @{
59 */
60 #define RNG_TIMEOUT_VALUE 2U
61 /**
62 * @}
63 */
64 /* Private macros ------------------------------------------------------------*/
65 /* Private functions prototypes ----------------------------------------------*/
66 /* Private functions --------------------------------------------------------*/
67 /* Exported functions --------------------------------------------------------*/
68
69 /** @addtogroup RNG_Ex_Exported_Functions
70 * @{
71 */
72
73 /** @addtogroup RNG_Ex_Exported_Functions_Group1
74 * @brief Configuration functions
75 *
76 @verbatim
77 ===============================================================================
78 ##### Configuration and lock functions #####
79 ===============================================================================
80 [..] This section provides functions allowing to:
81 (+) Configure the RNG with the specified parameters in the RNG_ConfigTypeDef
82 (+) Lock RNG configuration Allows user to lock a configuration until next reset.
83
84 @endverbatim
85 * @{
86 */
87
88 /**
89 * @brief Configure the RNG with the specified parameters in the
90 * RNG_ConfigTypeDef.
91 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
92 * the configuration information for RNG.
93 * @param pConf: pointer to a RNG_ConfigTypeDef structure that contains
94 * the configuration information for RNG module
95
96 * @retval HAL status
97 */
HAL_RNGEx_SetConfig(RNG_HandleTypeDef * hrng,RNG_ConfigTypeDef * pConf)98 HAL_StatusTypeDef HAL_RNGEx_SetConfig(RNG_HandleTypeDef *hrng, RNG_ConfigTypeDef *pConf)
99 {
100 uint32_t tickstart;
101 uint32_t cr_value;
102 HAL_StatusTypeDef status ;
103
104 /* Check the RNG handle allocation */
105 if ((hrng == NULL) || (pConf == NULL))
106 {
107 return HAL_ERROR;
108 }
109
110 /* Check the parameters */
111 assert_param(IS_RNG_ALL_INSTANCE(hrng->Instance));
112 assert_param(IS_RNG_CLOCK_DIVIDER(pConf->ClockDivider));
113 assert_param(IS_RNG_NIST_COMPLIANCE(pConf->NistCompliance));
114 assert_param(IS_RNG_CONFIG1(pConf->Config1));
115 assert_param(IS_RNG_CONFIG2(pConf->Config2));
116 assert_param(IS_RNG_CONFIG3(pConf->Config3));
117
118 /* Check RNG peripheral state */
119 if (hrng->State == HAL_RNG_STATE_READY)
120 {
121 /* Change RNG peripheral state */
122 hrng->State = HAL_RNG_STATE_BUSY;
123
124 /* Disable RNG */
125 __HAL_RNG_DISABLE(hrng);
126
127 /* RNG CR register configuration. Set value in CR register for :
128 - NIST Compliance setting
129 - Clock divider value
130 - CONFIG 1, CONFIG 2 and CONFIG 3 values */
131
132 cr_value = (uint32_t)(pConf->ClockDivider | pConf->NistCompliance
133 | (pConf->Config1 << RNG_CR_RNG_CONFIG1_Pos)
134 | (pConf->Config2 << RNG_CR_RNG_CONFIG2_Pos)
135 | (pConf->Config3 << RNG_CR_RNG_CONFIG3_Pos));
136
137 MODIFY_REG(hrng->Instance->CR, RNG_CR_NISTC | RNG_CR_CLKDIV | RNG_CR_RNG_CONFIG1
138 | RNG_CR_RNG_CONFIG2 | RNG_CR_RNG_CONFIG3,
139 (uint32_t)(RNG_CR_CONDRST | cr_value));
140
141 #if defined(RNG_VER_3_2) || defined(RNG_VER_3_1) || defined(RNG_VER_3_0)
142 /*!< magic number must be written immediately before to RNG_HTCRG */
143 WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG_1);
144 /* for best latency and to be compliant with NIST */
145 WRITE_REG(hrng->Instance->HTCR, RNG_HTCFG);
146 #endif /* RNG_VER_3_2 || RNG_VER_3_1 || RNG_VER_3_0 */
147
148 /* Writing bit CONDRST=0*/
149 CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
150 /* Get tick */
151 tickstart = HAL_GetTick();
152
153 /* Wait for conditioning reset process to be completed */
154 while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
155 {
156 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
157 {
158 /* New check to avoid false timeout detection in case of prememption */
159 if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
160 {
161 hrng->State = HAL_RNG_STATE_READY;
162 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
163 return HAL_ERROR;
164 }
165 }
166 }
167
168 /* Enable RNG */
169 __HAL_RNG_ENABLE(hrng);
170
171 /* Initialize the RNG state */
172 hrng->State = HAL_RNG_STATE_READY;
173
174 /* function status */
175 status = HAL_OK;
176 }
177 else
178 {
179 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
180 status = HAL_ERROR;
181 }
182
183 /* Return the function status */
184 return status;
185 }
186
187 /**
188 * @brief Get the RNG Configuration and fill parameters in the
189 * RNG_ConfigTypeDef.
190 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
191 * the configuration information for RNG.
192 * @param pConf: pointer to a RNG_ConfigTypeDef structure that contains
193 * the configuration information for RNG module
194
195 * @retval HAL status
196 */
HAL_RNGEx_GetConfig(RNG_HandleTypeDef * hrng,RNG_ConfigTypeDef * pConf)197 HAL_StatusTypeDef HAL_RNGEx_GetConfig(RNG_HandleTypeDef *hrng, RNG_ConfigTypeDef *pConf)
198 {
199
200 HAL_StatusTypeDef status ;
201
202 /* Check the RNG handle allocation */
203 if ((hrng == NULL) || (pConf == NULL))
204 {
205 return HAL_ERROR;
206 }
207
208 /* Check RNG peripheral state */
209 if (hrng->State == HAL_RNG_STATE_READY)
210 {
211 /* Change RNG peripheral state */
212 hrng->State = HAL_RNG_STATE_BUSY;
213
214 /* Get RNG parameters */
215 pConf->Config1 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG1) >> RNG_CR_RNG_CONFIG1_Pos) ;
216 pConf->Config2 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG2) >> RNG_CR_RNG_CONFIG2_Pos);
217 pConf->Config3 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG3) >> RNG_CR_RNG_CONFIG3_Pos);
218 pConf->ClockDivider = (hrng->Instance->CR & RNG_CR_CLKDIV);
219 pConf->NistCompliance = (hrng->Instance->CR & RNG_CR_NISTC);
220
221 /* Initialize the RNG state */
222 hrng->State = HAL_RNG_STATE_READY;
223
224 /* function status */
225 status = HAL_OK;
226 }
227 else
228 {
229 hrng->ErrorCode |= HAL_RNG_ERROR_BUSY;
230 status = HAL_ERROR;
231 }
232
233 /* Return the function status */
234 return status;
235 }
236
237 /**
238 * @brief RNG current configuration lock.
239 * @note This function allows to lock RNG peripheral configuration.
240 * Once locked, HW RNG reset has to be performed prior any further
241 * configuration update.
242 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
243 * the configuration information for RNG.
244 * @retval HAL status
245 */
HAL_RNGEx_LockConfig(RNG_HandleTypeDef * hrng)246 HAL_StatusTypeDef HAL_RNGEx_LockConfig(RNG_HandleTypeDef *hrng)
247 {
248 HAL_StatusTypeDef status;
249
250 /* Check the RNG handle allocation */
251 if (hrng == NULL)
252 {
253 return HAL_ERROR;
254 }
255
256 /* Check RNG peripheral state */
257 if (hrng->State == HAL_RNG_STATE_READY)
258 {
259 /* Change RNG peripheral state */
260 hrng->State = HAL_RNG_STATE_BUSY;
261
262 /* Perform RNG configuration Lock */
263 MODIFY_REG(hrng->Instance->CR, RNG_CR_CONFIGLOCK, RNG_CR_CONFIGLOCK);
264
265 /* Change RNG peripheral state */
266 hrng->State = HAL_RNG_STATE_READY;
267
268 /* function status */
269 status = HAL_OK;
270 }
271 else
272 {
273 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
274 status = HAL_ERROR;
275 }
276
277 /* Return the function status */
278 return status;
279 }
280
281
282 /**
283 * @}
284 */
285
286 /** @addtogroup RNG_Ex_Exported_Functions_Group2
287 * @brief Recover from seed error function
288 *
289 @verbatim
290 ===============================================================================
291 ##### Configuration and lock functions #####
292 ===============================================================================
293 [..] This section provide function allowing to:
294 (+) Recover from a seed error
295
296 @endverbatim
297 * @{
298 */
299
300 /**
301 * @brief RNG sequence to recover from a seed error
302 * @param hrng: pointer to a RNG_HandleTypeDef structure.
303 * @retval HAL status
304 */
HAL_RNGEx_RecoverSeedError(RNG_HandleTypeDef * hrng)305 HAL_StatusTypeDef HAL_RNGEx_RecoverSeedError(RNG_HandleTypeDef *hrng)
306 {
307 HAL_StatusTypeDef status;
308
309 /* Check the RNG handle allocation */
310 if (hrng == NULL)
311 {
312 return HAL_ERROR;
313 }
314
315 /* Check RNG peripheral state */
316 if (hrng->State == HAL_RNG_STATE_READY)
317 {
318 /* Change RNG peripheral state */
319 hrng->State = HAL_RNG_STATE_BUSY;
320
321 /* sequence to fully recover from a seed error */
322 status = RNG_RecoverSeedError(hrng);
323 }
324 else
325 {
326 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
327 status = HAL_ERROR;
328 }
329
330 /* Return the function status */
331 return status;
332 }
333
334 /**
335 * @}
336 */
337
338 /**
339 * @}
340 */
341
342 #endif /* RNG_CR_CONDRST */
343 #endif /* HAL_RNG_MODULE_ENABLED */
344 /**
345 * @}
346 */
347
348 #endif /* RNG */
349
350 /**
351 * @}
352 */
353
354