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