1use core::ops::Deref;
7use rand_core::{CryptoRng, RngCore};
8
9use crate::target::{
10 rng,
11 RNG,
12};
13
14
15pub trait RngExt : Deref<Target=rng::RegisterBlock> + Sized {
16 fn constrain(self) -> Rng;
17}
18
19impl RngExt for RNG {
20 fn constrain(self) -> Rng {
21 self.config.write(|w| w.dercen().enabled());
22 Rng(self)
23 }
24}
25
26
27pub struct Rng(RNG);
31
32impl Rng {
33 pub fn random(&mut self, buf: &mut [u8]) {
37 self.0.tasks_start.write(|w| unsafe { w.bits(1) });
38
39 for b in buf {
40 while self.0.events_valrdy.read().bits() == 0 {}
42 self.0.events_valrdy.write(|w| unsafe { w.bits(0) });
43
44 *b = self.0.value.read().value().bits();
45 }
46
47 self.0.tasks_stop.write(|w| unsafe { w.bits(1) });
48 }
49
50 pub fn random_u8(&mut self) -> u8 {
52 let mut buf = [0; 1];
53 self.random(&mut buf);
54 buf[0]
55 }
56
57 pub fn random_u16(&mut self) -> u16 {
59 let mut buf = [0; 2];
60 self.random(&mut buf);
61 buf[0] as u16 |
62 (buf[1] as u16) << 8
63 }
64
65 pub fn random_u32(&mut self) -> u32 {
67 let mut buf = [0; 4];
68 self.random(&mut buf);
69 buf[0] as u32 |
70 (buf[1] as u32) << 8 |
71 (buf[2] as u32) << 16 |
72 (buf[3] as u32) << 24
73 }
74
75 pub fn random_u64(&mut self) -> u64 {
77 let mut buf = [0; 8];
78 self.random(&mut buf);
79 buf[0] as u64 |
80 (buf[1] as u64) << 8 |
81 (buf[2] as u64) << 16 |
82 (buf[3] as u64) << 24 |
83 (buf[4] as u64) << 32 |
84 (buf[5] as u64) << 40 |
85 (buf[6] as u64) << 48 |
86 (buf[7] as u64) << 56
87 }
88}
89
90impl RngCore for Rng {
91 fn next_u32(&mut self) -> u32 {
92 self.random_u32()
93 }
94
95 fn next_u64(&mut self) -> u64 {
96 self.random_u64()
97 }
98
99 fn fill_bytes(&mut self, dest: &mut [u8]) {
100 self.random(dest)
101 }
102
103 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
104 Ok(self.fill_bytes(dest))
105 }
106}
107
108impl CryptoRng for Rng {}