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