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