1086: rp: Add an RngCore impl based on ROSC.RANDOMBIT r=Dirbaio a=yodaldevoid

This has the potential to not be random, but it should not be an issue if default clock settings are used.

Co-authored-by: Gabriel Smith <ga29smith@gmail.com>
This commit is contained in:
bors[bot] 2022-11-30 19:10:44 +00:00 committed by GitHub
commit eb010fbe33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 2 deletions

View file

@ -55,6 +55,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
chrono = { version = "0.4", default-features = false, optional = true }
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
embedded-storage = { version = "0.3" }
rand_core = "0.6.4"
rp2040-pac2 = { git = "https://github.com/embassy-rs/rp2040-pac2", rev="017e3c9007b2d3b6965f0d85b5bf8ce3fa6d7364", features = ["rt"] }
#rp2040-pac2 = { path = "../../rp2040-pac2", features = ["rt"] }

View file

@ -5,7 +5,7 @@ use crate::{pac, reset};
const XOSC_MHZ: u32 = 12;
/// safety: must be called exactly once at bootup
pub unsafe fn init() {
pub(crate) unsafe fn init() {
// Reset everything except:
// - QSPI (we're using it to run this code!)
// - PLLs (it may be suicide if that's what's clocking us)
@ -196,3 +196,40 @@ unsafe fn configure_pll(p: pac::pll::Pll, refdiv: u32, vco_freq: u32, post_div1:
// Turn on post divider
p.pwr().modify(|w| w.set_postdivpd(false));
}
/// Random number generator based on the ROSC RANDOMBIT register.
///
/// This will not produce random values if the ROSC is stopped or run at some
/// harmonic of the bus frequency. With default clock settings these are not
/// issues.
pub struct RoscRng;
impl RoscRng {
fn next_u8() -> u8 {
let random_reg = pac::ROSC.randombit();
let mut acc = 0;
for _ in 0..u8::BITS {
acc <<= 1;
acc |= unsafe { random_reg.read().randombit() as u8 };
}
acc
}
}
impl rand_core::RngCore for RoscRng {
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
Ok(self.fill_bytes(dest))
}
fn next_u32(&mut self) -> u32 {
rand_core::impls::next_u32_via_fill(self)
}
fn next_u64(&mut self) -> u64 {
rand_core::impls::next_u64_via_fill(self)
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
dest.fill_with(Self::next_u8)
}
}

View file

@ -21,7 +21,7 @@ pub mod uart;
#[cfg(feature = "nightly")]
pub mod usb;
mod clocks;
pub mod clocks;
pub mod flash;
mod reset;