-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtrng.rs
86 lines (78 loc) · 2.37 KB
/
trng.rs
1
2
3
4
5
6
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
//! # True Random Number Generator (TRNG)
//!
//! The TRNG is a hardware module that generates random numbers using
//! physical entropy sources.
use rand::Error;
#[cfg(feature = "rand")]
use rand::RngCore;
#[cfg(feature = "rand")]
use rand_core::impls::{fill_bytes_via_next, next_u64_via_u32};
/// # True Random Number Generator (TRNG) Peripheral
///
/// Example:
/// ```
/// // Create a new TRNG peripheral instance
/// let trng = Trng::new(p.trng, &mut gcr.reg);
/// // Generate a random 32-bit number
/// let random_u32 = trng.gen_u32();
/// ```
pub struct Trng {
trng: crate::pac::Trng,
}
impl Trng {
/// Create a new TRNG peripheral instance.
pub fn new(trng: crate::pac::Trng, reg: &mut crate::gcr::GcrRegisters) -> Self {
use crate::gcr::ClockForPeripheral;
unsafe { trng.enable_clock(&mut reg.gcr); }
Self { trng }
}
/// Check if the TRNG peripheral is ready to generate random numbers.
#[doc(hidden)]
#[inline(always)]
fn _is_ready(&self) -> bool {
self.trng.status().read().rdy().is_ready()
}
/// Generate a random 32-bit number.
#[inline(always)]
pub fn gen_u32(&self) -> u32 {
while !self._is_ready() {}
self.trng.data().read().bits() as u32
}
}
/// Enhanced functionality for the TRNG peripheral using the [`rand`] crate.
/// This trait implementation can be disabled by removing the `rand` feature
/// flag since you may want to implement your own [`RngCore`].
///
/// Example:
/// ```
/// // Create a new TRNG peripheral instance
/// let trng = Trng::new(p.trng, &mut gcr.reg);
/// // Generate a random 32-bit number
/// let random_u32 = trng.next_u32(); // Equivalent to trng.gen_u32()
/// // Generate a random 64-bit number
/// let random_u64 = trng.next_u64();
/// // Fill a buffer with random bytes
/// let mut buffer = [0u8; 16];
/// trng.fill_bytes(&mut buffer);
/// ```
#[doc(cfg(feature = "rand"))]
#[cfg(feature = "rand")]
impl RngCore for Trng {
#[inline(always)]
fn next_u32(&mut self) -> u32 {
self.gen_u32()
}
#[inline(always)]
fn next_u64(&mut self) -> u64 {
next_u64_via_u32(self)
}
#[inline(always)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
fill_bytes_via_next(self, dest);
}
#[inline(always)]
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
self.fill_bytes(dest);
Ok(())
}
}