lpc55s6x_hal/peripherals/rng.rs
1use crate::{
2 raw,
3 peripherals::{
4 syscon::Syscon,
5 },
6 typestates::{
7 init_state,
8 }
9};
10
11crate::wrap_stateful_peripheral!(Rng, RNG);
12
13// /// HAL-ified RNG peripheral
14// pub struct Rng<State = init_state::Enabled> {
15// raw: raw::RNG,
16// _state: State,
17// }
18
19#[derive(Debug)]
20// not sure why this kind of thing is not in `svd2rust`?
21pub struct ModuleId {
22 id: u16,
23 maj_rev: u8,
24 min_rev: u8,
25 aperture: u8,
26}
27
28impl Rng {
29}
30
31impl<State> Rng<State> {
32 pub fn enabled(mut self, syscon: &mut Syscon) -> Rng<init_state::Enabled> {
33 syscon.enable_clock(&mut self.raw);
34
35 Rng {
36 raw: self.raw,
37 _state: init_state::Enabled(()),
38 }
39 }
40
41 pub fn disabled(mut self, syscon: &mut Syscon) -> Rng<init_state::Disabled> {
42 syscon.disable_clock(&mut self.raw);
43
44 Rng {
45 raw: self.raw,
46 _state: init_state::Disabled,
47 }
48 }
49
50}
51
52impl Rng<init_state::Enabled> {
53 /// DO NOT CALL - doesn't work yet
54 #[allow(dead_code, unreachable_code)]
55 fn initialize_entropy(&self) {
56 unimplemented!();
57
58 // NB: there are functional and operational differences between
59 // the A0 and A1 versions of the chip, see UM 48.14 (page 1033)
60 //
61 // A0/A1 refer to syscon.dieid.rev
62 //
63 // Here, we assume A1 (as maj.min = 3.2 seems to indicate this)
64 // TODO: check this is true for the lpcxpresso55s69
65 // TODO: check again when going into production
66
67 // poll ONLINE_TEST_VAL
68 let val = &self.raw.online_test_val.read();
69 #[allow(non_snake_case)]
70 let REF_CHI_SQUARED = 2;
71
72 // dbg!("shift4x is", self.raw.counter_cfg.read().shift4x().bits());
73 // let _: u8 = self.raw.counter_cfg.read().shift4x().bits();
74
75 loop {
76 // activate CHI computing
77 // dbg!(self.raw.online_test_cfg.read().activate().bit()); // <-- false
78 self.raw
79 .online_test_cfg
80 .modify(|_, w| unsafe { w.data_sel().bits(4) });
81 self.raw
82 .online_test_cfg
83 .modify(|_, w| w.activate().set_bit());
84 // dbg!(self.raw.online_test_cfg.read().activate().bit()); // <-- true
85
86 // dbg!(val.min_chi_squared().bits()); // <-- 15
87 // dbg!(val.max_chi_squared().bits()); // <-- 0
88
89 // TODO: this gets stuck
90 // unimplemented!("figure out how to make this not block");
91 while val.min_chi_squared().bits() > val.max_chi_squared().bits() {}
92
93 // dbg!("passed");
94
95 if val.max_chi_squared().bits() > REF_CHI_SQUARED {
96 // reset
97 self.raw
98 .online_test_cfg
99 .modify(|_, w| w.activate().clear_bit());
100 // increment SHIFT4X, which has bit width 3
101 // self.raw.counter_cfg.modify(|_, w| (w.shift4x().bits() as u8) + 1);
102 continue;
103 } else {
104 break;
105 }
106 }
107 }
108
109 pub fn get_random_u32(&self) -> u32 {
110 for _ in 0..32 {
111 while self.raw.counter_val.read().refresh_cnt() == 0 {
112 // dbg!("was not zero");
113 }
114 }
115 self.raw.random_number.read().bits()
116 }
117
118 /// random method to get some information about the RNG
119 pub fn module_id(&self) -> ModuleId {
120 ModuleId {
121 id: self.raw.moduleid.read().id().bits(),
122 maj_rev: self.raw.moduleid.read().maj_rev().bits(),
123 min_rev: self.raw.moduleid.read().min_rev().bits(),
124 aperture: self.raw.moduleid.read().aperture().bits(),
125 }
126 }
127}
128