1 /******************************************************************************
2 * Filename: trng.h
3 * Revised: 2017-05-23 12:08:52 +0200 (Tue, 23 May 2017)
4 * Revision: 49048
5 *
6 * Description: Defines and prototypes for the true random number gen.
7 *
8 * Copyright (c) 2015 - 2017, 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 "debug.h"
69 #include "interrupt.h"
70 #include "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 // Return the status.
209 return (HWREG(TRNG_BASE + TRNG_O_IRQFLAGSTAT));
210 }
211
212 //*****************************************************************************
213 //
214 //! \brief Reset the TRNG.
215 //!
216 //! Use this function to reset the TRNG module. Reset will be low for
217 //! approximately 5 clock cycles.
218 //!
219 //! \return None
220 //
221 //*****************************************************************************
222 __STATIC_INLINE void
TRNGReset(void)223 TRNGReset(void)
224 {
225 // Reset the TRNG.
226 HWREG(TRNG_BASE + TRNG_O_SWRESET) = 1;
227 }
228
229 //*****************************************************************************
230 //
231 //! \brief Enables individual TRNG interrupt sources.
232 //!
233 //! This function enables the indicated TRNG interrupt sources. Only the
234 //! sources that are enabled can be reflected to the processor interrupt;
235 //! disabled sources have no effect on the processor.
236 //!
237 //! \param ui32IntFlags is the bit mask of the interrupt sources to be enabled.
238 //! The parameter is the bitwise OR of any of the following:
239 //! - \ref TRNG_NUMBER_READY
240 //! - \ref TRNG_FRO_SHUTDOWN
241 //!
242 //! \return None
243 //
244 //*****************************************************************************
245 __STATIC_INLINE void
TRNGIntEnable(uint32_t ui32IntFlags)246 TRNGIntEnable(uint32_t ui32IntFlags)
247 {
248 // Check the arguments.
249 ASSERT((ui32IntFlags & TRNG_NUMBER_READY) ||
250 (ui32IntFlags & TRNG_FRO_SHUTDOWN));
251
252 // Enable the specified interrupts.
253 HWREG(TRNG_BASE + TRNG_O_IRQFLAGMASK) |= ui32IntFlags;
254 }
255
256 //*****************************************************************************
257 //
258 //! \brief Disables individual TRNG interrupt sources.
259 //!
260 //! This function disables the indicated TRNG interrupt sources. Only the
261 //! sources that are enabled can be reflected to the processor interrupt;
262 //! disabled sources have no effect on the processor.
263 //!
264 //! \param ui32IntFlags is the bit mask of the interrupt sources to be disabled.
265 //! The parameter is the bitwise OR of any of the following:
266 //! - \ref TRNG_NUMBER_READY
267 //! - \ref TRNG_FRO_SHUTDOWN
268 //!
269 //! \return None
270 //
271 //*****************************************************************************
272 __STATIC_INLINE void
TRNGIntDisable(uint32_t ui32IntFlags)273 TRNGIntDisable(uint32_t ui32IntFlags)
274 {
275 // Check the arguments.
276 ASSERT((ui32IntFlags & TRNG_NUMBER_READY) ||
277 (ui32IntFlags & TRNG_FRO_SHUTDOWN));
278
279 // Disable the specified interrupts.
280 HWREG(TRNG_BASE + TRNG_O_IRQFLAGMASK) &= ~ui32IntFlags;
281 }
282
283 //*****************************************************************************
284 //
285 //! \brief Gets the current interrupt status of the TRNG module.
286 //!
287 //! This function returns the interrupt status for the specified TRNG. Either
288 //! the raw interrupt status or the status of interrupts that are allowed to
289 //! reflect to the processor can be returned.
290 //!
291 //! \param bMasked selects either raw or masked interrupt status.
292 //! - \c true : Masked interrupt.
293 //! - \c false : Raw interrupt.
294 //!
295 //! \return Returns the current interrupt status, enumerated as:
296 //! - \ref TRNG_NUMBER_READY
297 //! - \ref TRNG_FRO_SHUTDOWN
298 //
299 //*****************************************************************************
300 __STATIC_INLINE uint32_t
TRNGIntStatus(bool bMasked)301 TRNGIntStatus(bool bMasked)
302 {
303 uint32_t ui32Mask;
304
305 // Return either the interrupt status or the raw interrupt status as
306 // requested.
307 if(bMasked)
308 {
309 ui32Mask = HWREG(TRNG_BASE + TRNG_O_IRQFLAGMASK);
310 return(ui32Mask & HWREG(TRNG_BASE + TRNG_O_IRQFLAGSTAT));
311 }
312 else
313 {
314 return(HWREG(TRNG_BASE + TRNG_O_IRQFLAGSTAT) & 0x00000003);
315 }
316 }
317
318 //*****************************************************************************
319 //
320 //! \brief Clears TRNG interrupt sources.
321 //!
322 //! The specified TRNG interrupt sources are cleared, so that they no longer
323 //! assert. This function must be called in the interrupt handler to keep the
324 //! interrupt from being recognized again immediately upon exit.
325 //!
326 //! \note Due to write buffers and synchronizers in the system it may take several
327 //! clock cycles from a register write clearing an event in a module and until the
328 //! event is actually cleared in the NVIC of the system CPU. It is recommended to
329 //! clear the event source early in the interrupt service routine (ISR) to allow
330 //! the event clear to propagate to the NVIC before returning from the ISR.
331 //! At the same time, an early event clear allows new events of the same type to be
332 //! pended instead of ignored if the event is cleared later in the ISR.
333 //! It is the responsibility of the programmer to make sure that enough time has passed
334 //! before returning from the ISR to avoid false re-triggering of the cleared event.
335 //! A simple, although not necessarily optimal, way of clearing an event before
336 //! returning from the ISR is:
337 //! -# Write to clear event (interrupt source). (buffered write)
338 //! -# Dummy read from the event source module. (making sure the write has propagated)
339 //! -# Wait two system CPU clock cycles (user code or two NOPs). (allowing cleared event to propagate through any synchronizers)
340 //!
341 //! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared.
342 //! The parameter is the bitwise OR of any of the following:
343 //! - \ref TRNG_NUMBER_READY
344 //! - \ref TRNG_FRO_SHUTDOWN
345 //!
346 //! \return None
347 //
348 //*****************************************************************************
349 __STATIC_INLINE void
TRNGIntClear(uint32_t ui32IntFlags)350 TRNGIntClear(uint32_t ui32IntFlags)
351 {
352 // Check the arguments.
353 ASSERT((ui32IntFlags & TRNG_NUMBER_READY) ||
354 (ui32IntFlags & TRNG_FRO_SHUTDOWN));
355
356 // Clear the requested interrupt sources.
357 HWREG(TRNG_BASE + TRNG_O_IRQFLAGCLR) = ui32IntFlags;
358 }
359
360 //*****************************************************************************
361 //
362 //! \brief Registers an interrupt handler for a TRNG interrupt in the dynamic interrupt table.
363 //!
364 //! \note Only use this function if you want to use the dynamic vector table (in SRAM)!
365 //!
366 //! This function registers a function as the interrupt handler for a specific
367 //! interrupt and enables the corresponding interrupt in the interrupt controller.
368 //!
369 //! Specific TRNG interrupts must be enabled via \ref TRNGIntEnable(). It is the interrupt
370 //! handler's responsibility to clear the interrupt source.
371 //!
372 //! \param pfnHandler is a pointer to the function to be called when the
373 //! TRNG interrupt occurs.
374 //!
375 //! \return None
376 //!
377 //! \sa \ref IntRegister() for important information about registering interrupt
378 //! handlers.
379 //
380 //*****************************************************************************
381 __STATIC_INLINE void
TRNGIntRegister(void (* pfnHandler)(void))382 TRNGIntRegister(void (*pfnHandler)(void))
383 {
384 // Register the interrupt handler.
385 IntRegister(INT_TRNG_IRQ, pfnHandler);
386
387 // Enable the TRNG interrupt.
388 IntEnable(INT_TRNG_IRQ);
389 }
390
391 //*****************************************************************************
392 //
393 //! \brief Unregisters an interrupt handler for a TRNG interrupt in the dynamic interrupt table.
394 //!
395 //! This function does the actual unregistering of the interrupt handler. It
396 //! clears the handler to be called when a Crypto interrupt occurs. This
397 //! function also masks off the interrupt in the interrupt controller so that
398 //! the interrupt handler no longer is called.
399 //!
400 //! \return None
401 //!
402 //! \sa \ref IntRegister() for important information about registering interrupt
403 //! handlers.
404 //
405 //*****************************************************************************
406 __STATIC_INLINE void
TRNGIntUnregister(void)407 TRNGIntUnregister(void)
408 {
409 // Disable the interrupt.
410 IntDisable(INT_TRNG_IRQ);
411
412 // Unregister the interrupt handler.
413 IntUnregister(INT_TRNG_IRQ);
414 }
415
416 //*****************************************************************************
417 //
418 // Support for DriverLib in ROM:
419 // Redirect to implementation in ROM when available.
420 //
421 //*****************************************************************************
422 #if !defined(DRIVERLIB_NOROM) && !defined(DOXYGEN)
423 #include "../driverlib/rom.h"
424 #ifdef ROM_TRNGConfigure
425 #undef TRNGConfigure
426 #define TRNGConfigure ROM_TRNGConfigure
427 #endif
428 #ifdef ROM_TRNGNumberGet
429 #undef TRNGNumberGet
430 #define TRNGNumberGet ROM_TRNGNumberGet
431 #endif
432 #endif
433
434 //*****************************************************************************
435 //
436 // Mark the end of the C bindings section for C++ compilers.
437 //
438 //*****************************************************************************
439 #ifdef __cplusplus
440 }
441 #endif
442
443 #endif // __TRNG_H__
444
445 //*****************************************************************************
446 //
447 //! Close the Doxygen group.
448 //! @}
449 //! @}
450 //
451 //*****************************************************************************
452