From b65406791a718e4e15a388b20c843fff2ab88037 Mon Sep 17 00:00:00 2001 From: Jan Christoph Bernack Date: Sat, 1 Jul 2023 03:15:39 +0200 Subject: [PATCH 1/3] add RNG conditioning --- embassy-stm32/src/rng.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 27415c2d7..5d61d0361 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -31,6 +31,7 @@ impl<'d, T: Instance> Rng<'d, T> { random } + #[cfg(rng_v1)] pub fn reset(&mut self) { // rng_v2 locks up on seed error, needs reset #[cfg(rng_v2)] @@ -49,6 +50,38 @@ impl<'d, T: Instance> Rng<'d, T> { let _ = self.next_u32(); } + #[cfg(not(rng_v1))] + pub fn reset(&mut self) { + T::regs().cr().modify(|reg| { + reg.set_rngen(false); + reg.set_condrst(true); + // set RNG config "A" according to reference manual + // this has to be written within the same write access as setting the CONDRST bit + reg.set_nistc(pac::rng::vals::Nistc::DEFAULT); + reg.set_rng_config1(pac::rng::vals::RngConfig1::CONFIGA); + reg.set_rng_config2(pac::rng::vals::RngConfig2::CONFIGA_B); + reg.set_rng_config3(pac::rng::vals::RngConfig3::CONFIGA); + reg.set_clkdiv(pac::rng::vals::Clkdiv::NODIV); + }); + // wait for CONDRST to be set + while !T::regs().cr().read().condrst() {} + // magic number must be written immediately before every read or write access to HTCR + T::regs().htcr().write(|w| w.set_htcfg(pac::rng::vals::Htcfg::MAGIC)); + // write recommended value according to reference manual + // note: HTCR can only be written during conditioning + T::regs() + .htcr() + .write(|w| w.set_htcfg(pac::rng::vals::Htcfg::RECOMMENDED)); + // finish conditioning + T::regs().cr().modify(|reg| { + reg.set_rngen(true); + reg.set_condrst(false); + reg.set_ie(true); + }); + // wait for CONDRST to be reset + while T::regs().cr().read().condrst() {} + } + pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { T::regs().cr().modify(|reg| { reg.set_rngen(true); From d6c5c1772cf2c6099ab08675afc0fead2e50fffb Mon Sep 17 00:00:00 2001 From: Jan Christoph Bernack Date: Sat, 1 Jul 2023 03:32:01 +0200 Subject: [PATCH 2/3] improve RNG polling --- embassy-stm32/src/rng.rs | 105 ++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 39 deletions(-) diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index 5d61d0361..c4b77d019 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -3,11 +3,12 @@ use core::future::poll_fn; use core::task::Poll; +use embassy_hal_internal::interrupt::InterruptExt; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use rand_core::{CryptoRng, RngCore}; -use crate::{pac, peripherals, Peripheral}; +use crate::{interrupt, pac, peripherals, Peripheral}; pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new(); @@ -28,31 +29,31 @@ impl<'d, T: Instance> Rng<'d, T> { into_ref!(inner); let mut random = Self { _inner: inner }; random.reset(); + unsafe { + interrupt::RNG.enable(); + } random } #[cfg(rng_v1)] pub fn reset(&mut self) { - // rng_v2 locks up on seed error, needs reset - #[cfg(rng_v2)] - if T::regs().sr().read().seis() { - T::reset(); - } - T::regs().cr().modify(|reg| { - reg.set_rngen(true); - reg.set_ie(true); + T::regs().cr().write(|reg| { + reg.set_rngen(false); }); T::regs().sr().modify(|reg| { reg.set_seis(false); reg.set_ceis(false); }); + T::regs().cr().modify(|reg| { + reg.set_rngen(true); + }); // Reference manual says to discard the first. let _ = self.next_u32(); } #[cfg(not(rng_v1))] pub fn reset(&mut self) { - T::regs().cr().modify(|reg| { + T::regs().cr().write(|reg| { reg.set_rngen(false); reg.set_condrst(true); // set RNG config "A" according to reference manual @@ -76,42 +77,68 @@ impl<'d, T: Instance> Rng<'d, T> { T::regs().cr().modify(|reg| { reg.set_rngen(true); reg.set_condrst(false); - reg.set_ie(true); }); // wait for CONDRST to be reset while T::regs().cr().read().condrst() {} } + pub fn recover_seed_error(&mut self) -> () { + self.reset(); + // reset should also clear the SEIS flag + if T::regs().sr().read().seis() { + warn!("recovering from seed error failed"); + return; + } + // wait for SECS to be cleared by RNG + while T::regs().sr().read().secs() {} + } + pub async fn async_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> { - T::regs().cr().modify(|reg| { - reg.set_rngen(true); - }); - for chunk in dest.chunks_mut(4) { - poll_fn(|cx| { - RNG_WAKER.register(cx.waker()); - T::regs().cr().modify(|reg| { - reg.set_ie(true); - }); - - let bits = T::regs().sr().read(); - - if bits.drdy() { - Poll::Ready(Ok(())) - } else if bits.seis() { - self.reset(); - Poll::Ready(Err(Error::SeedError)) - } else if bits.ceis() { - self.reset(); - Poll::Ready(Err(Error::ClockError)) - } else { - Poll::Pending + let bits = T::regs().sr().read(); + if bits.seis() { + // in case of noise-source or seed error we try to recover here + // but we must not use the data in DR and we return an error + // to leave retry-logic to the application + self.recover_seed_error(); + return Err(Error::SeedError); + } else if bits.ceis() { + // clock error detected, DR could still be used but keep it safe, + // clear the error and abort + T::regs().sr().modify(|sr| sr.set_ceis(false)); + return Err(Error::ClockError); + } else if bits.drdy() { + // DR can be read up to four times until the output buffer is empty + // DRDY is cleared automatically when that happens + let random_word = T::regs().dr().read(); + // reference manual: always check if DR is zero + if random_word == 0 { + return Err(Error::SeedError); } - }) - .await?; - let random_bytes = T::regs().dr().read().to_be_bytes(); - for (dest, src) in chunk.iter_mut().zip(random_bytes.iter()) { - *dest = *src + // write bytes to chunk + for (dest, src) in chunk.iter_mut().zip(random_word.to_be_bytes().iter()) { + *dest = *src + } + } else { + // wait for interrupt + poll_fn(|cx| { + // quick check to avoid registration if already done. + let bits = T::regs().sr().read(); + if bits.drdy() || bits.seis() || bits.ceis() { + return Poll::Ready(()); + } + RNG_WAKER.register(cx.waker()); + T::regs().cr().modify(|reg| reg.set_ie(true)); + // Need to check condition **after** `register` to avoid a race + // condition that would result in lost notifications. + let bits = T::regs().sr().read(); + if bits.drdy() || bits.seis() || bits.ceis() { + Poll::Ready(()) + } else { + Poll::Pending + } + }) + .await; } } @@ -186,7 +213,7 @@ macro_rules! irq { unsafe fn $irq() { let bits = $crate::pac::RNG.sr().read(); if bits.drdy() || bits.seis() || bits.ceis() { - $crate::pac::RNG.cr().write(|reg| reg.set_ie(false)); + $crate::pac::RNG.cr().modify(|reg| reg.set_ie(false)); $crate::rng::RNG_WAKER.wake(); } } From 4999b045df4e5956733b0341795714a9214c12d3 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 31 Jul 2023 01:41:12 +0200 Subject: [PATCH 3/3] stm32/rng: use bind_interrupts!. --- embassy-stm32/Cargo.toml | 4 +- embassy-stm32/src/rng.rs | 86 ++++++++++-------------- examples/stm32f4/src/bin/eth.rs | 6 +- examples/stm32f4/src/bin/usb_ethernet.rs | 5 +- examples/stm32f7/src/bin/eth.rs | 6 +- examples/stm32h5/src/bin/eth.rs | 6 +- examples/stm32h5/src/bin/rng.rs | 7 +- examples/stm32h7/src/bin/eth.rs | 6 +- examples/stm32h7/src/bin/eth_client.rs | 6 +- examples/stm32h7/src/bin/rng.rs | 7 +- examples/stm32l0/src/bin/lora_lorawan.rs | 8 ++- examples/stm32l4/src/bin/rng.rs | 8 ++- examples/stm32l5/src/bin/rng.rs | 8 ++- examples/stm32l5/src/bin/usb_ethernet.rs | 5 +- examples/stm32wl/src/bin/lora_lorawan.rs | 7 +- examples/stm32wl/src/bin/random.rs | 10 ++- 16 files changed, 103 insertions(+), 82 deletions(-) diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml index ba279f795..a1323e85b 100644 --- a/embassy-stm32/Cargo.toml +++ b/embassy-stm32/Cargo.toml @@ -57,7 +57,7 @@ sdio-host = "0.5.0" embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } critical-section = "1.1" atomic-polyfill = "1.0.1" -stm32-metapac = "13" +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe" } vcell = "0.1.3" bxcan = "0.7.0" nb = "1.0.0" @@ -75,7 +75,7 @@ critical-section = { version = "1.1", features = ["std"] } [build-dependencies] proc-macro2 = "1.0.36" quote = "1.0.15" -stm32-metapac = { version = "13", default-features = false, features = ["metadata"]} +stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe", default-features = false, features = ["metadata"]} [features] default = ["rt"] diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs index c4b77d019..2a4978ec5 100644 --- a/embassy-stm32/src/rng.rs +++ b/embassy-stm32/src/rng.rs @@ -1,16 +1,17 @@ #![macro_use] use core::future::poll_fn; +use core::marker::PhantomData; use core::task::Poll; -use embassy_hal_internal::interrupt::InterruptExt; use embassy_hal_internal::{into_ref, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; use rand_core::{CryptoRng, RngCore}; +use crate::interrupt::typelevel::Interrupt; use crate::{interrupt, pac, peripherals, Peripheral}; -pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new(); +static RNG_WAKER: AtomicWaker = AtomicWaker::new(); #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum Error { @@ -18,20 +19,38 @@ pub enum Error { ClockError, } +pub struct InterruptHandler { + _phantom: PhantomData, +} + +impl interrupt::typelevel::Handler for InterruptHandler { + unsafe fn on_interrupt() { + let bits = T::regs().sr().read(); + if bits.drdy() || bits.seis() || bits.ceis() { + T::regs().cr().modify(|reg| reg.set_ie(false)); + RNG_WAKER.wake(); + } + } +} + pub struct Rng<'d, T: Instance> { _inner: PeripheralRef<'d, T>, } impl<'d, T: Instance> Rng<'d, T> { - pub fn new(inner: impl Peripheral

