1 /******************************************************************************
2 * Filename: trng.h
3 * Revised: 2015-11-16 19:41:47 +0100 (Mon, 16 Nov 2015)
4 * Revision: 45094
5 *
6 * Description: Defines and prototypes for the true random number gen.
7 *
8 * Copyright (c) 2015, Texas Instruments Incorporated
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * 1) Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 *
17 * 2) Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
22 * be used to endorse or promote products derived from this software without
23 * specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 ******************************************************************************/
38
39 //*****************************************************************************
40 //
41 //! \addtogroup peripheral_group
42 //! @{
43 //! \addtogroup trng_api
44 //! @{
45 //
46 //*****************************************************************************
47
48 #ifndef __TRNG_H__
49 #define __TRNG_H__
50
51 //*****************************************************************************
52 //
53 // If building with a C++ compiler, make all of the definitions in this header
54 // have a C binding.
55 //
56 //*****************************************************************************
57 #ifdef __cplusplus
58 extern "C"
59 {
60 #endif
61
62 #include <stdbool.h>
63 #include <stdint.h>
64 #include <inc/hw_types.h>
65 #include <inc/hw_trng.h>
66 #include <inc/hw_memmap.h>
67 #include <inc/hw_ints.h>
68 #include <driverlib/debug.h>
69 #include <driverlib/interrupt.h>
70 #include <driverlib/cpu.h>
71
72 //*****************************************************************************
73 //
74 // Support for DriverLib in ROM:
75 // This section renames all functions that are not "static inline", so that
76 // calling these functions will default to implementation in flash. At the end
77 // of this file a second renaming will change the defaults to implementation in
78 // ROM for available functions.
79 //
80 // To force use of the implementation in flash, e.g. for debugging:
81 // - Globally: Define DRIVERLIB_NOROM at project level
82 // - Per function: Use prefix "NOROM_" when calling the function
83 //
84 //*****************************************************************************
85 #if !defined(DOXYGEN)
86 #define TRNGConfigure NOROM_TRNGConfigure
87 #define TRNGNumberGet NOROM_TRNGNumberGet
88 #endif
89
90 //*****************************************************************************
91 //
92 //
93 //
94 //*****************************************************************************
95 #define TRNG_NUMBER_READY 0x00000001 //
96 #define TRNG_FRO_SHUTDOWN 0x00000002 //
97 #define TRNG_NEED_CLOCK 0x80000000 //
98
99 #define TRNG_HI_WORD 0x00000001
100 #define TRNG_LOW_WORD 0x00000002
101
102 //*****************************************************************************
103 //
104 // API Function and prototypes
105 //
106 //*****************************************************************************
107
108 //*****************************************************************************
109 //
110 //! \brief Configure the true random number generator.
111 //!
112 //! Use this function to set the minimum and maximum number of samples required
113 //! in each generation of a new random number.
114 //!
115 //! \param ui32MinSamplesPerCycle is the minimum number of samples per each
116 //! generated random number. Constraints:
117 //! - Value must be bigger than or equal to 2^6 and less than 2^14.
118 //! - The 6 LSBs of the argument are truncated.
119 //! - If the value is zero, the number of samples is fixed to the value determined
120 //! by ui32MaxSamplesPerCycle. To ensure same entropy in all generated random
121 //! numbers the value 0 should be used.
122 //! \param ui32MaxSamplesPerCycle is the maximum number of samples per each
123 //! generated random number. Constraints:
124 //! - Value must be between 2^8 and 2^24 (both included).
125 //! - The 8 LSBs of the argument are truncated.
126 //! - Value 0 and 2^24 both give the highest possible value.
127 //! \param ui32ClocksPerSample is the number of clock cycles for each time
128 //! a new sample is generated from the FROs.
129 //! - 0 : Every sample.
130 //! - 1 : Every second sample.
131 //! - ...
132 //! - 15 : Every 16. sample.
133 //!
134 //! \return None
135 //
136 //*****************************************************************************
137 extern void TRNGConfigure(uint32_t ui32MinSamplesPerCycle,
138 uint32_t ui32MaxSamplesPerCycle,
139 uint32_t ui32ClocksPerSample);
140
141 //*****************************************************************************
142 //
143 //! \brief Enable the TRNG.
144 //!
145 //! Enable the TRNG to start preparing a random number.
146 //!
147 //! \return None
148 //
149 //*****************************************************************************
150 __STATIC_INLINE void
TRNGEnable(void)151 TRNGEnable(void)
152 {
153 // Enable the TRNG.
154 HWREGBITW(TRNG_BASE + TRNG_O_CTL, TRNG_CTL_TRNG_EN_BITN) = 1;
155 }
156
157 //*****************************************************************************
158 //
159 //! \brief Disable the TRNG module.
160 //!
161 //! \return None
162 //
163 //*****************************************************************************
164 __STATIC_INLINE void
TRNGDisable(void)165 TRNGDisable(void)
166 {
167 // Enable the TRNG
168 HWREGBITW(TRNG_BASE + TRNG_O_CTL, TRNG_CTL_TRNG_EN_BITN) = 0;
169 }
170
171 //*****************************************************************************
172 //
173 //! \brief Get a random number from the generator.
174 //!
175 //! Use this function to get either the high or low part of the 64 bit
176 //! generated number.
177 //!
178 //! \note Data from this register is only valid if the TRNG has produced a
179 //! number. Use \ref TRNGStatusGet() to poll the for status. After calling this
180 //! function a new random number will be generated.
181 //!
182 //! \param ui32Word determines if whether to return the high or low 32 bits.
183 //! - \ref TRNG_HI_WORD
184 //! - \ref TRNG_LOW_WORD
185 //!
186 //! \return Return either the high or low part of the 64 bit generated random
187 //! number.
188 //
189 //*****************************************************************************
190 extern uint32_t TRNGNumberGet(uint32_t ui32Word);
191
192 //*****************************************************************************
193 //
194 //! \brief Get the status of the TRNG.
195 //!
196 //! Use this function to retrieve the status of the TRNG.
197 //!
198 //! \return Returns the current status of the TRNG module.
199 //! The returned status is a bitwise OR'ed combination of:
200 //! - \ref TRNG_NUMBER_READY
201 //! - \ref TRNG_FRO_SHUTDOWN
202 //! - \ref TRNG_NEED_CLOCK
203 //
204 //*****************************************************************************
205 __STATIC_INLINE uint32_t
TRNGStatusGet(void)206 TRNGStatusGet(void)
207 {
208 //
209 // Return the status.
210 //
211 return (HWREG(TRNG_BASE + TRNG_O_IRQFLAGSTAT));
212 }
213
214 //*****************************************************************************
215 //
216 //! \brief Reset the TRNG.
217 //!
218 //! Use this function to reset the TRNG module. Reset will be low for
219 //! approximately 5 clock cycles.
220 //!
221 //! \return None
222 //
223 //*****************************************************************************
224 __STATIC_INLINE void
TRNGReset(void)225 TRNGReset(void)
226 {
227 //
228 // Reset the TRNG.
229 //
230 HWREG(TRNG_BASE + TRNG_O_SWRESET) = 1;
231 }
232
233 //*****************************************************************************
234 //
235 //! \brief Enables individual TRNG interrupt sources.
236 //!
237 //! This function enables the indicated TRNG interrupt sources. Only the
238 //! sources that are enabled can be reflected to the processor interrupt;
239 //! disabled sources have no effect on the processor.
240 //!
241 //! \param ui32IntFlags is the bit mask of the interrupt sources to be enabled.
242 //! The parameter is the bitwise OR of any of the following:
243 //! - \ref TRNG_NUMBER_READY
244 //! - \ref TRNG_FRO_SHUTDOWN
245 //!
246 //! \return None
247 //
248 //*****************************************************************************
249 __STATIC_INLINE void
TRNGIntEnable(uint32_t ui32IntFlags)250 TRNGIntEnable(uint32_t ui32IntFlags)
251 {
252 //
253 // Check the arguments.
254 //
255 ASSERT((ui32IntFlags & TRNG_NUMBER_READY) ||
256 (ui32IntFlags & TRNG_FRO_SHUTDOWN));
257
258 //
259 // Enable the specified interrupts.
260 //
261 HWREG(TRNG_BASE + TRNG_O_IRQFLAGMASK) |= ui32IntFlags;
262 }
263
264 //*****************************************************************************
265 //
266 //! \brief Disables individual TRNG interrupt sources.
267 //!
268 //! This function disables the indicated TRNG interrupt sources. Only the
269 //! sources that are enabled can be reflected to the processor interrupt;
270 //! disabled sources have no effect on the processor.
271 //!
272 //! \param ui32IntFlags is the bit mask of the interrupt sources to be disabled.
273 //! The parameter is the bitwise OR of any of the following:
274 //! - \ref TRNG_NUMBER_READY
275 //! - \ref TRNG_FRO_SHUTDOWN
276 //!
277 //! \return None
278 //
279 //*****************************************************************************
280 __STATIC_INLINE void
TRNGIntDisable(uint32_t ui32IntFlags)281 TRNGIntDisable(uint32_t ui32IntFlags)
282 {
283 //
284 // Check the arguments.
285 //
286 ASSERT((ui32IntFlags & TRNG_NUMBER_READY) ||
287 (ui32IntFlags & TRNG_FRO_SHUTDOWN));
288
289 //
290 // Disable the specified interrupts.
291 //
292 HWREG(TRNG_BASE + TRNG_O_IRQFLAGMASK) &= ~ui32IntFlags;
293 }
294
295 //*****************************************************************************
296 //
297 //! \brief Gets the current interrupt status of the TRNG module.
298 //!
299 //! This function returns the interrupt status for the specified TRNG. Either
300 //! the raw interrupt status or the status of interrupts that are allowed to
301 //! reflect to the processor can be returned.
302 //!
303 //! \param bMasked selects either raw or masked interrupt status.
304 //! - \c true : Masked interrupt.
305 //! - \c false : Raw interrupt.
306 //!
307 //! \return Returns the current interrupt status, enumerated as:
308 //! - \ref TRNG_NUMBER_READY
309 //! - \ref TRNG_FRO_SHUTDOWN
310 //
311 //*****************************************************************************
312 __STATIC_INLINE uint32_t
TRNGIntStatus(bool bMasked)313 TRNGIntStatus(bool bMasked)
314 {
315 uint32_t ui32Mask;
316
317 //
318 // Return either the interrupt status or the raw interrupt status as
319 // requested.
320 //
321 if(bMasked)
322 {
323 ui32Mask = HWREG(TRNG_BASE + TRNG_O_IRQFLAGMASK);
324 return(ui32Mask & HWREG(TRNG_BASE + TRNG_O_IRQFLAGSTAT));
325 }
326 else
327 {
328 return(HWREG(TRNG_BASE + TRNG_O_IRQFLAGSTAT) & 0x00000003);
329 }
330 }
331
332 //*****************************************************************************
333 //
334 //! \brief Clears TRNG interrupt sources.
335 //!
336 //! The specified TRNG interrupt sources are cleared, so that they no longer
337 //! assert. This function must be called in the interrupt handler to keep the
338 //! interrupt from being recognized again immediately upon exit.
339 //!
340 //! \note Due to write buffers and synchronizers in the system it may take several
341 //! clock cycles from a register write clearing an event in a module and until the
342 //! event is actually cleared in the NVIC of the system CPU. It is recommended to
343 //! clear the event source early in the interrupt service routine (ISR) to allow
344 //! the event clear to propagate to the NVIC before returning from the ISR.
345 //! At the same time, an early event clear allows new events of the same type to be
346 //! pended instead of ignored if the event is cleared later in the ISR.
347 //! It is the responsibility of the programmer to make sure that enough time has passed
348 //! before returning from the ISR to avoid false re-triggering of the cleared event.
349 //! A simple, although not necessarily optimal, way of clearing an event before
350 //! returning from the ISR is:
351 //! -# Write to clear event (interrupt source). (buffered write)
352 //! -# Dummy read from the event source module. (making sure the write has propagated)
353 //! -# Wait two system CPU clock cycles (user code or two NOPs). (allowing cleared event to propagate through any synchronizers)
354 //!
355 //! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared.
356 //! The parameter is the bitwise OR of any of the following:
357 //! - \ref TRNG_NUMBER_READY
358 //! - \ref TRNG_FRO_SHUTDOWN
359 //!
360 //! \return None
361 //
362 //*****************************************************************************
363 __STATIC_INLINE void
TRNGIntClear(uint32_t ui32IntFlags)364 TRNGIntClear(uint32_t ui32IntFlags)
365 {
366 //
367 // Check the arguments.
368 //
369 ASSERT((ui32IntFlags & TRNG_NUMBER_READY) ||
370 (ui32IntFlags & TRNG_FRO_SHUTDOWN));
371
372 //
373 // Clear the requested interrupt sources.
374 //
375 HWREG(TRNG_BASE + TRNG_O_IRQFLAGCLR) = ui32IntFlags;
376 }
377
378 //*****************************************************************************
379 //
380 //! \brief Registers an interrupt handler for a TRNG interrupt.
381 //!
382 //! This function does the actual registering of the interrupt handler. This
383 //! function enables the global interrupt in the interrupt controller; specific
384 //! UART interrupts must be enabled via \ref TRNGIntEnable(). It is the interrupt
385 //! handler's responsibility to clear the interrupt source.
386 //!
387 //! \param pfnHandler is a pointer to the function to be called when the
388 //! UART interrupt occurs.
389 //!
390 //! \return None
391 //!
392 //! \sa \ref IntRegister() for important information about registering interrupt
393 //! handlers.
394 //
395 //*****************************************************************************
396 __STATIC_INLINE void
TRNGIntRegister(void (* pfnHandler)(void))397 TRNGIntRegister(void (*pfnHandler)(void))
398 {
399 //
400 // Register the interrupt handler.
401 //
402 IntRegister(INT_TRNG_IRQ, pfnHandler);
403
404 //
405 // Enable the TRNG interrupt.
406 //
407 IntEnable(INT_TRNG_IRQ);
408 }
409
410 //*****************************************************************************
411 //
412 //! \brief Unregisters an interrupt handler for a TRNG interrupt.
413 //!
414 //! This function does the actual unregistering of the interrupt handler. It
415 //! clears the handler to be called when a Crypto interrupt occurs. This
416 //! function also masks off the interrupt in the interrupt controller so that
417 //! the interrupt handler no longer is called.
418 //!
419 //! \return None
420 //!
421 //! \sa \ref IntRegister() for important information about registering interrupt
422 //! handlers.
423 //
424 //*****************************************************************************
425 __STATIC_INLINE void
TRNGIntUnregister(void)426 TRNGIntUnregister(void)
427 {
428 //
429 // Disable the interrupt.
430 //
431 IntDisable(INT_TRNG_IRQ);
432
433 //
434 // Unregister the interrupt handler.
435 //
436 IntUnregister(INT_TRNG_IRQ);
437 }
438
439 //*****************************************************************************
440 //
441 // Support for DriverLib in ROM:
442 // Redirect to implementation in ROM when available.
443 //
444 //*****************************************************************************
445 #if !defined(DRIVERLIB_NOROM) && !defined(DOXYGEN)
446 #include <driverlib/rom.h>
447 #ifdef ROM_TRNGConfigure
448 #undef TRNGConfigure
449 #define TRNGConfigure ROM_TRNGConfigure
450 #endif
451 #ifdef ROM_TRNGNumberGet
452 #undef TRNGNumberGet
453 #define TRNGNumberGet ROM_TRNGNumberGet
454 #endif
455 #endif
456
457 //*****************************************************************************
458 //
459 // Mark the end of the C bindings section for C++ compilers.
460 //
461 //*****************************************************************************
462 #ifdef __cplusplus
463 }
464 #endif
465
466 #endif // __TRNG_H__
467
468 //*****************************************************************************
469 //
470 //! Close the Doxygen group.
471 //! @}
472 //! @}
473 //
474 //*****************************************************************************
475