aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-02-09 00:31:21 +0100
committerDario Nieuwenhuis <[email protected]>2022-02-09 00:31:21 +0100
commit940412c034cfc4d86557a3f4669dc9783e89ec22 (patch)
tree29461bdec8c41569db5dd31faa0173f4c670998b
parent4d73d87b40ae9530681c8d0461810aae85430669 (diff)
stm32/build.rs: switch to using stm32-metapac metadata and quote.
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs186
2 files changed, 88 insertions, 102 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index edee4e3a5..d1bdfae6b 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -35,7 +35,9 @@ seq-macro = "0.2.2"
35cfg-if = "1.0.0" 35cfg-if = "1.0.0"
36 36
37[build-dependencies] 37[build-dependencies]
38stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false } 38proc-macro2 = "1.0.36"
39quote = "1.0.15"
40stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false, features = ["metadata"]}
39 41
40[features] 42[features]
41sdmmc-rs = ["embedded-sdmmc"] 43sdmmc-rs = ["embedded-sdmmc"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index ff91f93de..c476420d2 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -1,8 +1,10 @@
1use std::collections::HashMap; 1use proc_macro2::TokenStream;
2use quote::{format_ident, quote};
3use std::collections::HashSet;
2use std::env; 4use std::env;
3use std::fmt::Write;
4use std::fs; 5use std::fs;
5use std::path::PathBuf; 6use std::path::PathBuf;
7use stm32_metapac::metadata::METADATA;
6 8
7fn main() { 9fn main() {
8 let chip_name = match env::vars() 10 let chip_name = match env::vars()
@@ -18,67 +20,50 @@ fn main() {
18 .unwrap() 20 .unwrap()
19 .to_ascii_lowercase(); 21 .to_ascii_lowercase();
20 22
21 struct Peripheral { 23 for p in METADATA.peripherals {
22 kind: String, 24 if let Some(r) = &p.registers {
23 name: String, 25 println!("cargo:rustc-cfg={}", r.kind);
24 version: String, 26 println!("cargo:rustc-cfg={}_{}", r.kind, r.version);
27 }
25 } 28 }
26 29
27 let mut peripheral_version_mapping = HashMap::<String, String>::new();
28 stm32_metapac::peripheral_versions!(
29 ($peri:ident, $version:ident) => {
30 peripheral_version_mapping.insert(stringify!($peri).to_string(), stringify!($version).to_string());
31 println!("cargo:rustc-cfg={}", stringify!($peri));
32 println!("cargo:rustc-cfg={}_{}", stringify!($peri), stringify!($version));
33 };
34 );
35
36 let mut peripherals: Vec<Peripheral> = Vec::new();
37 stm32_metapac::peripherals!(
38 ($kind:ident, $name:ident) => {
39 peripherals.push(Peripheral{
40 kind: stringify!($kind).to_string(),
41 name: stringify!($name).to_string(),
42 version: peripheral_version_mapping[&stringify!($kind).to_ascii_lowercase()].clone()
43 });
44 };
45 );
46
47 // ======== 30 // ========
48 // Generate singletons 31 // Generate singletons
49 32
50 let mut singletons: Vec<String> = Vec::new(); 33 let mut singletons: Vec<String> = Vec::new();
51 for p in peripherals { 34 for p in METADATA.peripherals {
52 match p.kind.as_str() { 35 if let Some(r) = &p.registers {
53 // Generate singletons per pin, not per port 36 match r.kind {
54 "gpio" => { 37 // Generate singletons per pin, not per port
55 println!("{}", p.name); 38 "gpio" => {
56 let port_letter = p.name.strip_prefix("GPIO").unwrap(); 39 println!("{}", p.name);
57 for pin_num in 0..16 { 40 let port_letter = p.name.strip_prefix("GPIO").unwrap();
58 singletons.push(format!("P{}{}", port_letter, pin_num)); 41 for pin_num in 0..16 {
42 singletons.push(format!("P{}{}", port_letter, pin_num));
43 }
59 } 44 }
60 }
61
62 // No singleton for these, the HAL handles them specially.
63 "exti" => {}
64 45
65 // We *shouldn't* have singletons for these, but the HAL currently requires 46 // No singleton for these, the HAL handles them specially.
66 // singletons, for using with RccPeripheral to enable/disable clocks to them. 47 "exti" => {}
67 "rcc" => { 48
68 if p.version == "h7" { 49 // We *shouldn't* have singletons for these, but the HAL currently requires
69 singletons.push("MCO1".to_string()); 50 // singletons, for using with RccPeripheral to enable/disable clocks to them.
70 singletons.push("MCO2".to_string()); 51 "rcc" => {
52 if r.version == "h7" {
53 singletons.push("MCO1".to_string());
54 singletons.push("MCO2".to_string());
55 }
56 singletons.push(p.name.to_string());
71 } 57 }
72 singletons.push(p.name.clone()); 58 //"dbgmcu" => {}
59 //"syscfg" => {}
60 //"dma" => {}
61 //"bdma" => {}
62 //"dmamux" => {}
63
64 // For other peripherals, one singleton per peri
65 _ => singletons.push(p.name.to_string()),
73 } 66 }
74 //"dbgmcu" => {}
75 //"syscfg" => {}
76 //"dma" => {}
77 //"bdma" => {}
78 //"dmamux" => {}
79
80 // For other peripherals, one singleton per peri
81 _ => singletons.push(p.name.clone()),
82 } 67 }
83 } 68 }
84 69
@@ -88,68 +73,67 @@ fn main() {
88 } 73 }
89 74
90 // One singleton per DMA channel 75 // One singleton per DMA channel
91 stm32_metapac::dma_channels! { 76 for c in METADATA.dma_channels {
92 ($channel_peri:ident, $dma_peri:ident, $version:ident, $channel_num:expr, $ignore:tt) => { 77 singletons.push(c.name.to_string());
93 singletons.push(stringify!($channel_peri).to_string());
94 };
95 } 78 }
96 79
97 let mut generated = String::new(); 80 let mut g = TokenStream::new();
98 write!( 81
99 &mut generated, 82 let singleton_tokens: Vec<_> = singletons.iter().map(|s| format_ident!("{}", s)).collect();
100 "embassy_hal_common::peripherals!({});\n", 83 g.extend(quote! {
101 singletons.join(",") 84 embassy_hal_common::peripherals!(#(#singleton_tokens),*);
102 ) 85 });
103 .unwrap();
104 86
105 // ======== 87 // ========
106 // Generate DMA IRQs. 88 // Generate DMA IRQs.
107 // This can't be done with macrotables alone because in many chips, one irq is shared between many
108 // channels, so we have to deduplicate them.
109
110 #[allow(unused_mut)]
111 let mut dma_irqs: Vec<String> = Vec::new();
112 #[allow(unused_mut)]
113 let mut bdma_irqs: Vec<String> = Vec::new();
114
115 stm32_metapac::interrupts! {
116 ($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => {
117 dma_irqs.push(stringify!($irq).to_string());
118 };
119 ($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => {
120 bdma_irqs.push(stringify!($irq).to_string());
121 };
122 }
123 89
124 dma_irqs.sort(); 90 let mut dma_irqs: HashSet<&str> = HashSet::new();
125 dma_irqs.dedup(); 91 let mut bdma_irqs: HashSet<&str> = HashSet::new();
126 bdma_irqs.sort();
127 bdma_irqs.dedup();
128
129 for irq in dma_irqs {
130 write!(
131 &mut generated,
132 "#[crate::interrupt] unsafe fn {} () {{ crate::dma::dma::on_irq(); }}\n",
133 irq
134 )
135 .unwrap();
136 }
137 92
138 for irq in bdma_irqs { 93 for p in METADATA.peripherals {
139 write!( 94 if let Some(r) = &p.registers {
140 &mut generated, 95 match r.kind {
141 "#[crate::interrupt] unsafe fn {} () {{ crate::dma::bdma::on_irq(); }}\n", 96 "dma" => {
142 irq 97 for irq in p.interrupts {
143 ) 98 dma_irqs.insert(irq.interrupt);
144 .unwrap(); 99 }
100 }
101 "bdma" => {
102 for irq in p.interrupts {
103 bdma_irqs.insert(irq.interrupt);
104 }
105 }
106 _ => {}
107 }
108 }
145 } 109 }
146 110
111 let tokens: Vec<_> = dma_irqs.iter().map(|s| format_ident!("{}", s)).collect();
112 g.extend(quote! {
113 #(
114 #[crate::interrupt]
115 unsafe fn #tokens () {
116 crate::dma::dma::on_irq();
117 }
118 )*
119 });
120
121 let tokens: Vec<_> = bdma_irqs.iter().map(|s| format_ident!("{}", s)).collect();
122 g.extend(quote! {
123 #(
124 #[crate::interrupt]
125 unsafe fn #tokens () {
126 crate::dma::bdma::on_irq();
127 }
128 )*
129 });
130
147 // ======== 131 // ========
148 // Write generated.rs 132 // Write generated.rs
149 133
150 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 134 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
151 let out_file = out_dir.join("generated.rs").to_string_lossy().to_string(); 135 let out_file = out_dir.join("generated.rs").to_string_lossy().to_string();
152 fs::write(out_file, &generated).unwrap(); 136 fs::write(out_file, g.to_string()).unwrap();
153 137
154 // ======== 138 // ========
155 // Multicore 139 // Multicore