+ 'd) -> Self { + pub fn new( + inner: impl Peripheral

+ 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, + ) -> Self { T::enable(); T::reset(); into_ref!(inner); let mut random = Self { _inner: inner }; random.reset(); - unsafe { - interrupt::RNG.enable(); - } + + T::Interrupt::unpend(); + unsafe { T::Interrupt::enable() }; + random } @@ -189,57 +208,20 @@ pub(crate) mod sealed { } } -pub trait Instance: sealed::Instance + crate::rcc::RccPeripheral {} +pub trait Instance: sealed::Instance + Peripheral

+ crate::rcc::RccPeripheral + 'static + Send { + type Interrupt: interrupt::typelevel::Interrupt; +} -foreach_peripheral!( - (rng, $inst:ident) => { - impl Instance for peripherals::$inst {} +foreach_interrupt!( + ($inst:ident, rng, RNG, GLOBAL, $irq:ident) => { + impl Instance for peripherals::$inst { + type Interrupt = crate::interrupt::typelevel::$irq; + } impl sealed::Instance for peripherals::$inst { fn regs() -> crate::pac::rng::Rng { - crate::pac::RNG + crate::pac::$inst } } }; ); - -#[cfg(feature = "rt")] -macro_rules! irq { - ($irq:ident) => { - mod rng_irq { - use crate::interrupt; - - #[interrupt] - unsafe fn $irq() { - let bits = $crate::pac::RNG.sr().read(); - if bits.drdy() || bits.seis() || bits.ceis() { - $crate::pac::RNG.cr().modify(|reg| reg.set_ie(false)); - $crate::rng::RNG_WAKER.wake(); - } - } - } - }; -} - -#[cfg(feature = "rt")] -foreach_interrupt!( - (RNG) => { - irq!(RNG); - }; - - (RNG_LPUART1) => { - irq!(RNG_LPUART1); - }; - - (AES_RNG_LPUART1) => { - irq!(AES_RNG_LPUART1); - }; - - (AES_RNG) => { - irq!(AES_RNG); - }; - - (HASH_RNG) => { - irq!(HASH_RNG); - }; -); diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs index d0b164393..496016687 100644 --- a/examples/stm32f4/src/bin/eth.rs +++ b/examples/stm32f4/src/bin/eth.rs @@ -11,13 +11,15 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; -use embassy_stm32::{bind_interrupts, eth, Config}; +use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::{Duration, Timer}; use embedded_io::asynch::Write; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; + bind_interrupts!(struct Irqs { ETH => eth::InterruptHandler; + HASH_RNG => rng::InterruptHandler; }); type Device = Ethernet<'static, ETH, GenericSMI>; @@ -36,7 +38,7 @@ async fn main(spawner: Spawner) -> ! { info!("Hello World!"); // Generate random seed. - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut seed = [0; 8]; let _ = rng.async_fill_bytes(&mut seed).await; let seed = u64::from_le_bytes(seed); diff --git a/examples/stm32f4/src/bin/usb_ethernet.rs b/examples/stm32f4/src/bin/usb_ethernet.rs index b1f01417c..740d3018e 100644 --- a/examples/stm32f4/src/bin/usb_ethernet.rs +++ b/examples/stm32f4/src/bin/usb_ethernet.rs @@ -6,7 +6,7 @@ use defmt::*; use embassy_executor::Spawner; use embassy_net::tcp::TcpSocket; use embassy_net::{Stack, StackResources}; -use embassy_stm32::rng::Rng; +use embassy_stm32::rng::{self, Rng}; use embassy_stm32::time::mhz; use embassy_stm32::usb_otg::Driver; use embassy_stm32::{bind_interrupts, peripherals, usb_otg, Config}; @@ -38,6 +38,7 @@ async fn net_task(stack: &'static Stack>) -> ! { bind_interrupts!(struct Irqs { OTG_FS => usb_otg::InterruptHandler; + HASH_RNG => rng::InterruptHandler; }); #[embassy_executor::main] @@ -104,7 +105,7 @@ async fn main(spawner: Spawner) { //}); // Generate random seed - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut seed = [0; 8]; unwrap!(rng.async_fill_bytes(&mut seed).await); let seed = u64::from_le_bytes(seed); diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index c6b2ba45c..e5abf52bc 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -11,14 +11,16 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; -use embassy_stm32::{bind_interrupts, eth, Config}; +use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::{Duration, Timer}; use embedded_io::asynch::Write; use rand_core::RngCore; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; + bind_interrupts!(struct Irqs { ETH => eth::InterruptHandler; + RNG => rng::InterruptHandler; }); type Device = Ethernet<'static, ETH, GenericSMI>; @@ -37,7 +39,7 @@ async fn main(spawner: Spawner) -> ! { info!("Hello World!"); // Generate random seed. - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut seed = [0; 8]; rng.fill_bytes(&mut seed); let seed = u64::from_le_bytes(seed); diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs index 0bff85ed8..2aa2ab62b 100644 --- a/examples/stm32h5/src/bin/eth.rs +++ b/examples/stm32h5/src/bin/eth.rs @@ -12,14 +12,16 @@ use embassy_stm32::peripherals::ETH; use embassy_stm32::rcc::{AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllSource, Sysclk, VoltageScale}; use embassy_stm32::rng::Rng; use embassy_stm32::time::Hertz; -use embassy_stm32::{bind_interrupts, eth, Config}; +use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::{Duration, Timer}; use embedded_io::asynch::Write; use rand_core::RngCore; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; + bind_interrupts!(struct Irqs { ETH => eth::InterruptHandler; + RNG => rng::InterruptHandler; }); type Device = Ethernet<'static, ETH, GenericSMI>; @@ -56,7 +58,7 @@ async fn main(spawner: Spawner) -> ! { info!("Hello World!"); // Generate random seed. - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut seed = [0; 8]; rng.fill_bytes(&mut seed); let seed = u64::from_le_bytes(seed); diff --git a/examples/stm32h5/src/bin/rng.rs b/examples/stm32h5/src/bin/rng.rs index af9be0b62..7c8c50eca 100644 --- a/examples/stm32h5/src/bin/rng.rs +++ b/examples/stm32h5/src/bin/rng.rs @@ -5,14 +5,19 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, peripherals, rng}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut buf = [0u8; 16]; unwrap!(rng.async_fill_bytes(&mut buf).await); diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index cfafcaed1..c93be9f00 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -11,14 +11,16 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; -use embassy_stm32::{bind_interrupts, eth, Config}; +use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::{Duration, Timer}; use embedded_io::asynch::Write; use rand_core::RngCore; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; + bind_interrupts!(struct Irqs { ETH => eth::InterruptHandler; + RNG => rng::InterruptHandler; }); type Device = Ethernet<'static, ETH, GenericSMI>; @@ -38,7 +40,7 @@ async fn main(spawner: Spawner) -> ! { info!("Hello World!"); // Generate random seed. - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut seed = [0; 8]; rng.fill_bytes(&mut seed); let seed = u64::from_le_bytes(seed); diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 4ed737578..78005e91f 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -11,15 +11,17 @@ use embassy_stm32::eth::{Ethernet, PacketQueue}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; -use embassy_stm32::{bind_interrupts, eth, Config}; +use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; use embassy_time::{Duration, Timer}; use embedded_io::asynch::Write; use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; use rand_core::RngCore; use static_cell::make_static; use {defmt_rtt as _, panic_probe as _}; + bind_interrupts!(struct Irqs { ETH => eth::InterruptHandler; + RNG => rng::InterruptHandler; }); type Device = Ethernet<'static, ETH, GenericSMI>; @@ -39,7 +41,7 @@ async fn main(spawner: Spawner) -> ! { info!("Hello World!"); // Generate random seed. - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut seed = [0; 8]; rng.fill_bytes(&mut seed); let seed = u64::from_le_bytes(seed); diff --git a/examples/stm32h7/src/bin/rng.rs b/examples/stm32h7/src/bin/rng.rs index af9be0b62..7c8c50eca 100644 --- a/examples/stm32h7/src/bin/rng.rs +++ b/examples/stm32h7/src/bin/rng.rs @@ -5,14 +5,19 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rng::Rng; +use embassy_stm32::{bind_interrupts, peripherals, rng}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_stm32::init(Default::default()); info!("Hello World!"); - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut buf = [0u8; 16]; unwrap!(rng.async_fill_bytes(&mut buf).await); diff --git a/examples/stm32l0/src/bin/lora_lorawan.rs b/examples/stm32l0/src/bin/lora_lorawan.rs index c397edd58..03c793b32 100644 --- a/examples/stm32l0/src/bin/lora_lorawan.rs +++ b/examples/stm32l0/src/bin/lora_lorawan.rs @@ -12,8 +12,8 @@ use embassy_lora::LoraTimer; use embassy_stm32::exti::{Channel, ExtiInput}; use embassy_stm32::gpio::{Input, Level, Output, Pin, Pull, Speed}; use embassy_stm32::rng::Rng; -use embassy_stm32::spi; use embassy_stm32::time::khz; +use embassy_stm32::{bind_interrupts, peripherals, rng, spi}; use embassy_time::Delay; use lora_phy::mod_params::*; use lora_phy::sx1276_7_8_9::SX1276_7_8_9; @@ -23,6 +23,10 @@ use lorawan_device::async_device::lora_radio::LoRaRadio; use lorawan_device::async_device::{region, Device, JoinMode}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + RNG_LPUART1 => rng::InterruptHandler; +}); + const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set this appropriately for the region #[embassy_executor::main] @@ -66,7 +70,7 @@ async fn main(_spawner: Spawner) { let radio = LoRaRadio::new(lora); let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); - let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG)); + let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG, Irqs)); defmt::info!("Joining LoRaWAN network"); diff --git a/examples/stm32l4/src/bin/rng.rs b/examples/stm32l4/src/bin/rng.rs index c9302bb99..806e49f59 100644 --- a/examples/stm32l4/src/bin/rng.rs +++ b/examples/stm32l4/src/bin/rng.rs @@ -6,9 +6,13 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; use embassy_stm32::rng::Rng; -use embassy_stm32::Config; +use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); @@ -24,7 +28,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut buf = [0u8; 16]; unwrap!(rng.async_fill_bytes(&mut buf).await); diff --git a/examples/stm32l5/src/bin/rng.rs b/examples/stm32l5/src/bin/rng.rs index d359847e8..9549d64d8 100644 --- a/examples/stm32l5/src/bin/rng.rs +++ b/examples/stm32l5/src/bin/rng.rs @@ -6,9 +6,13 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::rcc::{ClockSrc, PLLClkDiv, PLLMul, PLLSource, PLLSrcDiv}; use embassy_stm32::rng::Rng; -use embassy_stm32::Config; +use embassy_stm32::{bind_interrupts, peripherals, rng, Config}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + RNG => rng::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = Config::default(); @@ -23,7 +27,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut buf = [0u8; 16]; unwrap!(rng.async_fill_bytes(&mut buf).await); diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 32eba4277..5e75b21c9 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -9,7 +9,7 @@ use embassy_net::{Stack, StackResources}; use embassy_stm32::rcc::*; use embassy_stm32::rng::Rng; use embassy_stm32::usb::Driver; -use embassy_stm32::{bind_interrupts, peripherals, usb, Config}; +use embassy_stm32::{bind_interrupts, peripherals, rng, usb, Config}; use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState}; use embassy_usb::class::cdc_ncm::{CdcNcmClass, State}; use embassy_usb::{Builder, UsbDevice}; @@ -24,6 +24,7 @@ const MTU: usize = 1514; bind_interrupts!(struct Irqs { USB_FS => usb::InterruptHandler; + RNG => rng::InterruptHandler; }); #[embassy_executor::task] @@ -99,7 +100,7 @@ async fn main(spawner: Spawner) { //}); // Generate random seed - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let seed = rng.next_u64(); // Init network stack diff --git a/examples/stm32wl/src/bin/lora_lorawan.rs b/examples/stm32wl/src/bin/lora_lorawan.rs index 805d21418..2c9c98861 100644 --- a/examples/stm32wl/src/bin/lora_lorawan.rs +++ b/examples/stm32wl/src/bin/lora_lorawan.rs @@ -10,9 +10,9 @@ use embassy_executor::Spawner; use embassy_lora::iv::{InterruptHandler, Stm32wlInterfaceVariant}; use embassy_lora::LoraTimer; use embassy_stm32::gpio::{Level, Output, Pin, Speed}; -use embassy_stm32::rng::Rng; +use embassy_stm32::rng::{self, Rng}; use embassy_stm32::spi::Spi; -use embassy_stm32::{bind_interrupts, pac}; +use embassy_stm32::{bind_interrupts, pac, peripherals}; use embassy_time::Delay; use lora_phy::mod_params::*; use lora_phy::sx1261_2::SX1261_2; @@ -26,6 +26,7 @@ const LORAWAN_REGION: region::Region = region::Region::EU868; // warning: set th bind_interrupts!(struct Irqs{ SUBGHZ_RADIO => InterruptHandler; + RNG => rng::InterruptHandler; }); #[embassy_executor::main] @@ -58,7 +59,7 @@ async fn main(_spawner: Spawner) { }; let radio = LoRaRadio::new(lora); let region: region::Configuration = region::Configuration::new(LORAWAN_REGION); - let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG)); + let mut device: Device<_, Crypto, _, _> = Device::new(region, radio, LoraTimer::new(), Rng::new(p.RNG, Irqs)); defmt::info!("Joining LoRaWAN network"); diff --git a/examples/stm32wl/src/bin/random.rs b/examples/stm32wl/src/bin/random.rs index d8562fca5..592e65f40 100644 --- a/examples/stm32wl/src/bin/random.rs +++ b/examples/stm32wl/src/bin/random.rs @@ -4,10 +4,14 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_stm32::pac; -use embassy_stm32::rng::Rng; +use embassy_stm32::rng::{self, Rng}; +use embassy_stm32::{bind_interrupts, pac, peripherals}; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs{ + RNG => rng::InterruptHandler; +}); + #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut config = embassy_stm32::Config::default(); @@ -21,7 +25,7 @@ async fn main(_spawner: Spawner) { info!("Hello World!"); - let mut rng = Rng::new(p.RNG); + let mut rng = Rng::new(p.RNG, Irqs); let mut buf = [0u8; 16]; unwrap!(rng.async_fill_bytes(&mut buf).await);