atsamd_hal/peripherals/
trng.rs

1use crate::pac::{self, Mclk};
2
3use rand_core::{CryptoRng, RngCore};
4
5use crate::ehal_02::blocking::rng::Read;
6
7pub struct Trng(pac::Trng);
8
9impl Trng {
10    pub fn new(mclk: &mut Mclk, trng: pac::Trng) -> Trng {
11        mclk.apbcmask().modify(|_, w| w.trng_().set_bit());
12        trng.ctrla().modify(|_, w| w.enable().set_bit());
13        Self(trng)
14    }
15
16    pub fn random(&self, buf: &mut [u8]) {
17        for chunk in buf.chunks_mut(4) {
18            chunk.copy_from_slice(&self.random_u32().to_le_bytes()[..chunk.len()]);
19        }
20    }
21
22    pub fn random_u8(&self) -> u8 {
23        self.random_u32() as u8
24    }
25
26    pub fn random_u16(&self) -> u16 {
27        self.random_u32() as u16
28    }
29
30    pub fn random_u32(&self) -> u32 {
31        while self.0.intflag().read().datardy().bit_is_clear() {}
32        self.0.data().read().bits()
33    }
34
35    pub fn random_u64(&self) -> u64 {
36        while self.0.intflag().read().datardy().bit_is_clear() {}
37        let lower_half = self.0.data().read().bits() as u64;
38        while self.0.intflag().read().datardy().bit_is_clear() {}
39        let upper_half = self.0.data().read().bits() as u64;
40        (upper_half << 32) | lower_half
41    }
42}
43
44impl RngCore for Trng {
45    fn next_u32(&mut self) -> u32 {
46        self.random_u32()
47    }
48
49    fn next_u64(&mut self) -> u64 {
50        self.random_u64()
51    }
52
53    fn fill_bytes(&mut self, dest: &mut [u8]) {
54        self.random(dest)
55    }
56}
57
58impl CryptoRng for Trng {}
59
60impl Read for Trng {
61    type Error = ();
62    fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> {
63        self.random(buffer);
64        Ok(())
65    }
66}