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