Skip to content

Commit 9f457f2

Browse files
Merge #303
303: Better documentation of rng and prelude r=burrbull a=jounathaen This adds doc comments to the rng and prelude module as well as to the re-export of the svd2rust API. The rng documentation might repeat some information, but as the generated documentation splits this to multiple pages, I find it is better that way. I also added small example code to the documentation. The examples in the repository are nice, but I personally would favor examples inside the docs. It might be good, if somebody reads over the prelude part to check that I'm not completely off-track there. Co-authored-by: Jonathan Klimt <jonathan.klimt@rwth-aachen.de>
2 parents 8a89078 + b315c24 commit 9f457f2

File tree

4 files changed

+120
-4
lines changed

4 files changed

+120
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212
- `Enable`, `LPEnable` and `Reset` traits in `rcc`. Implemented for all used peripherals
1313
- Features corresponding to peripherals
1414
- Fixed typo in string representation in DMAError type
15+
- Improved documentation of rng and prelude
1516
- Added an example of integration with RTIC.
1617
- Added internal pullup configuaration for the AlternateOD pin type
1718
- Added USART support for sending and receiving 9-bit words [#299]

src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,54 +29,71 @@ pub use nb;
2929
pub use nb::block;
3030

3131
#[cfg(feature = "stm32f401")]
32+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f401 peripherals.
3233
pub use stm32f4::stm32f401 as pac;
3334

3435
#[cfg(feature = "stm32f405")]
36+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f405 peripherals.
3537
pub use stm32f4::stm32f405 as pac;
3638

3739
#[cfg(feature = "stm32f407")]
40+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f407 peripherals.
3841
pub use stm32f4::stm32f407 as pac;
3942

4043
#[cfg(feature = "stm32f410")]
44+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f410 peripherals.
4145
pub use stm32f4::stm32f410 as pac;
4246

4347
#[cfg(feature = "stm32f411")]
48+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f411 peripherals.
4449
pub use stm32f4::stm32f411 as pac;
4550

4651
#[cfg(feature = "stm32f412")]
52+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f412 peripherals.
4753
pub use stm32f4::stm32f412 as pac;
4854

4955
#[cfg(feature = "stm32f413")]
56+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f413 peripherals.
5057
pub use stm32f4::stm32f413 as pac;
5158

5259
#[cfg(feature = "stm32f415")]
60+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f405 peripherals.
5361
pub use stm32f4::stm32f405 as pac;
5462

5563
#[cfg(feature = "stm32f417")]
64+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f407 peripherals.
5665
pub use stm32f4::stm32f407 as pac;
5766

5867
#[cfg(feature = "stm32f423")]
68+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f413 peripherals.
5969
pub use stm32f4::stm32f413 as pac;
6070

6171
#[cfg(feature = "stm32f427")]
72+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f427 peripherals.
6273
pub use stm32f4::stm32f427 as pac;
6374

6475
#[cfg(feature = "stm32f429")]
76+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f429 peripherals.
6577
pub use stm32f4::stm32f429 as pac;
6678

6779
#[cfg(feature = "stm32f437")]
80+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f427 peripherals.
6881
pub use stm32f4::stm32f427 as pac;
6982

7083
#[cfg(feature = "stm32f439")]
84+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f429 peripherals.
7185
pub use stm32f4::stm32f429 as pac;
7286

7387
#[cfg(feature = "stm32f446")]
88+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f446 peripherals.
7489
pub use stm32f4::stm32f446 as pac;
7590

7691
#[cfg(feature = "stm32f469")]
92+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f469 peripherals.
7793
pub use stm32f4::stm32f469 as pac;
7894

7995
#[cfg(feature = "stm32f479")]
96+
/// Re-export of the [svd2rust](https://crates.io/crates/svd2rust) auto-generated API for the stm32f469 peripherals.
8097
pub use stm32f4::stm32f469 as pac;
8198

8299
// Enable use of interrupt macro

src/prelude.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
//! Convenience re-export of multiple traits.
2+
//!
3+
//! This allows a HAL user to conveniently import this module and have all the
4+
//! helper traits already imported.
5+
//! Otherwise the use of peripherals would require the import of the
6+
//! corresponding module and the import of the trait, which connects this HAL
7+
//! to the autogenerated svd2rust API in [crate::stm32].
8+
//!
9+
//! # Example
10+
//!
11+
//! Consider the following code.
12+
//!
13+
//! ```
14+
//! #[entry]
15+
//! fn main() -> ! {
16+
//! let dp = stm32::Peripherals::take().unwrap();
17+
//! let gpiog = dp.GPIOG.split();
18+
//! let mut led1 = gpiog.pg13.into_push_pull_output();
19+
//! led1.set_high().unwrap();
20+
//! }
21+
//! ```
22+
//!
23+
//! Without the prelude we would have to import the following traits:
24+
//!
25+
//! ```
26+
//! use stm32f4xx_hal::gpio::GpioExt; // for the split method.
27+
//! use embedded_hal::digital::v2::OutputPin; // for the set_high() function.
28+
//! // And more use-statements with more complex code.
29+
//! ```
30+
//!
31+
//! These imports are a bit unintuitive, because we can create the objects
32+
//! without the import. But we need these traits to access most of their
33+
//! functions.
34+
//!
35+
//! The prelude module keeps the import section cleaner:
36+
//! ```
37+
//! use stm32f4xx_hal::prelude::*;
38+
//! ```
139
pub use embedded_hal::digital::v2::InputPin as _embedded_hal_digital_v2_InputPin;
240
pub use embedded_hal::digital::v2::OutputPin as _embedded_hal_digital_v2_OutputPin;
341
pub use embedded_hal::digital::v2::StatefulOutputPin as _embedded_hal_digital_v2_StatefulOutputPin;

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)