Merge #1086
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:
commit
eb010fbe33
3 changed files with 40 additions and 2 deletions
|
@ -55,6 +55,7 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
|
||||||
chrono = { version = "0.4", default-features = false, optional = true }
|
chrono = { version = "0.4", default-features = false, optional = true }
|
||||||
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
|
embedded-io = { version = "0.4.0", features = ["async"], optional = true }
|
||||||
embedded-storage = { version = "0.3" }
|
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 = { git = "https://github.com/embassy-rs/rp2040-pac2", rev="017e3c9007b2d3b6965f0d85b5bf8ce3fa6d7364", features = ["rt"] }
|
||||||
#rp2040-pac2 = { path = "../../rp2040-pac2", features = ["rt"] }
|
#rp2040-pac2 = { path = "../../rp2040-pac2", features = ["rt"] }
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{pac, reset};
|
||||||
const XOSC_MHZ: u32 = 12;
|
const XOSC_MHZ: u32 = 12;
|
||||||
|
|
||||||
/// safety: must be called exactly once at bootup
|
/// safety: must be called exactly once at bootup
|
||||||
pub unsafe fn init() {
|
pub(crate) unsafe fn init() {
|
||||||
// Reset everything except:
|
// Reset everything except:
|
||||||
// - QSPI (we're using it to run this code!)
|
// - QSPI (we're using it to run this code!)
|
||||||
// - PLLs (it may be suicide if that's what's clocking us)
|
// - 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
|
// Turn on post divider
|
||||||
p.pwr().modify(|w| w.set_postdivpd(false));
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub mod uart;
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
pub mod usb;
|
pub mod usb;
|
||||||
|
|
||||||
mod clocks;
|
pub mod clocks;
|
||||||
pub mod flash;
|
pub mod flash;
|
||||||
mod reset;
|
mod reset;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue