use crate::delay::delay_ms;
use crate::hal::pin::Pins;
use crate::sensors::*;
use bit_field::BitField;
#[derive(Clone, Copy)]
pub enum Generator {
Analog,
Mpu,
}
#[repr(C, packed)]
pub struct RandomNumberGenerator {
pins: Pins,
mpu: &'static mut MPU6050<'static>,
mode: Generator,
}
impl RandomNumberGenerator {
pub fn new(mode1: Generator) -> RandomNumberGenerator {
RandomNumberGenerator {
pins: Pins::new(),
mpu: MPU6050::new(),
mode: mode1,
}
}
pub fn generate_by_analog(&mut self) -> u8 {
match self.mode {
Generator::Mpu => unreachable!(),
Generator::Analog => (),
}
let mut bits1: u8 = unsafe { xor_rotate() };
bits1 = xor_shift(bits1);
let bits2: u8 = unsafe { xor_rotate() };
bits1 = xor(bits1, bits2);
let mut lbuf: u8 = unsafe { xor_rotate() };
let mut rbuf: u8 = unsafe { xor_rotate() };
let buf: u8 = xor(lbuf, rbuf);
let mut bits3: u8 = 0;
for i in 1..4 {
let left: u8;
let right: u8;
delay_ms(100);
left = self.pins.analog[0].read() as u8;
delay_ms(100);
right = self.pins.analog[0].read() as u8;
bits3 = xor(bits3, rotate(left, i));
bits3 = xor(bits3, rotate(right, 7 - i));
for j in 1..8 {
let lb = left.get_bit(j);
let rb = right.get_bit(j);
if lb != rb {
if buf % 2 == 0 {
lbuf = push_left(lbuf, lb as u8);
} else {
rbuf = push_right(rbuf, lb as u8);
}
}
}
}
bits1 = xor_shift(bits1);
bits1 = xor(bits1, bits3);
xor(bits1, xor(lbuf, rbuf))
}
pub fn generate_by_mpu(&mut self) -> u8 {
match self.mode {
Generator::Analog => unreachable!(),
Generator::Mpu => (),
}
let (a, b, c, d, e, f) = generate_mpu();
let a1 = (a & 0x3) << 6;
let a2 = (d & 0x3) << 6;
let mut bits1 = xor(a1, xor(c << 4, xor(b << 2, xor(a, c >> 2))));
let bits2 = xor(a2, xor(f << 4, xor(e << 2, xor(d, f >> 2))));
bits1 = xor_shift(bits1);
bits1 = xor(bits1, bits2);
bits1
}
}
pub fn rotate(b: u8, n: u8) -> u8 {
(b >> n) | (b << (8 - n))
}
pub fn xor(a: u8, b: u8) -> u8 {
(a | b) - (a & b)
}
pub fn xor_shift(a: u8) -> u8 {
let mut ans: u8 = 0;
ans = xor(ans, a);
ans = xor(ans, a >> 3);
ans = xor(ans, a << 5);
ans = xor(ans, a >> 4);
ans
}
pub unsafe fn xor_rotate() -> u8 {
let mut bits1: u8 = 0;
let mut obj = RandomNumberGenerator::new(Generator::Analog);
for i in 1..8 {
let a: u8 = obj.pins.analog[0].read() as u8;
bits1 = xor(bits1, rotate(a, i));
delay_ms(20);
}
bits1
}
pub fn push_left(val: u8, change: u8) -> u8 {
xor(val << 1, xor(change, val))
}
pub fn push_right(val: u8, change: u8) -> u8 {
xor(val >> 1, xor(change << 7, val))
}
pub fn generate_mpu() -> (u8, u8, u8, u8, u8, u8) {
let obj = RandomNumberGenerator::new(Generator::Mpu);
obj.mpu
.begin(MPUdpsT::MPU6050Scale250DPS, MPURangeT::MPU6050Range2G);
obj.mpu.read_gyro();
delay_ms(1000);
obj.mpu.read_accel();
delay_ms(1000);
let d: u8 = obj.mpu.gyro_output[0] as u8;
let e: u8 = obj.mpu.gyro_output[1] as u8;
let f: u8 = obj.mpu.gyro_output[2] as u8;
let a: u8 = obj.mpu.accel_output[0] as u8;
let b: u8 = obj.mpu.accel_output[1] as u8;
let c: u8 = obj.mpu.accel_output[2] as u8;
(a, b, c, d, e, f)
}