use avr_device::interrupt::{CriticalSection, Mutex}; use avr_hal_generic::avr_device; use core::cell::Cell; static STATE: Mutex> = Mutex::new(Cell::new(Lfsr8::from_seed(0xcd))); pub fn next(token: CriticalSection) -> T { let cell = STATE.borrow(token); let mut rng = cell.get(); let result = T::random(&mut rng); cell.set(rng); result } #[derive(Clone, Copy)] struct Lfsr8 { state: u8, } impl Lfsr8 { pub const fn from_seed(seed: u8) -> Self { Self { state: seed } } } pub trait Rng { fn next_bit(&mut self) -> bool; } impl Rng for Lfsr8 { fn next_bit(&mut self) -> bool { let result = self.state & 1 != 0; let new_bit = ((self.state >> 2) ^ (self.state >> 4) ^ (self.state >> 5) ^ (self.state >> 7)) & 1; // 10110100 tap bit battern self.state = (self.state >> 1) | (new_bit << 7); result } } pub trait Random { fn random(rng: &mut G) -> Self; } impl Random for bool { fn random(rng: &mut G) -> Self { rng.next_bit() } } impl Random for u8 { fn random(rng: &mut G) -> Self { let mut result = 0u8; for i in 0..8 { let bit = rng.next_bit(); result |= (bit as u8) << i; } result } }