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 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 "stm32u5xx_hal.h"
26
27 /** @addtogroup STM32U5xx_HAL_Driver
28 * @{
29 */
30
31 #if defined(RNG)
32
33 /** @addtogroup RNGEx
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 RNGEx_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 /** @defgroup RNGEx_Exported_Functions RNGEx Exported Functions
57 * @{
58 */
59
60 /** @defgroup RNGEx_Exported_Functions_Group1 Configuration and lock functions
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,const RNG_ConfigTypeDef * pConf)85 HAL_StatusTypeDef HAL_RNGEx_SetConfig(RNG_HandleTypeDef *hrng, const 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 | RNG_CR_ARDIS,
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 /* RNG noise source control in accordance with NIST */
133 WRITE_REG(hrng->Instance->NSCR, pConf->NoiseSource);
134
135 /* Writing bit CONDRST=0*/
136 CLEAR_BIT(hrng->Instance->CR, RNG_CR_CONDRST);
137 /* Get tick */
138 tickstart = HAL_GetTick();
139
140 /* Wait for conditioning reset process to be completed */
141 while (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
142 {
143 if ((HAL_GetTick() - tickstart) > RNG_TIMEOUT_VALUE)
144 {
145 /* New check to avoid false timeout detection in case of prememption */
146 if (HAL_IS_BIT_SET(hrng->Instance->CR, RNG_CR_CONDRST))
147 {
148 hrng->State = HAL_RNG_STATE_READY;
149 hrng->ErrorCode = HAL_RNG_ERROR_TIMEOUT;
150 return HAL_ERROR;
151 }
152 }
153 }
154
155 /* Enable RNG */
156 __HAL_RNG_ENABLE(hrng);
157
158 /* Initialize the RNG state */
159 hrng->State = HAL_RNG_STATE_READY;
160
161 /* function status */
162 status = HAL_OK;
163 }
164 else
165 {
166 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
167 status = HAL_ERROR;
168 }
169
170 /* Return the function status */
171 return status;
172 }
173
174 /**
175 * @brief Get the RNG Configuration and fill parameters in the
176 * RNG_ConfigTypeDef.
177 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
178 * the configuration information for RNG.
179 * @param pConf pointer to a RNG_ConfigTypeDef structure that contains
180 * the configuration information for RNG module
181
182 * @retval HAL status
183 */
HAL_RNGEx_GetConfig(RNG_HandleTypeDef * hrng,RNG_ConfigTypeDef * pConf)184 HAL_StatusTypeDef HAL_RNGEx_GetConfig(RNG_HandleTypeDef *hrng, RNG_ConfigTypeDef *pConf)
185 {
186
187 HAL_StatusTypeDef status ;
188
189 /* Check the RNG handle allocation */
190 if ((hrng == NULL) || (pConf == NULL))
191 {
192 return HAL_ERROR;
193 }
194
195 /* Check RNG peripheral state */
196 if (hrng->State == HAL_RNG_STATE_READY)
197 {
198 /* Change RNG peripheral state */
199 hrng->State = HAL_RNG_STATE_BUSY;
200
201 /* Get RNG parameters */
202 pConf->Config1 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG1) >> RNG_CR_RNG_CONFIG1_Pos) ;
203 pConf->Config2 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG2) >> RNG_CR_RNG_CONFIG2_Pos);
204 pConf->Config3 = (uint32_t)((hrng->Instance->CR & RNG_CR_RNG_CONFIG3) >> RNG_CR_RNG_CONFIG3_Pos);
205 pConf->ClockDivider = (hrng->Instance->CR & RNG_CR_CLKDIV);
206 pConf->NistCompliance = (hrng->Instance->CR & RNG_CR_NISTC);
207 pConf->AutoReset = (hrng->Instance->CR & RNG_CR_ARDIS);
208 pConf->HealthTest = (hrng->Instance->HTCR);
209
210 /* Initialize the RNG state */
211 hrng->State = HAL_RNG_STATE_READY;
212
213 /* function status */
214 status = HAL_OK;
215 }
216 else
217 {
218 hrng->ErrorCode |= HAL_RNG_ERROR_BUSY;
219 status = HAL_ERROR;
220 }
221
222 /* Return the function status */
223 return status;
224 }
225
226 /**
227 * @brief RNG current configuration lock.
228 * @note This function allows to lock RNG peripheral configuration.
229 * Once locked, HW RNG reset has to be performed prior any further
230 * configuration update.
231 * @param hrng pointer to a RNG_HandleTypeDef structure that contains
232 * the configuration information for RNG.
233 * @retval HAL status
234 */
HAL_RNGEx_LockConfig(RNG_HandleTypeDef * hrng)235 HAL_StatusTypeDef HAL_RNGEx_LockConfig(RNG_HandleTypeDef *hrng)
236 {
237 HAL_StatusTypeDef status;
238
239 /* Check the RNG handle allocation */
240 if (hrng == NULL)
241 {
242 return HAL_ERROR;
243 }
244
245 /* Check RNG peripheral state */
246 if (hrng->State == HAL_RNG_STATE_READY)
247 {
248 /* Change RNG peripheral state */
249 hrng->State = HAL_RNG_STATE_BUSY;
250
251 /* Perform RNG configuration Lock */
252 MODIFY_REG(hrng->Instance->CR, RNG_CR_CONFIGLOCK, RNG_CR_CONFIGLOCK);
253
254 /* Change RNG peripheral state */
255 hrng->State = HAL_RNG_STATE_READY;
256
257 /* function status */
258 status = HAL_OK;
259 }
260 else
261 {
262 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
263 status = HAL_ERROR;
264 }
265
266 /* Return the function status */
267 return status;
268 }
269
270
271 /**
272 * @}
273 */
274
275 /** @defgroup RNGEx_Exported_Functions_Group2 Recover from seed error function
276 * @brief Recover from seed error function
277 *
278 @verbatim
279 ===============================================================================
280 ##### Recover from seed error function #####
281 ===============================================================================
282 [..] This section provide function allowing to:
283 (+) Recover from a seed error
284
285 @endverbatim
286 * @{
287 */
288
289 /**
290 * @brief RNG sequence to recover from a seed error
291 * @param hrng: pointer to a RNG_HandleTypeDef structure.
292 * @retval HAL status
293 */
HAL_RNGEx_RecoverSeedError(RNG_HandleTypeDef * hrng)294 HAL_StatusTypeDef HAL_RNGEx_RecoverSeedError(RNG_HandleTypeDef *hrng)
295 {
296 HAL_StatusTypeDef status;
297
298 /* Check the RNG handle allocation */
299 if (hrng == NULL)
300 {
301 return HAL_ERROR;
302 }
303
304 /* Check RNG peripheral state */
305 if (hrng->State == HAL_RNG_STATE_READY)
306 {
307 /* Change RNG peripheral state */
308 hrng->State = HAL_RNG_STATE_BUSY;
309
310 /* sequence to fully recover from a seed error */
311 status = RNG_RecoverSeedError(hrng);
312 if (status == HAL_ERROR)
313 {
314 /* Update the error code */
315 hrng->ErrorCode = HAL_RNG_ERROR_RECOVERSEED;
316 }
317 }
318 else
319 {
320 hrng->ErrorCode = HAL_RNG_ERROR_BUSY;
321 status = HAL_ERROR;
322 }
323
324 /* Return the function status */
325 return status;
326 }
327
328 /**
329 * @}
330 */
331
332 /**
333 * @}
334 */
335
336 #endif /* RNG_CR_CONDRST */
337 #endif /* HAL_RNG_MODULE_ENABLED */
338 /**
339 * @}
340 */
341
342 #endif /* RNG */
343
344 /**
345 * @}
346 */
347