From 13873df30b6fc2cdb0520ecd706a4f00e6afc528 Mon Sep 17 00:00:00 2001
From: Bob McWhirter <bmcwhirt@redhat.com>
Date: Thu, 22 Jul 2021 14:38:45 -0400
Subject: [PATCH 1/2] Auto-enable all GPIOs during init().

---
 embassy-stm32/src/gpio.rs             | 10 ++++++
 embassy-stm32/src/lib.rs              |  1 +
 examples/stm32h7/src/bin/usart_dma.rs | 12 -------
 stm32-metapac-gen/src/lib.rs          | 47 +++++++++++++++------------
 4 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index bf8400ca9..09f241faa 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -449,3 +449,13 @@ crate::pac::pins!(
         }
     };
 );
+
+pub(crate) unsafe fn init() {
+    crate::pac::gpio_rcc! {
+        ($name:ident, $clock:ident, $en_reg:ident, $rst_reg:ident, $en_fn:ident, $rst_fn:ident) => {
+            crate::pac::RCC.$en_reg().modify(|reg| {
+                reg.$en_fn(true);
+            });
+        };
+    }
+}
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs
index 07f8b9f3b..89fd86448 100644
--- a/embassy-stm32/src/lib.rs
+++ b/embassy-stm32/src/lib.rs
@@ -89,6 +89,7 @@ pub fn init(config: Config) -> Peripherals {
     let p = Peripherals::take();
 
     unsafe {
+        gpio::init();
         dma::init();
         #[cfg(exti)]
         exti::init();
diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs
index 097466cea..907356500 100644
--- a/examples/stm32h7/src/bin/usart_dma.rs
+++ b/examples/stm32h7/src/bin/usart_dma.rs
@@ -71,22 +71,10 @@ fn main() -> ! {
         .pll1_q_ck(48.mhz())
         .freeze(pwrcfg, &pp.SYSCFG);
 
-    let pp = unsafe { pac::Peripherals::steal() };
-
     unsafe {
         Dbgmcu::enable_all();
     }
 
-    pp.RCC.ahb4enr.modify(|_, w| {
-        w.gpioaen().set_bit();
-        w.gpioben().set_bit();
-        w.gpiocen().set_bit();
-        w.gpioden().set_bit();
-        w.gpioeen().set_bit();
-        w.gpiofen().set_bit();
-        w
-    });
-
     unsafe { embassy::time::set_clock(&ZeroClock) };
 
     let executor = EXECUTOR.put(Executor::new());
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index bfc2384cd..1c7ac38ee 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -287,6 +287,7 @@ pub fn gen(options: Options) {
         let mut peripheral_counts: HashMap<String, u8> = HashMap::new();
         let mut dma_channel_counts: HashMap<String, u8> = HashMap::new();
         let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
+        let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
 
         let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address;
         let gpio_stride = 0x400;
@@ -465,29 +466,32 @@ pub fn gen(options: Options) {
                                     clock.to_ascii_lowercase()
                                 };
 
-                                if !name.starts_with("GPIO") {
-                                    let mut row = Vec::with_capacity(6);
-                                    row.push(name.clone());
-                                    row.push(clock);
-                                    row.push(enable_reg.to_ascii_lowercase());
+                                let mut row = Vec::with_capacity(6);
+                                row.push(name.clone());
+                                row.push(clock);
+                                row.push(enable_reg.to_ascii_lowercase());
 
-                                    if let Some((reset_reg, reset_field)) = reset_reg_field {
-                                        row.push(reset_reg.to_ascii_lowercase());
-                                        row.push(format!(
-                                            "set_{}",
-                                            enable_field.to_ascii_lowercase()
-                                        ));
-                                        row.push(format!(
-                                            "set_{}",
-                                            reset_field.to_ascii_lowercase()
-                                        ));
-                                    } else {
-                                        row.push(format!(
-                                            "set_{}",
-                                            enable_field.to_ascii_lowercase()
-                                        ));
-                                    }
+                                if let Some((reset_reg, reset_field)) = reset_reg_field {
+                                    row.push(reset_reg.to_ascii_lowercase());
+                                    row.push(format!(
+                                        "set_{}",
+                                        enable_field.to_ascii_lowercase()
+                                    ));
+                                    row.push(format!(
+                                        "set_{}",
+                                        reset_field.to_ascii_lowercase()
+                                    ));
+                                } else {
+                                    row.push(format!(
+                                        "set_{}",
+                                        enable_field.to_ascii_lowercase()
+                                    ));
+                                }
+
+                                if !name.starts_with("GPIO") {
                                     peripheral_rcc_table.push(row);
+                                } else {
+                                    gpio_rcc_table.push(row);
                                 }
                             }
                             (None, Some(_)) => {
@@ -586,6 +590,7 @@ pub fn gen(options: Options) {
             &peripheral_dma_channels_table,
         );
         make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table);
+        make_table(&mut extra, "gpio_rcc", &gpio_rcc_table);
         make_table(&mut extra, "dma_channels", &dma_channels_table);
         make_table(&mut extra, "dbgmcu", &dbgmcu_table);
         make_peripheral_counts(&mut extra, &peripheral_counts);

From 650f867b1cb364a514d9e5145b0244bb7223c387 Mon Sep 17 00:00:00 2001
From: Bob McWhirter <bmcwhirt@redhat.com>
Date: Fri, 23 Jul 2021 11:16:17 -0400
Subject: [PATCH 2/2] Add a single-column variant to gpio_rcc! macro table
 which includes just the set of registers that need to be considered.

Then match against those registers with a single `modify(...)`
---
 embassy-stm32/src/gpio.rs    | 8 ++++++--
 stm32-metapac-gen/src/lib.rs | 6 ++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs
index 09f241faa..5145bd689 100644
--- a/embassy-stm32/src/gpio.rs
+++ b/embassy-stm32/src/gpio.rs
@@ -452,9 +452,13 @@ crate::pac::pins!(
 
 pub(crate) unsafe fn init() {
     crate::pac::gpio_rcc! {
-        ($name:ident, $clock:ident, $en_reg:ident, $rst_reg:ident, $en_fn:ident, $rst_fn:ident) => {
+        ($en_reg:ident) => {
             crate::pac::RCC.$en_reg().modify(|reg| {
-                reg.$en_fn(true);
+                crate::pac::gpio_rcc! {
+                    ($name:ident, $clock:ident, $en_reg, $rst_reg:ident, $en_fn:ident, $rst_fn:ident) => {
+                        reg.$en_fn(true);
+                    };
+                }
             });
         };
     }
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index 1c7ac38ee..203d943de 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -288,6 +288,7 @@ pub fn gen(options: Options) {
         let mut dma_channel_counts: HashMap<String, u8> = HashMap::new();
         let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
         let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
+        let mut gpio_regs: HashSet<String> = HashSet::new();
 
         let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address;
         let gpio_stride = 0x400;
@@ -492,6 +493,7 @@ pub fn gen(options: Options) {
                                     peripheral_rcc_table.push(row);
                                 } else {
                                     gpio_rcc_table.push(row);
+                                    gpio_regs.insert( enable_reg.to_ascii_lowercase() );
                                 }
                             }
                             (None, Some(_)) => {
@@ -508,6 +510,10 @@ pub fn gen(options: Options) {
             dev.peripherals.push(ir_peri);
         }
 
+        for reg in gpio_regs {
+            gpio_rcc_table.push( vec!( reg ) );
+        }
+
         for (id, channel_info) in &core.dma_channels {
             let mut row = Vec::new();
             let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();