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>&copy; 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