From 6958091b500a1104a3d9d3a2737b9fe756f25702 Mon Sep 17 00:00:00 2001
From: Bob McWhirter <bmcwhirt@redhat.com>
Date: Thu, 3 Jun 2021 11:09:29 -0400
Subject: [PATCH] Move DAC, I2C, SPI and RNG to macro-tables.

---
 embassy-stm32/gen.py         | 66 ++++++++++++++++++------------------
 embassy-stm32/src/dac/mod.rs | 28 +++++++++------
 embassy-stm32/src/i2c/mod.rs | 28 ++++++++++-----
 embassy-stm32/src/rng.rs     | 55 ++++++++++++++++++++++++++++++
 embassy-stm32/src/spi/mod.rs | 41 ++++++++++++++++------
 stm32-metapac/build.rs       |  6 ++++
 6 files changed, 162 insertions(+), 62 deletions(-)

diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py
index bfb791945..e8645ccf9 100644
--- a/embassy-stm32/gen.py
+++ b/embassy-stm32/gen.py
@@ -63,32 +63,32 @@ with open(output_file, 'w') as f:
                     if (func := funcs.get(f'{name}_CK')) != None:
                         f.write(f'impl_usart_pin!({name}, CkPin, {pin}, {func});')
 
-        if block_mod == 'rng':
-            for irq in chip['interrupts']:
-                if re.search('RNG', irq):
-                    f.write(f'impl_rng!({name}, {irq});')
+        # if block_mod == 'rng':
+        #     for irq in chip['interrupts']:
+        #         if re.search('RNG', irq):
+        #             f.write(f'impl_rng!({name}, {irq});')
 
-        if block_mod == 'spi':
-            if 'clock' in peri:
-                clock = peri['clock']
-                f.write(f'impl_spi!({name}, {clock});')
-                for pin, funcs in af.items():
-                    if pin in pins:
-                        if (func := funcs.get(f'{name}_SCK')) != None:
-                            f.write(f'impl_spi_pin!({name}, SckPin, {pin}, {func});')
-                        if (func := funcs.get(f'{name}_MOSI')) != None:
-                            f.write(f'impl_spi_pin!({name}, MosiPin, {pin}, {func});')
-                        if (func := funcs.get(f'{name}_MISO')) != None:
-                            f.write(f'impl_spi_pin!({name}, MisoPin, {pin}, {func});')
+        # if block_mod == 'spi':
+        #     if 'clock' in peri:
+        #         clock = peri['clock']
+        #         f.write(f'impl_spi!({name}, {clock});')
+        #         for pin, funcs in af.items():
+        #             if pin in pins:
+        #                 if (func := funcs.get(f'{name}_SCK')) != None:
+        #                     f.write(f'impl_spi_pin!({name}, SckPin, {pin}, {func});')
+        #                 if (func := funcs.get(f'{name}_MOSI')) != None:
+        #                     f.write(f'impl_spi_pin!({name}, MosiPin, {pin}, {func});')
+        #                 if (func := funcs.get(f'{name}_MISO')) != None:
+        #                     f.write(f'impl_spi_pin!({name}, MisoPin, {pin}, {func});')
 
-        if block_mod == 'i2c':
-            f.write(f'impl_i2c!({name});')
-            for pin, funcs in af.items():
-                if pin in pins:
-                    if func := funcs.get(f'{name}_SCL'):
-                        f.write(f'impl_i2c_pin!({name}, SclPin, {pin}, {func});')
-                    if func := funcs.get(f'{name}_SDA'):
-                        f.write(f'impl_i2c_pin!({name}, SdaPin, {pin}, {func});')
+        # if block_mod == 'i2c':
+        #     f.write(f'impl_i2c!({name});')
+        #     for pin, funcs in af.items():
+        #         if pin in pins:
+        #             if func := funcs.get(f'{name}_SCL'):
+        #                 f.write(f'impl_i2c_pin!({name}, SclPin, {pin}, {func});')
+        #             if func := funcs.get(f'{name}_SDA'):
+        #                 f.write(f'impl_i2c_pin!({name}, SdaPin, {pin}, {func});')
 
         if block_mod == 'gpio':
             custom_singletons = True
@@ -145,15 +145,15 @@ with open(output_file, 'w') as f:
                 if re.match('EXTI', irq):
                     exti_interrupts.append(irq)
 
-        if block_mod == 'dac':
-            f.write(f'impl_dac!({name});')
-            if 'dac_out1' in peri:
-                pin = peri['dac_out1']
-                f.write(f'impl_dac_pin!({name}, 1, {pin});')
-            if 'dac_out2' in peri:
-                pin = peri['dac_out2']
-                f.write(f'impl_dac_pin!({name}, 2, {pin});')
-
+        # if block_mod == 'dac':
+        #     f.write(f'impl_dac!({name});')
+        #     if 'dac_out1' in peri:
+        #         pin = peri['dac_out1']
+        #         f.write(f'impl_dac_pin!({name}, 1, {pin});')
+        #     if 'dac_out2' in peri:
+        #         pin = peri['dac_out2']
+        #         f.write(f'impl_dac_pin!({name}, 2, {pin});')
+        #
         if not custom_singletons:
             singletons.append(name)
 
