Skip to content

Commit 3256dc9

Browse files
lthieryhannobraun
authored andcommitted
Add RNG driver and example
1 parent e2f4163 commit 3256dc9

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ required-features = ["rt"]
114114
name = "i2c_dma"
115115
required-features = ["rt","stm32l0x2"]
116116

117+
[[example]]
118+
name = "rng"
119+
required-features = ["rt","stm32l0x2"]
120+
117121
[[example]]
118122
name = "rtc"
119123
required-features = ["stm32l0x2"]

examples/rng.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
5+
extern crate panic_halt;
6+
7+
use cortex_m_rt::entry;
8+
use stm32l0xx_hal::{pac, prelude::*, rcc::Config, syscfg::SYSCFG};
9+
10+
use stm32l0xx_hal::rng::Rng;
11+
12+
#[entry]
13+
fn main() -> ! {
14+
let dp = pac::Peripherals::take().unwrap();
15+
16+
let mut rcc = dp.RCC.freeze(Config::hsi16());
17+
let mut syscfg = SYSCFG::new(dp.SYSCFG_COMP, &mut rcc);
18+
19+
// constructor initializes 48 MHz clock that RNG requires
20+
// Initialize 48 MHz clock and RNG
21+
let hsi48 = rcc.enable_hsi48(&mut syscfg, dp.CRS);
22+
let mut rng = Rng::new(dp.RNG, &mut rcc, hsi48);
23+
24+
loop {
25+
// enable starts the ADC conversions that generate the random number
26+
rng.enable();
27+
// wait until the flag flips; interrupt driven is possible but no implemented
28+
rng.wait();
29+
// reading the result clears the ready flag
30+
let _ = rng.take_result();
31+
// can save some power by disabling until next random number needed
32+
rng.disable();
33+
}
34+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub mod prelude;
3333
pub mod pwm;
3434
pub mod pwr;
3535
pub mod rcc;
36+
#[cfg(any(feature = "stm32l0x2", feature = "stm32l0x3"))]
37+
pub mod rng;
3638
pub mod rtc;
3739
pub mod serial;
3840
pub mod spi;

src/rng.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use crate::rcc::{HSI48, Rcc};
2+
3+
pub use crate::pac::{rng, RNG};
4+
5+
6+
pub struct Rng {
7+
rng: RNG
8+
}
9+
10+
impl Rng {
11+
// Initializes the peripheral
12+
pub fn new(rng: RNG, rcc: &mut Rcc, _: HSI48) -> Rng {
13+
// Reset peripheral
14+
rcc.rb.ahbrstr.modify(|_, w| w.rngrst().set_bit());
15+
rcc.rb.ahbrstr.modify(|_, w| w.rngrst().clear_bit());
16+
17+
// Enable peripheral clock
18+
rcc.rb.ahbenr.modify(|_, w| w.rngen().set_bit());
19+
20+
rng.cr.write(|w|
21+
w
22+
.rngen().set_bit()
23+
.ie().clear_bit()
24+
);
25+
26+
let mut ret = Self {
27+
rng
28+
};
29+
30+
ret.enable();
31+
32+
ret
33+
}
34+
35+
pub fn enable(&mut self) {
36+
self.rng.cr.write(|w|
37+
w
38+
.rngen().set_bit()
39+
.ie().clear_bit()
40+
);
41+
}
42+
43+
pub fn disable(&mut self) {
44+
self.rng.cr.modify(|_, w|
45+
w
46+
.rngen().clear_bit()
47+
.ie().clear_bit()
48+
);
49+
}
50+
51+
pub fn wait(&mut self) {
52+
while self.rng.sr.read().drdy().bit_is_clear() {}
53+
}
54+
55+
pub fn take_result(&mut self) -> u32 {
56+
self.rng.dr.read().bits()
57+
}
58+
}

0 commit comments

Comments
 (0)