stm32f4xx_rng.c 13.7 KB
Newer Older
Damien's avatar
Damien committed
1
2
3
4
/**
  ******************************************************************************
  * @file    stm32f4xx_rng.c
  * @author  MCD Application Team
5
6
  * @version V1.3.0
  * @date    08-November-2013
Damien's avatar
Damien committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  * @brief This file provides firmware functions to manage the following 
  *          functionalities of the Random Number Generator (RNG) peripheral:           
  *           + Initialization and Configuration 
  *           + Get 32 bit Random number      
  *           + Interrupts and flags management       
  *         
@verbatim
                                 
 ===================================================================      
                 ##### How to use this driver #####
 ===================================================================          
 [..]
   (#) Enable The RNG controller clock using 
       RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE) function.
                
   (#) Activate the RNG peripheral using RNG_Cmd() function.
            
   (#) Wait until the 32 bit Random number Generator contains a valid  random data
      (using polling/interrupt mode). For more details, refer to "Interrupts and 
      flags management functions" module description.
             
   (#) Get the 32 bit Random number using RNG_GetRandomNumber() function
            
   (#) To get another 32 bit Random number, go to step 3.       
         
                
@endverbatim
  *         
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************  
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_rng.h"
#include "stm32f4xx_rcc.h"

/** @addtogroup STM32F4xx_StdPeriph_Driver
  * @{
  */

/** @defgroup RNG 
  * @brief RNG driver modules
  * @{
  */ 

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup RNG_Private_Functions
  * @{
  */ 

/** @defgroup RNG_Group1 Initialization and Configuration functions
 *  @brief    Initialization and Configuration functions 
 *
@verbatim    
 ===============================================================================
             ##### Initialization and Configuration functions #####
 ===============================================================================  
 [..] This section provides functions allowing to 
   (+) Initialize the RNG peripheral
   (+) Enable or disable the RNG peripheral
   
@endverbatim
  * @{
  */

/**
  * @brief  De-initializes the RNG peripheral registers to their default reset values.
  * @param  None
  * @retval None
  */
void RNG_DeInit(void)
{
  /* Enable RNG reset state */
  RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, ENABLE);

  /* Release RNG from reset state */
  RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, DISABLE);
}

/**
  * @brief  Enables or disables the RNG peripheral.
  * @param  NewState: new state of the RNG peripheral.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void RNG_Cmd(FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    /* Enable the RNG */
    RNG->CR |= RNG_CR_RNGEN;
  }
  else
  {
    /* Disable the RNG */
    RNG->CR &= ~RNG_CR_RNGEN;
  }
}
/**
  * @}
  */

/** @defgroup RNG_Group2 Get 32 bit Random number function
 *  @brief    Get 32 bit Random number function 
 *

@verbatim    
 ===============================================================================
                 ##### Get 32 bit Random number function #####
 ===============================================================================  
 [..] This section provides a function allowing to get the 32 bit Random number  
  
   (@)  Before to call this function you have to wait till DRDY flag is set,
        using RNG_GetFlagStatus(RNG_FLAG_DRDY) function. 
   
@endverbatim
  * @{
  */


/**
  * @brief  Returns a 32-bit random number.
  *   
  * @note   Before to call this function you have to wait till DRDY (data ready)
  *         flag is set, using RNG_GetFlagStatus(RNG_FLAG_DRDY) function.
  * @note   Each time the the Random number data is read (using RNG_GetRandomNumber()
  *         function), the RNG_FLAG_DRDY flag is automatically cleared.
  * @note   In the case of a seed error, the generation of random numbers is 
  *         interrupted for as long as the SECS bit is '1'. If a number is 
  *         available in the RNG_DR register, it must not be used because it may 
  *         not have enough entropy. In this case, it is recommended to clear the 
  *         SEIS bit(using RNG_ClearFlag(RNG_FLAG_SECS) function), then disable 
  *         and enable the RNG peripheral (using RNG_Cmd() function) to 
  *         reinitialize and restart the RNG.
  * @note   In the case of a clock error, the RNG is no more able to generate 
  *         random numbers because the PLL48CLK clock is not correct. User have 
  *         to check that the clock controller is correctly configured to provide
  *         the RNG clock and clear the CEIS bit (using RNG_ClearFlag(RNG_FLAG_CECS) 
  *         function) . The clock error has no impact on the previously generated 
  *         random numbers, and the RNG_DR register contents can be used.
  *         
  * @param  None
  * @retval 32-bit random number.
  */
