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