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