uint32_t RNG_GetRandomNumber(void)
{
  /* Return the 32 bit random number from the DR register */
  return RNG->DR;
}


/**
  * @}
  */

/** @defgroup RNG_Group3 Interrupts and flags management functions
 *  @brief   Interrupts and flags management functions
 *
@verbatim   
 ===============================================================================
             ##### Interrupts and flags management functions #####
 ===============================================================================  

 [..] This section provides functions allowing to configure the RNG Interrupts and 
      to get the status and clear flags and Interrupts pending bits.
  
 [..] The RNG provides 3 Interrupts sources and 3 Flags:
  
 *** Flags : ***
 ===============
 [..] 
    (#) RNG_FLAG_DRDY :  In the case of the RNG_DR register contains valid 
        random data. it is cleared by reading the valid data(using 
        RNG_GetRandomNumber() function).

    (#) RNG_FLAG_CECS : In the case of a seed error detection. 
      
    (#) RNG_FLAG_SECS : In the case of a clock error detection.
              
 *** Interrupts ***
 ==================
 [..] If enabled, an RNG interrupt is pending :
    
   (#) In the case of the RNG_DR register contains valid random data. 
       This interrupt source is cleared once the RNG_DR register has been read 
       (using RNG_GetRandomNumber() function) until a new valid value is 
       computed; or 
   (#) In the case of a seed error : One of the following faulty sequences has 
       been detected:
       (++) More than 64 consecutive bits at the same value (0 or 1)
       (++) More than 32 consecutive alternance of 0 and 1 (0101010101...01)
       This interrupt source is cleared using RNG_ClearITPendingBit(RNG_IT_SEI)
       function; or
   (#) In the case of a clock error : the PLL48CLK (RNG peripheral clock source) 
       was not correctly detected (fPLL48CLK< fHCLK/16). This interrupt source is
       cleared using RNG_ClearITPendingBit(RNG_IT_CEI) function.
       -@- note In this case, User have to check that the clock controller is 
           correctly configured to provide the RNG clock. 

 *** Managing the RNG controller events : ***
 ============================================
 [..] The user should identify which mode will be used in his application to manage 
      the RNG controller events: Polling mode or Interrupt mode.
  
   (#) In the Polling Mode it is advised to use the following functions:
       (++) RNG_GetFlagStatus() : to check if flags events occur. 
       (++) RNG_ClearFlag()     : to clear the flags events.
  
       -@@- RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag(). it is cleared only 
            by reading the Random number data.      
  
   (#)  In the Interrupt Mode it is advised to use the following functions:
        (++) RNG_ITConfig()       : to enable or disable the interrupt source.
        (++) RNG_GetITStatus()    : to check if Interrupt occurs.
        (++) RNG_ClearITPendingBit() : to clear the Interrupt pending Bit 
             (corresponding Flag). 
  
@endverbatim
  * @{
  */ 

/**
  * @brief  Enables or disables the RNG interrupt.
  * @note   The RNG provides 3 interrupt sources,
  *           - Computed data is ready event (DRDY), and           
  *           - Seed error Interrupt (SEI) and 
  *           - Clock error Interrupt (CEI), 
  *         all these interrupts sources are enabled by setting the IE bit in 
  *         CR register. However, each interrupt have its specific status bit
  *         (see RNG_GetITStatus() function) and clear bit except the DRDY event
  *         (see RNG_ClearITPendingBit() function).
  * @param  NewState: new state of the RNG interrupt.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void RNG_ITConfig(FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    /* Enable the RNG interrupt */
    RNG->CR |= RNG_CR_IE;
  }
  else
  {
    /* Disable the RNG interrupt */
    RNG->CR &= ~RNG_CR_IE;
  }
}

