Skip to content

Commit 3fd034d

Browse files
committed
Enhanced the documentation for rng
1 parent 8a89078 commit 3fd034d

File tree

1 file changed

+64
-4
lines changed

1 file changed

+64
-4
lines changed

src/rng.rs

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
//! # Hardware random number generator.
2+
//!
3+
//!
4+
//! The build in random number generator (RNG) of an STM32F4 uses analog noise to
5+
//! proved random 32-bit values.
6+
//!
7+
//! Notes:
8+
//! - It takes 40 periods of `RNG_CLK` to generate a new random value.
9+
//! - The RNG requires the `PLL48_CLK` to be active ([more details](RngExt::constrain))
10+
//!
11+
//! For more details, see reference manual chapter 24.
12+
//!
13+
//! Minimal working example:
14+
//! ```
15+
//! let dp = stm32::Peripherals::take().unwrap();
16+
//! let rcc = dp.RCC.constrain();
17+
//! let clocks = rcc.cfgr.require_pll48clk().freeze();
18+
//! let mut rand_source = dp.RNG.constrain(clocks);
19+
//! let rand_val = rand_source.next_u32();
20+
//! ```
21+
//!
22+
//! A full exaple can be found [in the examples folder on github](https://github.com/stm32-rs/stm32f4xx-hal/blob/master/examples/rng-display.rs)
123
use core::cmp;
224
use core::mem;
325

@@ -10,6 +32,7 @@ use core::num::NonZeroU32;
1032
use core::ops::Shl;
1133
use rand_core::RngCore;
1234

35+
/// Random number generator specific errors
1336
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
1437
pub enum ErrorKind {
1538
/// The RNG_CLK was not correctly detected (fRNG_CLK< fHCLK/16).
@@ -28,15 +51,36 @@ impl From<ErrorKind> for rand_core::Error {
2851
}
2952
}
3053

54+
/// Helper trait to implement the `constrain` method for the
55+
/// [RNG peripheral](crate::stm32::RNG) which is how the [Rng] struct is
56+
/// created.
57+
///
58+
/// Usage:
59+
/// ```
60+
/// let dp = stm32::Peripherals::take().unwrap();
61+
/// let rcc = dp.RCC.constrain();
62+
/// let clocks = rcc.cfgr.require_pll48clk().freeze();
63+
/// let mut rand_source = dp.RNG.constrain(clocks);
64+
/// ```
3165
pub trait RngExt {
66+
/// Enables the hardware random generator and provides the [Rng] struct.
67+
///
68+
/// The datasheet states, that the `RNG_CLK` must not be less than 1/16 HCLK
69+
/// (HCLK is the CPU clock), otherwise all reads of the RNG would return a
70+
/// ClockError (CECS error).
71+
/// As the `RNG_CLK` always seems to be connected to the `PLL48_CLK` and the
72+
/// maximum value of `HCLK` is 168MHz, this is always true as long as the `PLL48_CLK` is enabled.
73+
/// This can be done with the [require_pll48clk](crate::rcc::CFGR::require_pll48clk) function.
74+
///
75+
/// See reference manual section 24.4.2 for more details
76+
///
77+
/// # Panics
78+
///
79+
/// This function will panic if `PLL48_CLK < 1/16 HCLK`.
3280
fn constrain(self, clocks: Clocks) -> Rng;
3381
}
3482

3583
impl RngExt for RNG {
36-
/// Enable RNG_CLK and the RNG peripheral.
37-
/// Note that clocks must already be configured such that RNG_CLK is not less than 1/16 HCLK,
38-
/// otherwise all reads of the RNG would return a ClockError (CECS error).
39-
/// This function will panic if pll48clk < 1/16 hclk.
4084
fn constrain(self, clocks: Clocks) -> Rng {
4185
let rcc = unsafe { &*pac::RCC::ptr() };
4286

@@ -58,6 +102,20 @@ impl RngExt for RNG {
58102
}
59103
}
60104

105+
/// Random number provider which provides access to all [rand_core::RngCore]
106+
/// functions.
107+
///
108+
/// Example use:
109+
///
110+
/// ```
111+
/// use rand_core::RngCore;
112+
///
113+
/// // ...
114+
///
115+
/// let mut rand_source = dp.RNG.constrain(clocks);
116+
/// let rand_u32: u32 = rand_source.next_u32();
117+
/// let rand_u64: u64 = rand_source.next_u64();
118+
/// ```
61119
pub struct Rng {
62120
rb: RNG,
63121
}
@@ -80,6 +138,8 @@ impl Rng {
80138
}
81139
}
82140

141+
/// Releases ownership of the [RNG](crate::stm32::RNG) peripheral object
142+
/// (after which `self` can't be used anymore).
83143
pub fn release(self) -> RNG {
84144
self.rb
85145
}

0 commit comments

Comments
 (0)