From 8160af6af99573d3ef66aede8c4b0aac033b0ff3 Mon Sep 17 00:00:00 2001
From: Dario Nieuwenhuis <dirbaio@dirbaio.net>
Date: Wed, 9 Feb 2022 00:58:17 +0100
Subject: [PATCH] stm32: replace `peripheral_rcc!` macrotable with build.rs

---
 embassy-stm32/build.rs          | 85 +++++++++++++++++++++++++++++++++
 embassy-stm32/src/dma/bdma.rs   |  7 +--
 embassy-stm32/src/dma/dma.rs    |  7 +--
 embassy-stm32/src/dma/dmamux.rs |  8 +---
 embassy-stm32/src/gpio.rs       |  8 +---
 embassy-stm32/src/rcc/mod.rs    | 64 -------------------------
 stm32-metapac-gen/src/lib.rs    | 30 ------------
 7 files changed, 89 insertions(+), 120 deletions(-)

diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 8889b0d01..404fb7e1f 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -145,6 +145,91 @@ fn main() {
         )*
     });
 
+    // ========
+    // Generate RccPeripheral impls
+
+    for p in METADATA.peripherals {
+        if !singletons.contains(&p.name.to_string()) {
+            continue;
+        }
+
+        if let Some(rcc) = &p.rcc {
+            let en = rcc.enable.as_ref().unwrap();
+
+            let rst = match &rcc.reset {
+                Some(rst) => {
+                    let rst_reg = format_ident!("{}", rst.register.to_ascii_lowercase());
+                    let set_rst_field = format_ident!("set_{}", rst.field.to_ascii_lowercase());
+                    quote! {
+                        critical_section::with(|_| unsafe {
+                            crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(true));
+                            crate::pac::RCC.#rst_reg().modify(|w| w.#set_rst_field(false));
+                        });
+                    }
+                }
+                None => TokenStream::new(),
+            };
+
+            let pname = format_ident!("{}", p.name);
+            let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase());
+            let en_reg = format_ident!("{}", en.register.to_ascii_lowercase());
+            let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase());
+
+            g.extend(quote! {
+                impl crate::rcc::sealed::RccPeripheral for peripherals::#pname {
+                    fn frequency() -> crate::time::Hertz {
+                        critical_section::with(|_| unsafe {
+                            crate::rcc::get_freqs().#clk
+                        })
+                    }
+                    fn enable() {
+                        critical_section::with(|_| unsafe {
+                            crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true))
+                        })
+                    }
+                    fn disable() {
+                        critical_section::with(|_| unsafe {
+                            crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false));
+                        })
+                    }
+                    fn reset() {
+                        #rst
+                    }
+                }
+
+                impl crate::rcc::RccPeripheral for peripherals::#pname {}
+            });
+        }
+    }
+
+    // ========
+    // Generate fns to enable GPIO, DMA in RCC
+
+    for kind in ["dma", "bdma", "dmamux", "gpio"] {
+        let mut gg = TokenStream::new();
+
+        for p in METADATA.peripherals {
+            if p.registers.is_some() && p.registers.as_ref().unwrap().kind == kind {
+                if let Some(rcc) = &p.rcc {
+                    let en = rcc.enable.as_ref().unwrap();
+                    let en_reg = format_ident!("{}", en.register.to_ascii_lowercase());
+                    let set_en_field = format_ident!("set_{}", en.field.to_ascii_lowercase());
+
+                    gg.extend(quote! {
+                        crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(true));
+                    })
+                }
+            }
+        }
+
+        let fname = format_ident!("init_{}", kind);
+        g.extend(quote! {
+            pub unsafe fn #fname(){
+                #gg
+            }
+        })
+    }
+
     // ========
     // Write generated.rs
 
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index ebb0467dc..a37de2d63 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -9,7 +9,6 @@ use embassy::waitqueue::AtomicWaker;
 use crate::dma::Request;
 use crate::pac;
 use crate::pac::bdma::vals;
-use crate::rcc::sealed::RccPeripheral;
 
 use super::{Word, WordSize};
 
@@ -77,11 +76,7 @@ pub(crate) unsafe fn init() {
             crate::interrupt::$irq::steal().enable();
         };
     }
-    pac::peripherals! {
-        (bdma, $peri:ident) => {
-            crate::peripherals::$peri::enable();
-        };
-    }
+    crate::generated::init_bdma();
 }
 
 pac::dma_channels! {
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index 21623b90c..c885452b0 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -7,7 +7,6 @@ use embassy::waitqueue::AtomicWaker;
 use crate::interrupt;
 use crate::pac;
 use crate::pac::dma::{regs, vals};
-use crate::rcc::sealed::RccPeripheral;
 
 use super::{Request, Word, WordSize};
 
@@ -74,11 +73,7 @@ pub(crate) unsafe fn init() {
             interrupt::$irq::steal().enable();
         };
     }