diff --git a/embassy-stm32/src/dac/mod.rs b/embassy-stm32/src/dac/mod.rs
index e1a603d40..46c485b35 100644
--- a/embassy-stm32/src/dac/mod.rs
+++ b/embassy-stm32/src/dac/mod.rs
@@ -3,6 +3,7 @@
 #[cfg_attr(dac_v2, path = "v2.rs")]
 mod _version;
 use crate::gpio::NoPin;
+use crate::peripherals;
 pub use _version::*;
 
 pub(crate) mod sealed {
@@ -23,8 +24,8 @@ pub trait DacPin<T: Instance, const C: u8>: sealed::DacPin<T, C> + 'static {}
 impl<T: Instance, const C: u8> DacPin<T, C> for NoPin {}
 impl<T: Instance, const C: u8> sealed::DacPin<T, C> for NoPin {}
 
-macro_rules! impl_dac {
-    ($inst:ident) => {
+crate::pac::peripherals!(
+    (dac, $inst:ident) => {
         impl crate::dac::sealed::Instance for peripherals::$inst {
             fn regs() -> &'static crate::pac::dac::Dac {
                 &crate::pac::$inst
@@ -33,16 +34,21 @@ macro_rules! impl_dac {
 
         impl crate::dac::Instance for peripherals::$inst {}
     };
-}
+);
 
-macro_rules! impl_dac_pin {
-    ($inst:ident, $channel:expr, $pin:ident ) => {
-        impl crate::dac::DacPin<peripherals::$inst, $channel> for peripherals::$pin {}
+crate::pac::peripheral_pins!(
+    ($inst:ident, dac, DAC, $pin:ident, OUT1) => {
+        impl DacPin<peripherals::$inst, 1> for peripherals::$pin {}
 
-        impl crate::dac::sealed::DacPin<peripherals::$inst, $channel> for peripherals::$pin {
-            //fn af_num(&self) -> u8 {
-            //$af
-            //}
+        impl sealed::DacPin<peripherals::$inst, 1> for peripherals::$pin {
+        }
+
+    };
+
+    ($inst:ident, dac, DAC, $pin:ident, OUT2) => {
+        impl DacPin<peripherals::$inst, 2> for peripherals::$pin {}
+
+        impl sealed::DacPin<peripherals::$inst, 2> for peripherals::$pin {
         }
     };
-}
+);
diff --git a/embassy-stm32/src/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs
index 7b0dd8160..f77e68600 100644
--- a/embassy-stm32/src/i2c/mod.rs
+++ b/embassy-stm32/src/i2c/mod.rs
@@ -3,6 +3,7 @@
 #[cfg_attr(i2c_v1, path = "v1.rs")]
 #[cfg_attr(i2c_v2, path = "v2.rs")]
 mod _version;
+use crate::peripherals;
 pub use _version::*;
 
 pub enum Error {
@@ -37,8 +38,8 @@ pub trait SclPin<T: Instance>: sealed::SclPin<T> + 'static {}
 
 pub trait SdaPin<T: Instance>: sealed::SdaPin<T> + 'static {}
 
-macro_rules! impl_i2c {
-    ($inst:ident) => {
+crate::pac::peripherals!(
+    (i2c, $inst:ident) => {
         impl crate::i2c::sealed::Instance for peripherals::$inst {
             fn regs() -> &'static crate::pac::i2c::I2c {
                 &crate::pac::$inst
@@ -46,17 +47,28 @@ macro_rules! impl_i2c {
         }
 
         impl crate::i2c::Instance for peripherals::$inst {}
+
     };
-}
+);
 
-macro_rules! impl_i2c_pin {
-    ($inst:ident, $pin_func:ident, $pin:ident, $af:expr) => {
-        impl crate::i2c::$pin_func<peripherals::$inst> for peripherals::$pin {}
+crate::pac::peripheral_pins!(
+    ($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => {
+        impl SdaPin<peripherals::$inst> for peripherals::$pin {}
 
-        impl crate::i2c::sealed::$pin_func<peripherals::$inst> for peripherals::$pin {
+        impl sealed::SdaPin<peripherals::$inst> for peripherals::$pin {
             fn af_num(&self) -> u8 {
                 $af
             }
         }
     };
-}
+
+    ($inst:ident, i2c, I2C, $pin:ident, SCL, $af:expr) => {
+        impl SclPin<peripherals::$inst> for peripherals::$pin {}
+
+        impl sealed::SclPin<peripherals::$inst> for peripherals::$pin {
+            fn af_num(&self) -> u8 {
+                $af
+            }
+        }
+    };
+);
diff --git a/embassy-stm32/src/rng.rs b/embassy-stm32/src/rng.rs
index 694ad4a1c..4dd26c671 100644
--- a/embassy-stm32/src/rng.rs
+++ b/embassy-stm32/src/rng.rs
@@ -9,6 +9,7 @@ use futures::future::poll_fn;
 use rand_core::{CryptoRng, RngCore};
 
 use crate::pac;
+use crate::peripherals;
 
 pub(crate) static RNG_WAKER: AtomicWaker = AtomicWaker::new();
 
@@ -134,6 +135,58 @@ pub(crate) mod sealed {
 
 pub trait Instance: sealed::Instance {}
 
+crate::pac::peripherals!(
+    (rng, $inst:ident) => {
+        impl Instance for peripherals::$inst {}
+
+        impl sealed::Instance for peripherals::$inst {
+            fn regs() -> crate::pac::rng::Rng {
+                crate::pac::RNG
+            }
+        }
+    };
+);
+
+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().write(|reg| reg.set_ie(false));
+                    $crate::rng::RNG_WAKER.wake();
+                }
+            }
+        }
+    };
+}
+
+crate::pac::interrupts!(
+    (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);
+    };
+);
+
+/*
 macro_rules! impl_rng {
     ($inst:ident, $irq:ident) => {
         impl crate::rng::sealed::Instance for peripherals::RNG {
@@ -158,3 +211,5 @@ macro_rules! impl_rng {
         }
     };
 }
+
+ */
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index d8bd66d9c..a888622de 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -4,6 +4,7 @@
 #[cfg_attr(spi_v2, path = "v2.rs")]
 #[cfg_attr(spi_v3, path = "v3.rs")]
 mod _version;
+use crate::peripherals;
 pub use _version::*;
 
 use crate::gpio::Pin;
@@ -71,26 +72,46 @@ pub trait MosiPin<T: Instance>: sealed::MosiPin<T> + 'static {}
 
 pub trait MisoPin<T: Instance>: sealed::MisoPin<T> + 'static {}
 
-macro_rules! impl_spi {
-    ($inst:ident, $clk:ident) => {
-        impl crate::spi::sealed::Instance for peripherals::$inst {
+crate::pac::peripherals!(
+    (spi, $inst:ident) => {
+        impl sealed::Instance for peripherals::$inst {
             fn regs() -> &'static crate::pac::spi::Spi {
                 &crate::pac::$inst
             }
         }
 
-        impl crate::spi::Instance for peripherals::$inst {}
+        impl Instance for peripherals::$inst {}
     };
-}
+);
 
-macro_rules! impl_spi_pin {
-    ($inst:ident, $pin_func:ident, $pin:ident, $af:expr) => {
-        impl crate::spi::$pin_func<peripherals::$inst> for peripherals::$pin {}
+crate::pac::peripheral_pins!(
+    ($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => {
+        impl SckPin<peripherals::$inst> for peripherals::$pin {}
 
-        impl crate::spi::sealed::$pin_func<peripherals::$inst> for peripherals::$pin {
+        impl sealed::SckPin<peripherals::$inst> for peripherals::$pin {
             fn af_num(&self) -> u8 {
                 $af
             }
         }
     };
-}
+
+    ($inst:ident, spi, SPI, $pin:ident, MOSI, $af:expr) => {
+        impl MosiPin<peripherals::$inst> for peripherals::$pin {}
+
+        impl sealed::MosiPin<peripherals::$inst> for peripherals::$pin {
+            fn af_num(&self) -> u8 {
+                $af
+            }
+        }
+    };
+
+    ($inst:ident, spi, SPI, $pin:ident, MISO, $af:expr) => {
+        impl MisoPin<peripherals::$inst> for peripherals::$pin {}
+
+        impl sealed::MisoPin<peripherals::$inst> for peripherals::$pin {
+            fn af_num(&self) -> u8 {
+                $af
+            }
+        }
+    };
+);
diff --git a/stm32-metapac/build.rs b/stm32-metapac/build.rs
index 046bc11f3..d33693f3c 100644
--- a/stm32-metapac/build.rs
+++ b/stm32-metapac/build.rs
@@ -135,6 +135,7 @@ fn main() {
     let mut cfgs: HashSet<String> = HashSet::new();
     let mut pin_table: Vec<Vec<String>> = Vec::new();
     let mut interrupt_table: Vec<Vec<String>> = Vec::new();
+    let mut peripherals_table: Vec<Vec<String>> = Vec::new();
     let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new();
 
     let dma_base = chip
@@ -178,6 +179,10 @@ fn main() {
 
             cfgs.insert(bi.module.clone());
             cfgs.insert(format!("{}_{}", bi.module, bi.version));
+            let mut peripheral_row = Vec::new();
+            peripheral_row.push( bi.module.clone() );
+            peripheral_row.push( name.clone() );
+            peripherals_table.push( peripheral_row );
 
             if let Some(old_version) =
             peripheral_versions.insert(bi.module.clone(), bi.version.clone())
@@ -253,6 +258,7 @@ fn main() {
 
     make_table(&mut extra, "pins", &pin_table);
     make_table(&mut extra, "interrupts", &interrupt_table);
+    make_table(&mut extra, "peripherals", &peripherals_table);
     make_table(&mut extra, "peripheral_versions", &peripheral_version_table);
     make_table(&mut extra, "peripheral_pins", &peripheral_pins_table);