diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-07-31 01:41:12 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-07-31 01:41:12 +0200 |
| commit | 4999b045df4e5956733b0341795714a9214c12d3 (patch) | |
| tree | 84c40ec27c89bb4dedea30cdafbaad484bfda3cb /embassy-stm32 | |
| parent | d6c5c1772cf2c6099ab08675afc0fead2e50fffb (diff) | |
stm32/rng: use bind_interrupts!.
Diffstat (limited to 'embassy-stm32')
| -rw-r--r-- | embassy-stm32/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/rng.rs | 86 |
2 files changed, 36 insertions, 54 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" | |||
| 57 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } | 57 | embedded-sdmmc = { git = "https://github.com/embassy-rs/embedded-sdmmc-rs", rev = "a4f293d3a6f72158385f79c98634cb8a14d0d2fc", optional = true } |
| 58 | critical-section = "1.1" | 58 | critical-section = "1.1" |
| 59 | atomic-polyfill = "1.0.1" | 59 | atomic-polyfill = "1.0.1" |
| 60 | stm32-metapac = "13" | 60 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe" } |
| 61 | vcell = "0.1.3" | 61 | vcell = "0.1.3" |
| 62 | bxcan = "0.7.0" | 62 | bxcan = "0.7.0" |
| 63 | nb = "1.0.0" | 63 | nb = "1.0.0" |
| @@ -75,7 +75,7 @@ critical-section = { version = "1.1", features = ["std"] } | |||
| 75 | [build-dependencies] | 75 | [build-dependencies] |
| 76 | proc-macro2 = "1.0.36" | 76 | proc-macro2 = "1.0.36" |
| 77 | quote = "1.0.15" | 77 | quote = "1.0.15" |
| 78 | stm32-metapac = { version = "13", default-features = false, features = ["metadata"]} | 78 | stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-1f8ab493e029fc601edebc6bac105a63cc9858fe", default-features = false, features = ["metadata"]} |
| 79 | 79 | ||
| 80 | [features] | 80 | [features] |
| 81 | default = ["rt"] | 81 | 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 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | use core::future::poll_fn; | 3 | use core::future::poll_fn; |
| 4 | use core::marker::PhantomData; | ||
| 4 | use core::task::Poll; | 5 | use core::task::Poll; |
| 5 | 6 | ||
| 6 | use embassy_hal_internal::interrupt::InterruptExt; | ||
| 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 7 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 8 | use embassy_sync::waitqueue::AtomicWaker; |
| 9 | use rand_core::{CryptoRng, RngCore}; | 9 | use rand_core::{CryptoRng, RngCore}; |
| 10 | 10 | ||
| 11 | use crate::interrupt::typelevel::Interrupt; | ||
| 11 | use crate::{interrupt, pac, peripherals, Peripheral}; | 12 | use crate::{interrupt, pac, peripherals, Peripheral}; |
| 12 | 13 | ||
| 13 | pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new(); | 14 | static RNG_WAKER: AtomicWaker = AtomicWaker::new(); |
| 14 | 15 | ||
| 15 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 16 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 16 | pub enum Error { | 17 | pub enum Error { |
| @@ -18,20 +19,38 @@ pub enum Error { | |||
| 18 | ClockError, | 19 | ClockError, |
| 19 | } | 20 | } |
| 20 | 21 | ||
| 22 | pub struct InterruptHandler<T: Instance> { | ||
| 23 | _phantom: PhantomData<T>, | ||
| 24 | } | ||
| 25 | |||
| 26 | impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> { | ||
| 27 | unsafe fn on_interrupt() { | ||
| 28 | let bits = T::regs().sr().read(); | ||
| 29 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 30 | T::regs().cr().modify(|reg| reg.set_ie(false)); | ||
| 31 | RNG_WAKER.wake(); | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 21 | pub struct Rng<'d, T: Instance> { | 36 | pub struct Rng<'d, T: Instance> { |
| 22 | _inner: PeripheralRef<'d, T>, | 37 | _inner: PeripheralRef<'d, T>, |
| 23 | } | 38 | } |
| 24 | 39 | ||
| 25 | impl<'d, T: Instance> Rng<'d, T> { | 40 | impl<'d, T: Instance> Rng<'d, T> { |
| 26 | pub fn new(inner: impl Peripheral<P = T> + 'd) -> Self { | 41 | pub fn new( |
| 42 | inner: impl Peripheral<P = T> + 'd, | ||
| 43 | _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd, | ||
| 44 | ) -> Self { | ||
| 27 | T::enable(); | 45 | T::enable(); |
| 28 | T::reset(); | 46 | T::reset(); |
| 29 | into_ref!(inner); | 47 | into_ref!(inner); |
| 30 | let mut random = Self { _inner: inner }; | 48 | let mut random = Self { _inner: inner }; |
| 31 | random.reset(); | 49 | random.reset(); |
| 32 | unsafe { | 50 | |
| 33 | interrupt::RNG.enable(); | 51 | T::Interrupt::unpend(); |
| 34 | } | 52 | unsafe { T::Interrupt::enable() }; |
| 53 | |||
| 35 | random | 54 | random |
| 36 | } | 55 | } |
| 37 | 56 | ||
| @@ -189,57 +208,20 @@ pub(crate) mod sealed { | |||
| 189 | } | 208 | } |
| 190 | } | 209 | } |
| 191 | 210 | ||
| 192 | pub trait Instance: sealed::Instance + crate::rcc::RccPeripheral {} | 211 | pub trait Instance: sealed::Instance + Peripheral<P = Self> + crate::rcc::RccPeripheral + 'static + Send { |
| 212 | type Interrupt: interrupt::typelevel::Interrupt; | ||
| 213 | } | ||
| 193 | 214 | ||
| 194 | foreach_peripheral!( | 215 | foreach_interrupt!( |
| 195 | (rng, $inst:ident) => { | 216 | ($inst:ident, rng, RNG, GLOBAL, $irq:ident) => { |
| 196 | impl Instance for peripherals::$inst {} | 217 | impl Instance for peripherals::$inst { |
| 218 | type Interrupt = crate::interrupt::typelevel::$irq; | ||
| 219 | } | ||
| 197 | 220 | ||
| 198 | impl sealed::Instance for peripherals::$inst { | 221 | impl sealed::Instance for peripherals::$inst { |
| 199 | fn regs() -> crate::pac::rng::Rng { | 222 | fn regs() -> crate::pac::rng::Rng { |
| 200 | crate::pac::RNG | 223 | crate::pac::$inst |
| 201 | } | ||
| 202 | } | ||
| 203 | }; | ||
| 204 | ); | ||
| 205 | |||
| 206 | #[cfg(feature = "rt")] | ||
| 207 | macro_rules! irq { | ||
| 208 | ($irq:ident) => { | ||
| 209 | mod rng_irq { | ||
| 210 | use crate::interrupt; | ||
| 211 | |||
| 212 | #[interrupt] | ||
| 213 | unsafe fn $irq() { | ||
| 214 | let bits = $crate::pac::RNG.sr().read(); | ||
| 215 | if bits.drdy() || bits.seis() || bits.ceis() { | ||
| 216 | $crate::pac::RNG.cr().modify(|reg| reg.set_ie(false)); | ||
| 217 | $crate::rng::RNG_WAKER.wake(); | ||
| 218 | } | ||
| 219 | } | 224 | } |
| 220 | } | 225 | } |
| 221 | }; | 226 | }; |
| 222 | } | ||
| 223 | |||
| 224 | #[cfg(feature = "rt")] | ||
| 225 | foreach_interrupt!( | ||
| 226 | (RNG) => { | ||
| 227 | irq!(RNG); | ||
| 228 | }; | ||
| 229 | |||
| 230 | (RNG_LPUART1) => { | ||
| 231 | irq!(RNG_LPUART1); | ||
| 232 | }; | ||
| 233 | |||
| 234 | (AES_RNG_LPUART1) => { | ||
| 235 | irq!(AES_RNG_LPUART1); | ||
| 236 | }; | ||
| 237 | |||
| 238 | (AES_RNG) => { | ||
| 239 | irq!(AES_RNG); | ||
| 240 | }; | ||
| 241 | |||
| 242 | (HASH_RNG) => { | ||
| 243 | irq!(HASH_RNG); | ||
| 244 | }; | ||
| 245 | ); | 227 | ); |