/**
  * @brief  Checks whether the specified RNG flag is set or not.
  * @param  RNG_FLAG: specifies the RNG flag to check.
  *          This parameter can be one of the following values:
  *            @arg RNG_FLAG_DRDY: Data Ready flag.
  *            @arg RNG_FLAG_CECS: Clock Error Current flag.
  *            @arg RNG_FLAG_SECS: Seed Error Current flag.
  * @retval The new state of RNG_FLAG (SET or RESET).
  */
FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG)
{
  FlagStatus bitstatus = RESET;
  /* Check the parameters */
  assert_param(IS_RNG_GET_FLAG(RNG_FLAG));

  /* Check the status of the specified RNG flag */
  if ((RNG->SR & RNG_FLAG) != (uint8_t)RESET)
  {
    /* RNG_FLAG is set */
    bitstatus = SET;
  }
  else
  {
    /* RNG_FLAG is reset */
    bitstatus = RESET;
  }
  /* Return the RNG_FLAG status */
  return  bitstatus;
}


/**
  * @brief  Clears the RNG flags.
  * @param  RNG_FLAG: specifies the flag to clear. 
  *          This parameter can be any combination of the following values:
  *            @arg RNG_FLAG_CECS: Clock Error Current flag.
  *            @arg RNG_FLAG_SECS: Seed Error Current flag.
  * @note   RNG_FLAG_DRDY can not be cleared by RNG_ClearFlag() function. 
  *         This flag is cleared only by reading the Random number data (using 
  *         RNG_GetRandomNumber() function).                           
  * @retval None
  */
void RNG_ClearFlag(uint8_t RNG_FLAG)
{
  /* Check the parameters */
  assert_param(IS_RNG_CLEAR_FLAG(RNG_FLAG));
  /* Clear the selected RNG flags */
  RNG->SR = ~(uint32_t)(((uint32_t)RNG_FLAG) << 4);
}

/**
  * @brief  Checks whether the specified RNG interrupt has occurred or not.
  * @param  RNG_IT: specifies the RNG interrupt source to check.
  *          This parameter can be one of the following values:
  *            @arg RNG_IT_CEI: Clock Error Interrupt.
  *            @arg RNG_IT_SEI: Seed Error Interrupt.                   
  * @retval The new state of RNG_IT (SET or RESET).
  */
ITStatus RNG_GetITStatus(uint8_t RNG_IT)
{
  ITStatus bitstatus = RESET;
  /* Check the parameters */
  assert_param(IS_RNG_GET_IT(RNG_IT));

  /* Check the status of the specified RNG interrupt */
  if ((RNG->SR & RNG_IT) != (uint8_t)RESET)
  {
    /* RNG_IT is set */
    bitstatus = SET;
  }
  else
  {
    /* RNG_IT is reset */
    bitstatus = RESET;
  }
  /* Return the RNG_IT status */
  return bitstatus;
}


/**
  * @brief  Clears the RNG interrupt pending bit(s).
  * @param  RNG_IT: specifies the RNG interrupt pending bit(s) to clear.
  *          This parameter can be any combination of the following values:
  *            @arg RNG_IT_CEI: Clock Error Interrupt.
  *            @arg RNG_IT_SEI: Seed Error Interrupt.
  * @retval None
  */
void RNG_ClearITPendingBit(uint8_t RNG_IT)
{
  /* Check the parameters */
  assert_param(IS_RNG_IT(RNG_IT));

  /* Clear the selected RNG interrupt pending bit */
  RNG->SR = (uint8_t)~RNG_IT;
}
/**
  * @}
  */ 
  
/**
  * @}
  */ 

/**
  * @}
  */ 

/**
  * @}
  */ 


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/