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