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