diff --git a/Cargo.lock b/Cargo.lock index d975500..f6414e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,6 +110,8 @@ dependencies = [ "embedded-io", "max78000-pac", "paste", + "rand", + "rand_core", ] [[package]] @@ -151,6 +153,21 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + [[package]] name = "rustc_version" version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index bd86b28..3479cf3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,10 @@ embedded-hal-nb = "1.0.0" embedded-io = "0.6.1" max78000-pac = "0.3.0" paste = "1.0.15" +rand = { version = "0.8.5", default-features = false, optional = true } +rand_core = { version = "0.6.4", default-features = false, optional = true } [features] +default = ["rand", "rt"] +rand = ["dep:rand", "dep:rand_core"] rt = ["max78000-pac/critical-section", "max78000-pac/rt"] diff --git a/src/lib.rs b/src/lib.rs index 13e49a5..9642125 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ //! # Hardware Abstraction Layer for MAX7800x Microcontrollers #![no_std] +#![feature(doc_cfg)] /// Re-export of the Peripheral Access Crate (PAC) for the MAX78000. pub use max78000_pac as pac; diff --git a/src/trng.rs b/src/trng.rs index 8dd6731..2822b9b 100644 --- a/src/trng.rs +++ b/src/trng.rs @@ -2,6 +2,11 @@ //! //! The TRNG is a hardware module that generates random numbers using //! physical entropy sources. +use rand::Error; +#[cfg(feature = "rand")] +use rand::RngCore; +#[cfg(feature = "rand")] +use rand_core::impls::{fill_bytes_via_next, next_u64_via_u32}; /// # True Random Number Generator (TRNG) Peripheral /// @@ -10,10 +15,7 @@ /// // Create a new TRNG peripheral instance /// let trng = Trng::new(p.trng, &mut gcr.reg); /// // Generate a random 32-bit number -/// let random_number = trng.next_u32(); -/// // Fill an array with random bytes -/// let mut buffer = [0u8; 64]; -/// trng.fill_bytes(&mut buffer); +/// let random_u32 = trng.gen_u32(); /// ``` pub struct Trng { trng: crate::pac::Trng, @@ -36,23 +38,49 @@ impl Trng { /// Generate a random 32-bit number. #[inline(always)] - pub fn next_u32(&self) -> u32 { + pub fn gen_u32(&self) -> u32 { while !self._is_ready() {} self.trng.data().read().bits() as u32 } +} + +/// Enhanced functionality for the TRNG peripheral using the [`rand`] crate. +/// This trait implementation can be disabled by removing the `rand` feature +/// flag since you may want to implement your own [`RngCore`]. +/// +/// Example: +/// ``` +/// // Create a new TRNG peripheral instance +/// let trng = Trng::new(p.trng, &mut gcr.reg); +/// // Generate a random 32-bit number +/// let random_u32 = trng.next_u32(); // Equivalent to trng.gen_u32() +/// // Generate a random 64-bit number +/// let random_u64 = trng.next_u64(); +/// // Fill a buffer with random bytes +/// let mut buffer = [0u8; 16]; +/// trng.fill_bytes(&mut buffer); +/// ``` +#[doc(cfg(feature = "rand"))] +#[cfg(feature = "rand")] +impl RngCore for Trng { + #[inline(always)] + fn next_u32(&mut self) -> u32 { + self.gen_u32() + } + + #[inline(always)] + fn next_u64(&mut self) -> u64 { + next_u64_via_u32(self) + } - /// Generate a random 8-bit number. #[inline(always)] - pub fn next_u8(&self) -> u8 { - self.next_u32() as u8 + fn fill_bytes(&mut self, dest: &mut [u8]) { + fill_bytes_via_next(self, dest); } - /// Fill a buffer with random bytes. #[inline(always)] - pub fn fill_bytes(&self, buffer: &mut [u8]) { - for word in buffer.chunks_mut(size_of::()) { - let random = self.next_u32(); - word.copy_from_slice(&random.to_le_bytes()[..word.len()]); - } + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { + self.fill_bytes(dest); + Ok(()) } } \ No newline at end of file