-    pac::peripherals! {
-        (dma, $peri:ident) => {
-            crate::peripherals::$peri::enable();
-        };
-    }
+    crate::generated::init_dma();
 }
 
 pac::dma_channels! {
diff --git a/embassy-stm32/src/dma/dmamux.rs b/embassy-stm32/src/dma/dmamux.rs
index 83dcff4e8..fd076581b 100644
--- a/embassy-stm32/src/dma/dmamux.rs
+++ b/embassy-stm32/src/dma/dmamux.rs
@@ -49,11 +49,5 @@ pac::dma_channels! {
 
 /// safety: must be called only once
 pub(crate) unsafe fn init() {
-    crate::pac::peripheral_rcc! {
-        ($name:ident, dmamux, DMAMUX, $clock:ident, ($reg:ident, $field:ident, $set_field:ident), $rst:tt) => {
-            crate::pac::RCC.$reg().modify(|reg| {
-                reg.$set_field(true);
-            });
-        };
-    }
+    crate::generated::init_dmamux();
 }
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index d4606716c..f154a66c4 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -608,13 +608,7 @@ crate::pac::pins!(
 );
 
 pub(crate) unsafe fn init() {
-    crate::pac::peripheral_rcc! {
-        ($name:ident, gpio, GPIO, $clock:ident, ($reg:ident, $field:ident, $set_field:ident), $rst:tt) => {
-            crate::pac::RCC.$reg().modify(|reg| {
-                reg.$set_field(true);
-            });
-        };
-    }
+    crate::generated::init_gpio();
 }
 
 mod eh02 {
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs
index 541d9c148..3aab01afd 100644
--- a/embassy-stm32/src/rcc/mod.rs
+++ b/embassy-stm32/src/rcc/mod.rs
@@ -1,6 +1,5 @@
 #![macro_use]
 
-use crate::peripherals;
 use crate::time::Hertz;
 use core::mem::MaybeUninit;
 
@@ -104,66 +103,3 @@ pub(crate) mod sealed {
 }
 
 pub trait RccPeripheral: sealed::RccPeripheral + 'static {}
-
-crate::pac::peripheral_rcc!(
-    ($inst:ident, gpio, GPIO, $clk:ident, $en:tt, $rst:tt) => {};
-    ($inst:ident, $module:ident, $block:ident, $clk:ident, ($en_reg:ident, $en_field:ident, $en_set_field:ident), ($rst_reg:ident, $rst_field:ident, $rst_set_field:ident)) => {
-        impl sealed::RccPeripheral for peripherals::$inst {
-            fn frequency() -> crate::time::Hertz {
-                critical_section::with(|_| {
-                    unsafe { get_freqs().$clk }
-                })
-            }
-            fn enable() {
-                critical_section::with(|_| {
-                    unsafe {
-                        crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(true));
-                    }
-                })
-            }
-            fn disable() {
-                critical_section::with(|_| {
-                    unsafe {
-                        crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(false));
-                    }
-                })
-            }
-            fn reset() {
-                critical_section::with(|_| {
-                    unsafe {
-                        crate::pac::RCC.$rst_reg().modify(|w| w.$rst_set_field(true));
-                        crate::pac::RCC.$rst_reg().modify(|w| w.$rst_set_field(false));
-                    }
-                })
-            }
-        }
-
-        impl RccPeripheral for peripherals::$inst {}
-    };
-    ($inst:ident, $module:ident, $block:ident, $clk:ident, ($en_reg:ident, $en_field:ident, $en_set_field:ident), _) => {
-        impl sealed::RccPeripheral for peripherals::$inst {
-            fn frequency() -> crate::time::Hertz {
-                critical_section::with(|_| {
-                    unsafe { get_freqs().$clk }
-                })
-            }
-            fn enable() {
-                critical_section::with(|_| {
-                    unsafe {
-                        crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(true));
-                    }
-                })
-            }
-            fn disable() {
-                critical_section::with(|_| {
-                    unsafe {
-                        crate::pac::RCC.$en_reg().modify(|w| w.$en_set_field(false));
-                    }
-                })
-            }
-            fn reset() {}
-        }
-
-        impl RccPeripheral for peripherals::$inst {}
-    };
-);
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index ccf737eff..10d67869a 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -126,7 +126,6 @@ pub fn gen_chip(
     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 mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new();
     let mut dma_channels_table: Vec<Vec<String>> = Vec::new();
     let mut peripheral_dma_channels_table: Vec<Vec<String>> = Vec::new();
     let mut peripheral_counts: BTreeMap<String, u8> = BTreeMap::new();
@@ -264,34 +263,6 @@ pub fn gen_chip(
                 }
                 _ => {}
             }
-
-            if let Some(rcc) = &p.rcc {
-                let mut clock = rcc.clock.to_ascii_lowercase();
-                if p.name.starts_with("TIM") {
-                    clock = format!("{}_tim", clock)
-                }
-
-                let mut row = Vec::new();
-                row.push(p.name.clone());
-                row.push(bi.kind.clone());
-                row.push(bi.block.clone());
-                row.push(clock);
-
-                for reg in [&rcc.enable, &rcc.reset] {
-                    if let Some(reg) = reg {
-                        row.push(format!(
-                            "({}, {}, set_{})",
-                            reg.register.to_ascii_lowercase(),
-                            reg.field.to_ascii_lowercase(),
-                            reg.field.to_ascii_lowercase()
-                        ));
-                    } else {
-                        row.push("_".to_string())
-                    }
-                }
-
-                peripheral_rcc_table.push(row);
-            }
         }
 
         dev.peripherals.push(ir_peri);
@@ -422,7 +393,6 @@ pub fn gen_chip(
         "peripheral_dma_channels",
         &peripheral_dma_channels_table,
     );
-    make_table(&mut data, "peripheral_rcc", &peripheral_rcc_table);
     make_table(&mut data, "dma_channels", &dma_channels_table);
     make_table(&mut data, "dbgmcu", &dbgmcu_table);
     make_peripheral_counts(&mut data, &peripheral_counts);