aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-11-23 23:49:06 +0100
committerDario Nieuwenhuis <[email protected]>2021-11-23 23:49:06 +0100
commitdfb6d407a1b23f913b7584611099042f36144c5c (patch)
treef132b6908f9adda329a48b44d6e9afc0f7171437
parent039621c56de5518b178da8749fc0c9870f8a6b45 (diff)
stm32: rename core features from _cmX to -cmX, cleanup gen.
-rwxr-xr-xci.sh2
-rw-r--r--embassy-stm32/Cargo.toml116
-rw-r--r--examples/stm32wl55/Cargo.toml2
-rw-r--r--stm32-gen-features/src/lib.rs2
-rw-r--r--stm32-metapac-gen/src/assets/build.rs32
-rw-r--r--stm32-metapac-gen/src/lib.rs834
-rw-r--r--stm32-metapac-gen/src/main.rs1
-rw-r--r--stm32-metapac/Cargo.toml124
-rw-r--r--stm32-metapac/build.rs36
9 files changed, 565 insertions, 584 deletions
diff --git a/ci.sh b/ci.sh
index 601123863..a3b7d804f 100755
--- a/ci.sh
+++ b/ci.sh
@@ -28,7 +28,7 @@ cargo batch \
28 --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt \ 28 --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt \
29 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt \ 29 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt \
30 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log \ 30 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log \
31 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi_cm7,defmt \ 31 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt \
32 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt \ 32 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt \
33 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt \ 33 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt \
34 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt \ 34 --- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt \
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index f074a6b05..9885c589f 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -615,40 +615,40 @@ stm32h743xg = [ "stm32-metapac/stm32h743xg" ]
615stm32h743xi = [ "stm32-metapac/stm32h743xi" ] 615stm32h743xi = [ "stm32-metapac/stm32h743xi" ]
616stm32h743zg = [ "stm32-metapac/stm32h743zg" ] 616stm32h743zg = [ "stm32-metapac/stm32h743zg" ]
617stm32h743zi = [ "stm32-metapac/stm32h743zi" ] 617stm32h743zi = [ "stm32-metapac/stm32h743zi" ]
618stm32h745bg_cm7 = [ "stm32-metapac/stm32h745bg_cm7" ] 618stm32h745bg-cm7 = [ "stm32-metapac/stm32h745bg-cm7" ]
619stm32h745bg_cm4 = [ "stm32-metapac/stm32h745bg_cm4" ] 619stm32h745bg-cm4 = [ "stm32-metapac/stm32h745bg-cm4" ]
620stm32h745bi_cm7 = [ "stm32-metapac/stm32h745bi_cm7" ] 620stm32h745bi-cm7 = [ "stm32-metapac/stm32h745bi-cm7" ]
621stm32h745bi_cm4 = [ "stm32-metapac/stm32h745bi_cm4" ] 621stm32h745bi-cm4 = [ "stm32-metapac/stm32h745bi-cm4" ]
622stm32h745ig_cm7 = [ "stm32-metapac/stm32h745ig_cm7" ] 622stm32h745ig-cm7 = [ "stm32-metapac/stm32h745ig-cm7" ]
623stm32h745ig_cm4 = [ "stm32-metapac/stm32h745ig_cm4" ] 623stm32h745ig-cm4 = [ "stm32-metapac/stm32h745ig-cm4" ]
624stm32h745ii_cm7 = [ "stm32-metapac/stm32h745ii_cm7" ] 624stm32h745ii-cm7 = [ "stm32-metapac/stm32h745ii-cm7" ]
625stm32h745ii_cm4 = [ "stm32-metapac/stm32h745ii_cm4" ] 625stm32h745ii-cm4 = [ "stm32-metapac/stm32h745ii-cm4" ]
626stm32h745xg_cm7 = [ "stm32-metapac/stm32h745xg_cm7" ] 626stm32h745xg-cm7 = [ "stm32-metapac/stm32h745xg-cm7" ]
627stm32h745xg_cm4 = [ "stm32-metapac/stm32h745xg_cm4" ] 627stm32h745xg-cm4 = [ "stm32-metapac/stm32h745xg-cm4" ]
628stm32h745xi_cm7 = [ "stm32-metapac/stm32h745xi_cm7" ] 628stm32h745xi-cm7 = [ "stm32-metapac/stm32h745xi-cm7" ]
629stm32h745xi_cm4 = [ "stm32-metapac/stm32h745xi_cm4" ] 629stm32h745xi-cm4 = [ "stm32-metapac/stm32h745xi-cm4" ]
630stm32h745zg_cm7 = [ "stm32-metapac/stm32h745zg_cm7" ] 630stm32h745zg-cm7 = [ "stm32-metapac/stm32h745zg-cm7" ]
631stm32h745zg_cm4 = [ "stm32-metapac/stm32h745zg_cm4" ] 631stm32h745zg-cm4 = [ "stm32-metapac/stm32h745zg-cm4" ]
632stm32h745zi_cm7 = [ "stm32-metapac/stm32h745zi_cm7" ] 632stm32h745zi-cm7 = [ "stm32-metapac/stm32h745zi-cm7" ]
633stm32h745zi_cm4 = [ "stm32-metapac/stm32h745zi_cm4" ] 633stm32h745zi-cm4 = [ "stm32-metapac/stm32h745zi-cm4" ]
634stm32h747ag_cm7 = [ "stm32-metapac/stm32h747ag_cm7" ] 634stm32h747ag-cm7 = [ "stm32-metapac/stm32h747ag-cm7" ]
635stm32h747ag_cm4 = [ "stm32-metapac/stm32h747ag_cm4" ] 635stm32h747ag-cm4 = [ "stm32-metapac/stm32h747ag-cm4" ]
636stm32h747ai_cm7 = [ "stm32-metapac/stm32h747ai_cm7" ] 636stm32h747ai-cm7 = [ "stm32-metapac/stm32h747ai-cm7" ]
637stm32h747ai_cm4 = [ "stm32-metapac/stm32h747ai_cm4" ] 637stm32h747ai-cm4 = [ "stm32-metapac/stm32h747ai-cm4" ]
638stm32h747bg_cm7 = [ "stm32-metapac/stm32h747bg_cm7" ] 638stm32h747bg-cm7 = [ "stm32-metapac/stm32h747bg-cm7" ]
639stm32h747bg_cm4 = [ "stm32-metapac/stm32h747bg_cm4" ] 639stm32h747bg-cm4 = [ "stm32-metapac/stm32h747bg-cm4" ]
640stm32h747bi_cm7 = [ "stm32-metapac/stm32h747bi_cm7" ] 640stm32h747bi-cm7 = [ "stm32-metapac/stm32h747bi-cm7" ]
641stm32h747bi_cm4 = [ "stm32-metapac/stm32h747bi_cm4" ] 641stm32h747bi-cm4 = [ "stm32-metapac/stm32h747bi-cm4" ]
642stm32h747ig_cm7 = [ "stm32-metapac/stm32h747ig_cm7" ] 642stm32h747ig-cm7 = [ "stm32-metapac/stm32h747ig-cm7" ]
643stm32h747ig_cm4 = [ "stm32-metapac/stm32h747ig_cm4" ] 643stm32h747ig-cm4 = [ "stm32-metapac/stm32h747ig-cm4" ]
644stm32h747ii_cm7 = [ "stm32-metapac/stm32h747ii_cm7" ] 644stm32h747ii-cm7 = [ "stm32-metapac/stm32h747ii-cm7" ]
645stm32h747ii_cm4 = [ "stm32-metapac/stm32h747ii_cm4" ] 645stm32h747ii-cm4 = [ "stm32-metapac/stm32h747ii-cm4" ]
646stm32h747xg_cm7 = [ "stm32-metapac/stm32h747xg_cm7" ] 646stm32h747xg-cm7 = [ "stm32-metapac/stm32h747xg-cm7" ]
647stm32h747xg_cm4 = [ "stm32-metapac/stm32h747xg_cm4" ] 647stm32h747xg-cm4 = [ "stm32-metapac/stm32h747xg-cm4" ]
648stm32h747xi_cm7 = [ "stm32-metapac/stm32h747xi_cm7" ] 648stm32h747xi-cm7 = [ "stm32-metapac/stm32h747xi-cm7" ]
649stm32h747xi_cm4 = [ "stm32-metapac/stm32h747xi_cm4" ] 649stm32h747xi-cm4 = [ "stm32-metapac/stm32h747xi-cm4" ]
650stm32h747zi_cm7 = [ "stm32-metapac/stm32h747zi_cm7" ] 650stm32h747zi-cm7 = [ "stm32-metapac/stm32h747zi-cm7" ]
651stm32h747zi_cm4 = [ "stm32-metapac/stm32h747zi_cm4" ] 651stm32h747zi-cm4 = [ "stm32-metapac/stm32h747zi-cm4" ]
652stm32h750ib = [ "stm32-metapac/stm32h750ib" ] 652stm32h750ib = [ "stm32-metapac/stm32h750ib" ]
653stm32h750vb = [ "stm32-metapac/stm32h750vb" ] 653stm32h750vb = [ "stm32-metapac/stm32h750vb" ]
654stm32h750xb = [ "stm32-metapac/stm32h750xb" ] 654stm32h750xb = [ "stm32-metapac/stm32h750xb" ]
@@ -659,24 +659,24 @@ stm32h753ii = [ "stm32-metapac/stm32h753ii" ]
659stm32h753vi = [ "stm32-metapac/stm32h753vi" ] 659stm32h753vi = [ "stm32-metapac/stm32h753vi" ]
660stm32h753xi = [ "stm32-metapac/stm32h753xi" ] 660stm32h753xi = [ "stm32-metapac/stm32h753xi" ]
661stm32h753zi = [ "stm32-metapac/stm32h753zi" ] 661stm32h753zi = [ "stm32-metapac/stm32h753zi" ]
662stm32h755bi_cm7 = [ "stm32-metapac/stm32h755bi_cm7" ] 662stm32h755bi-cm7 = [ "stm32-metapac/stm32h755bi-cm7" ]
663stm32h755bi_cm4 = [ "stm32-metapac/stm32h755bi_cm4" ] 663stm32h755bi-cm4 = [ "stm32-metapac/stm32h755bi-cm4" ]
664stm32h755ii_cm7 = [ "stm32-metapac/stm32h755ii_cm7" ] 664stm32h755ii-cm7 = [ "stm32-metapac/stm32h755ii-cm7" ]
665stm32h755ii_cm4 = [ "stm32-metapac/stm32h755ii_cm4" ] 665stm32h755ii-cm4 = [ "stm32-metapac/stm32h755ii-cm4" ]
666stm32h755xi_cm7 = [ "stm32-metapac/stm32h755xi_cm7" ] 666stm32h755xi-cm7 = [ "stm32-metapac/stm32h755xi-cm7" ]
667stm32h755xi_cm4 = [ "stm32-metapac/stm32h755xi_cm4" ] 667stm32h755xi-cm4 = [ "stm32-metapac/stm32h755xi-cm4" ]
668stm32h755zi_cm7 = [ "stm32-metapac/stm32h755zi_cm7" ] 668stm32h755zi-cm7 = [ "stm32-metapac/stm32h755zi-cm7" ]
669stm32h755zi_cm4 = [ "stm32-metapac/stm32h755zi_cm4" ] 669stm32h755zi-cm4 = [ "stm32-metapac/stm32h755zi-cm4" ]
670stm32h757ai_cm7 = [ "stm32-metapac/stm32h757ai_cm7" ] 670stm32h757ai-cm7 = [ "stm32-metapac/stm32h757ai-cm7" ]
671stm32h757ai_cm4 = [ "stm32-metapac/stm32h757ai_cm4" ] 671stm32h757ai-cm4 = [ "stm32-metapac/stm32h757ai-cm4" ]
672stm32h757bi_cm7 = [ "stm32-metapac/stm32h757bi_cm7" ] 672stm32h757bi-cm7 = [ "stm32-metapac/stm32h757bi-cm7" ]
673stm32h757bi_cm4 = [ "stm32-metapac/stm32h757bi_cm4" ] 673stm32h757bi-cm4 = [ "stm32-metapac/stm32h757bi-cm4" ]
674stm32h757ii_cm7 = [ "stm32-metapac/stm32h757ii_cm7" ] 674stm32h757ii-cm7 = [ "stm32-metapac/stm32h757ii-cm7" ]
675stm32h757ii_cm4 = [ "stm32-metapac/stm32h757ii_cm4" ] 675stm32h757ii-cm4 = [ "stm32-metapac/stm32h757ii-cm4" ]
676stm32h757xi_cm7 = [ "stm32-metapac/stm32h757xi_cm7" ] 676stm32h757xi-cm7 = [ "stm32-metapac/stm32h757xi-cm7" ]
677stm32h757xi_cm4 = [ "stm32-metapac/stm32h757xi_cm4" ] 677stm32h757xi-cm4 = [ "stm32-metapac/stm32h757xi-cm4" ]
678stm32h757zi_cm7 = [ "stm32-metapac/stm32h757zi_cm7" ] 678stm32h757zi-cm7 = [ "stm32-metapac/stm32h757zi-cm7" ]
679stm32h757zi_cm4 = [ "stm32-metapac/stm32h757zi_cm4" ] 679stm32h757zi-cm4 = [ "stm32-metapac/stm32h757zi-cm4" ]
680stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ] 680stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ]
681stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ] 681stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ]
682stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ] 682stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ]
@@ -1066,10 +1066,10 @@ stm32wb55vc = [ "stm32-metapac/stm32wb55vc" ]
1066stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ] 1066stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ]
1067stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ] 1067stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ]
1068stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ] 1068stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ]
1069stm32wl55cc_cm4 = [ "stm32-metapac/stm32wl55cc_cm4" ] 1069stm32wl55cc-cm4 = [ "stm32-metapac/stm32wl55cc-cm4" ]
1070stm32wl55cc_cm0p = [ "stm32-metapac/stm32wl55cc_cm0p" ] 1070stm32wl55cc-cm0p = [ "stm32-metapac/stm32wl55cc-cm0p" ]
1071stm32wl55jc_cm4 = [ "stm32-metapac/stm32wl55jc_cm4" ] 1071stm32wl55jc-cm4 = [ "stm32-metapac/stm32wl55jc-cm4" ]
1072stm32wl55jc_cm0p = [ "stm32-metapac/stm32wl55jc_cm0p" ] 1072stm32wl55jc-cm0p = [ "stm32-metapac/stm32wl55jc-cm0p" ]
1073stm32wl55uc_cm4 = [ "stm32-metapac/stm32wl55uc_cm4" ] 1073stm32wl55uc-cm4 = [ "stm32-metapac/stm32wl55uc-cm4" ]
1074stm32wl55uc_cm0p = [ "stm32-metapac/stm32wl55uc_cm0p" ] 1074stm32wl55uc-cm0p = [ "stm32-metapac/stm32wl55uc-cm0p" ]
1075# END GENERATED FEATURES 1075# END GENERATED FEATURES
diff --git a/examples/stm32wl55/Cargo.toml b/examples/stm32wl55/Cargo.toml
index 69b97cbed..ec504b769 100644
--- a/examples/stm32wl55/Cargo.toml
+++ b/examples/stm32wl55/Cargo.toml
@@ -8,7 +8,7 @@ resolver = "2"
8[dependencies] 8[dependencies]
9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] } 9embassy = { version = "0.1.0", path = "../../embassy", features = ["defmt"] }
10embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] } 10embassy-traits = { version = "0.1.0", path = "../../embassy-traits", features = ["defmt"] }
11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc_cm4", "time-driver-tim2", "memory-x", "subghz", "unstable-pac"] } 11embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32wl55jc-cm4", "time-driver-tim2", "memory-x", "subghz", "unstable-pac"] }
12embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } 12embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" }
13embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] } 13embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time"] }
14 14
diff --git a/stm32-gen-features/src/lib.rs b/stm32-gen-features/src/lib.rs
index 756f4da83..29ea94a46 100644
--- a/stm32-gen-features/src/lib.rs
+++ b/stm32-gen-features/src/lib.rs
@@ -123,7 +123,7 @@ pub fn stm32_metapac_needed_data(names_and_cores: &[(String, Vec<String>)]) -> S
123 for (chip_name, cores) in names_and_cores { 123 for (chip_name, cores) in names_and_cores {
124 if cores.len() > 1 { 124 if cores.len() > 1 {
125 for core_name in cores { 125 for core_name in cores {
126 result += &format!("{}_{} = []\n", chip_name, core_name); 126 result += &format!("{}-{} = []\n", chip_name, core_name);
127 } 127 }
128 } else { 128 } else {
129 result += &format!("{} = []\n", chip_name); 129 result += &format!("{} = []\n", chip_name);
diff --git a/stm32-metapac-gen/src/assets/build.rs b/stm32-metapac-gen/src/assets/build.rs
index e4f31ae46..14d041ff6 100644
--- a/stm32-metapac-gen/src/assets/build.rs
+++ b/stm32-metapac-gen/src/assets/build.rs
@@ -1,30 +1,30 @@
1use std::env; 1use std::env;
2use std::path::PathBuf;
2 3
3fn main() { 4fn main() {
4 let chip_name = env::vars_os() 5 let crate_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
6
7 let chip_core_name = env::vars_os()
5 .map(|(a, _)| a.to_string_lossy().to_string()) 8 .map(|(a, _)| a.to_string_lossy().to_string())
6 .find(|x| x.starts_with("CARGO_FEATURE_STM32")) 9 .find(|x| x.starts_with("CARGO_FEATURE_STM32"))
7 .expect("No stm32xx Cargo feature enabled") 10 .expect("No stm32xx Cargo feature enabled")
8 .strip_prefix("CARGO_FEATURE_") 11 .strip_prefix("CARGO_FEATURE_")
9 .unwrap() 12 .unwrap()
10 .to_ascii_lowercase(); 13 .to_ascii_lowercase()
14 .replace('_', "-");
11 15
12 let mut s = chip_name.split('_'); 16 println!(
13 let mut chip_name: String = s.next().unwrap().to_string(); 17 "cargo:rustc-link-search={}/src/chips/{}",
14 if let Some(c) = s.next() { 18 crate_dir.display(),
15 if !c.starts_with("CM") { 19 chip_core_name,
16 chip_name.push('-'); 20 );
17 } else {
18 chip_name.push('_');
19 }
20 chip_name.push_str(c);
21 }
22 21
23 #[cfg(feature = "memory-x")] 22 #[cfg(feature = "memory-x")]
24 println!("cargo:rustc-link-search=src/chips/{}/memory_x/", _chip_name); 23 println!(
25 24 "cargo:rustc-link-search={}/src/chips/{}/memory_x/",
26 #[cfg(feature = "rt")] 25 crate_dir.display(),
27 println!("cargo:rustc-link-search=src/chips/{}", _chip_name); 26 chip_core_name,
27 );
28 28
29 println!("cargo:rerun-if-changed=build.rs"); 29 println!("cargo:rerun-if-changed=build.rs");
30} 30}
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index 00268bb0e..876251152 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -2,7 +2,6 @@ use chiptool::generate::CommonModule;
2use chiptool::ir::IR; 2use chiptool::ir::IR;
3use regex::Regex; 3use regex::Regex;
4use std::collections::{BTreeMap, HashMap, HashSet}; 4use std::collections::{BTreeMap, HashMap, HashSet};
5use std::env;
6use std::fmt::Write as _; 5use std::fmt::Write as _;
7use std::fs; 6use std::fs;
8use std::fs::File; 7use std::fs::File;
@@ -98,474 +97,457 @@ pub struct Options {
98 pub data_dir: PathBuf, 97 pub data_dir: PathBuf,
99} 98}
100 99
101pub fn gen(options: Options) { 100pub fn gen_chip(
102 let generate_opts = generate::Options { 101 options: &Options,
103 common_module: CommonModule::Builtin, 102 chip_core_name: &str,
103 chip: &Chip,
104 core: &Core,
105 core_index: usize,
106 all_peripheral_versions: &mut HashSet<(String, String)>,
107) {
108 let mut ir = ir::IR::new();
109
110 let mut dev = ir::Device {
111 interrupts: Vec::new(),
112 peripherals: Vec::new(),
104 }; 113 };
105 114
106 let out_dir = options.out_dir; 115 // Load DBGMCU register for chip
107 let data_dir = options.data_dir; 116 let mut dbgmcu: Option<ir::IR> = core.peripherals.iter().find_map(|(name, p)| {
108 117 if name == "DBGMCU" {
109 fs::create_dir_all(out_dir.join("src/peripherals")).unwrap(); 118 p.block.as_ref().map(|block| {
110 fs::create_dir_all(out_dir.join("src/chips")).unwrap(); 119 let bi = BlockInfo::parse(block);
111 120 let dbgmcu_reg_path = options
112 println!("cwd: {:?}", env::current_dir()); 121 .data_dir
113 122 .join("registers")
114 let mut all_peripheral_versions: HashSet<(String, String)> = HashSet::new(); 123 .join(&format!("{}_{}.yaml", bi.module, bi.version));
115 let mut chip_cores: BTreeMap<String, Option<String>> = BTreeMap::new(); 124 serde_yaml::from_reader(File::open(dbgmcu_reg_path).unwrap()).unwrap()
116 125 })
117 for chip_name in &options.chips {
118 let mut s = chip_name.split('_');
119 let mut chip_name: String = s.next().unwrap().to_string();
120 let core_name: Option<&str> = if let Some(c) = s.next() {
121 if !c.starts_with("CM") {
122 println!("Core not detected, adding as variant");
123 chip_name.push('-');
124 chip_name.push_str(c);
125 None
126 } else {
127 println!("Detected core {}", c);
128 Some(c)
129 }
130 } else { 126 } else {
131 None 127 None
132 }; 128 }
133 129 });
134 chip_cores.insert( 130
135 chip_name.to_string(), 131 // Load RCC register for chip
136 core_name.map(|s| s.to_ascii_lowercase().to_string()), 132 let (_, rcc) = core
137 ); 133 .peripherals
138 134 .iter()
139 let chip_path = data_dir.join("chips").join(&format!("{}.yaml", chip_name)); 135 .find(|(name, _)| name == &"RCC")
140 println!("chip_path: {:?}", chip_path); 136 .expect("RCC peripheral missing");
141 let chip = fs::read(chip_path).unwrap(); 137
142 let chip: Chip = serde_yaml::from_slice(&chip).unwrap(); 138 let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
143 139 let bi = BlockInfo::parse(&rcc_block);
144 println!("looking for core {:?}", core_name); 140 let rcc_reg_path = options
145 let core: Option<(&Core, usize)> = if let Some(core_name) = core_name { 141 .data_dir
146 let core_name = core_name.to_ascii_lowercase(); 142 .join("registers")
147 let mut c = None; 143 .join(&format!("{}_{}.yaml", bi.module, bi.version));
148 let mut idx = 0; 144 let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap();
149 for (i, core) in chip.cores.iter().enumerate() { 145
150 if core.name == core_name { 146 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
151 c = Some(core); 147 let mut pin_table: Vec<Vec<String>> = Vec::new();
152 idx = i; 148 let mut interrupt_table: Vec<Vec<String>> = Vec::new();
153 break; 149 let mut peripherals_table: Vec<Vec<String>> = Vec::new();
154 } 150 let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new();
151 let mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new();
152 let mut dma_channels_table: Vec<Vec<String>> = Vec::new();
153 let mut peripheral_dma_channels_table: Vec<Vec<String>> = Vec::new();
154 let mut peripheral_counts: BTreeMap<String, u8> = BTreeMap::new();
155 let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new();
156 let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
157 let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
158 let mut gpio_regs: HashSet<String> = HashSet::new();
159
160 let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address as u32;
161 let gpio_stride = 0x400;
162
163 let number_suffix_re = Regex::new("^(.*?)[0-9]*$").unwrap();
164
165 if let Some(ref mut reg) = dbgmcu {
166 if let Some(ref cr) = reg.fieldsets.get("CR") {
167 for field in cr.fields.iter().filter(|e| e.name.contains("DBG")) {
168 let mut fn_name = String::new();
169 fn_name.push_str("set_");
170 fn_name.push_str(&field.name.to_sanitized_snake_case());
171 dbgmcu_table.push(vec!["cr".into(), fn_name]);
155 } 172 }
156 c.map(|c| (c, idx)) 173 }
157 } else { 174 }
158 Some((&chip.cores[0], 0))
159 };
160
161 let (core, core_index) = core.unwrap();
162 let core_name = &core.name;
163
164 let mut ir = ir::IR::new();
165 175
166 let mut dev = ir::Device { 176 for (name, p) in &core.peripherals {
167 interrupts: Vec::new(), 177 let captures = number_suffix_re.captures(&name).unwrap();
168 peripherals: Vec::new(), 178 let root_peri_name = captures.get(1).unwrap().as_str().to_string();
179 peripheral_counts.insert(
180 root_peri_name.clone(),
181 peripheral_counts.get(&root_peri_name).map_or(1, |v| v + 1),
182 );
183 let mut ir_peri = ir::Peripheral {
184 name: name.clone(),
185 array: None,
186 base_address: p.address,
187 block: None,
188 description: None,
189 interrupts: HashMap::new(),
169 }; 190 };
170 191
171 // Load DBGMCU register for chip 192 if let Some(block) = &p.block {
172 let mut dbgmcu: Option<ir::IR> = core.peripherals.iter().find_map(|(name, p)| { 193 let bi = BlockInfo::parse(block);
173 if name == "DBGMCU" {
174 p.block.as_ref().map(|block| {
175 let bi = BlockInfo::parse(block);
176 let dbgmcu_reg_path = data_dir
177 .join("registers")
178 .join(&format!("{}_{}.yaml", bi.module, bi.version));
179 serde_yaml::from_reader(File::open(dbgmcu_reg_path).unwrap()).unwrap()
180 })
181 } else {
182 None
183 }
184 });
185
186 // Load RCC register for chip
187 let (_, rcc) = core
188 .peripherals
189 .iter()
190 .find(|(name, _)| name == &"RCC")
191 .expect("RCC peripheral missing");
192
193 let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
194 let bi = BlockInfo::parse(&rcc_block);
195 let rcc_reg_path = data_dir
196 .join("registers")
197 .join(&format!("{}_{}.yaml", bi.module, bi.version));
198 let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap();
199
200 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
201 let mut pin_table: Vec<Vec<String>> = Vec::new();
202 let mut interrupt_table: Vec<Vec<String>> = Vec::new();
203 let mut peripherals_table: Vec<Vec<String>> = Vec::new();
204 let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new();
205 let mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new();
206 let mut dma_channels_table: Vec<Vec<String>> = Vec::new();
207 let mut peripheral_dma_channels_table: Vec<Vec<String>> = Vec::new();
208 let mut peripheral_counts: BTreeMap<String, u8> = BTreeMap::new();
209 let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new();
210 let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
211 let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
212 let mut gpio_regs: HashSet<String> = HashSet::new();
213
214 let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address as u32;
215 let gpio_stride = 0x400;
216
217 let number_suffix_re = Regex::new("^(.*?)[0-9]*$").unwrap();
218
219 if let Some(ref mut reg) = dbgmcu {
220 if let Some(ref cr) = reg.fieldsets.get("CR") {
221 for field in cr.fields.iter().filter(|e| e.name.contains("DBG")) {
222 let mut fn_name = String::new();
223 fn_name.push_str("set_");
224 fn_name.push_str(&field.name.to_sanitized_snake_case());
225 dbgmcu_table.push(vec!["cr".into(), fn_name]);
226 }
227 }
228 }
229 194
230 for (name, p) in &core.peripherals {
231 let captures = number_suffix_re.captures(&name).unwrap();
232 let root_peri_name = captures.get(1).unwrap().as_str().to_string();
233 peripheral_counts.insert( 195 peripheral_counts.insert(
234 root_peri_name.clone(), 196 bi.module.clone(),
235 peripheral_counts.get(&root_peri_name).map_or(1, |v| v + 1), 197 peripheral_counts.get(&bi.module).map_or(1, |v| v + 1),
236 ); 198 );
237 let mut ir_peri = ir::Peripheral {
238 name: name.clone(),
239 array: None,
240 base_address: p.address,
241 block: None,
242 description: None,
243 interrupts: HashMap::new(),
244 };
245
246 if let Some(block) = &p.block {
247 let bi = BlockInfo::parse(block);
248
249 peripheral_counts.insert(
250 bi.module.clone(),
251 peripheral_counts.get(&bi.module).map_or(1, |v| v + 1),
252 );
253 199
254 for pin in &p.pins { 200 for pin in &p.pins {
255 let mut row = Vec::new(); 201 let mut row = Vec::new();
256 row.push(name.clone()); 202 row.push(name.clone());
257 row.push(bi.module.clone()); 203 row.push(bi.module.clone());
258 row.push(bi.block.clone()); 204 row.push(bi.block.clone());
259 row.push(pin.pin.clone()); 205 row.push(pin.pin.clone());
260 row.push(pin.signal.clone()); 206 row.push(pin.signal.clone());
261 if let Some(ref af) = pin.af { 207 if let Some(ref af) = pin.af {
262 row.push(af.clone()); 208 row.push(af.clone());
263 }
264 peripheral_pins_table.push(row);
265 } 209 }
210 peripheral_pins_table.push(row);
211 }
212
213 for (signal, irq_name) in &p.interrupts {
214 let mut row = Vec::new();
215 row.push(name.clone());
216 row.push(bi.module.clone());
217 row.push(bi.block.clone());
218 row.push(signal.clone());
219 row.push(irq_name.to_ascii_uppercase());
220 interrupt_table.push(row)
221 }
266 222
267 for (signal, irq_name) in &p.interrupts { 223 for (request, dma_channels) in &p.dma_channels {
224 for channel in dma_channels.iter() {
268 let mut row = Vec::new(); 225 let mut row = Vec::new();
269 row.push(name.clone()); 226 row.push(name.clone());
270 row.push(bi.module.clone()); 227 row.push(bi.module.clone());
271 row.push(bi.block.clone()); 228 row.push(bi.block.clone());
272 row.push(signal.clone()); 229 row.push(request.clone());
273 row.push(irq_name.to_ascii_uppercase()); 230 row.push(if let Some(channel) = &channel.channel {
274 interrupt_table.push(row) 231 format!("{{channel: {}}}", channel)
275 } 232 } else if let Some(dmamux) = &channel.dmamux {
276 233 format!("{{dmamux: {}}}", dmamux)
277 for (request, dma_channels) in &p.dma_channels { 234 } else {
278 for channel in dma_channels.iter() { 235 unreachable!();
279 let mut row = Vec::new(); 236 });
280 row.push(name.clone()); 237
281 row.push(bi.module.clone()); 238 row.push(if let Some(request) = channel.request {
282 row.push(bi.block.clone()); 239 request.to_string()
283 row.push(request.clone()); 240 } else {
284 row.push(if let Some(channel) = &channel.channel { 241 "()".to_string()
285 format!("{{channel: {}}}", channel) 242 });
286 } else if let Some(dmamux) = &channel.dmamux { 243
287 format!("{{dmamux: {}}}", dmamux) 244 if peripheral_dma_channels_table
288 } else { 245 .iter()
289 unreachable!(); 246 .find(|a| a[..a.len() - 1] == row[..row.len() - 1])
290 }); 247 .is_none()
291 248 {
292 row.push(if let Some(request) = channel.request { 249 peripheral_dma_channels_table.push(row);
293 request.to_string()
294 } else {
295 "()".to_string()
296 });
297
298 if peripheral_dma_channels_table
299 .iter()
300 .find(|a| a[..a.len() - 1] == row[..row.len() - 1])
301 .is_none()
302 {
303 peripheral_dma_channels_table.push(row);
304 }
305 } 250 }
306 } 251 }
252 }
307 253
308 let mut peripheral_row = Vec::new(); 254 let mut peripheral_row = Vec::new();
309 peripheral_row.push(bi.module.clone()); 255 peripheral_row.push(bi.module.clone());
310 peripheral_row.push(name.clone()); 256 peripheral_row.push(name.clone());
311 peripherals_table.push(peripheral_row); 257 peripherals_table.push(peripheral_row);
312 258
313 if let Some(old_version) = 259 if let Some(old_version) =
314 peripheral_versions.insert(bi.module.clone(), bi.version.clone()) 260 peripheral_versions.insert(bi.module.clone(), bi.version.clone())
315 { 261 {
316 if old_version != bi.version { 262 if old_version != bi.version {
317 panic!( 263 panic!(
318 "Peripheral {} has multiple versions: {} and {}", 264 "Peripheral {} has multiple versions: {} and {}",
319 bi.module, old_version, bi.version 265 bi.module, old_version, bi.version
320 ); 266 );
321 }
322 } 267 }
323 ir_peri.block = Some(format!("{}::{}", bi.module, bi.block)); 268 }
324 269 ir_peri.block = Some(format!("{}::{}", bi.module, bi.block));
325 match bi.module.as_str() { 270
326 "gpio" => { 271 match bi.module.as_str() {
327 let port_letter = name.chars().skip(4).next().unwrap(); 272 "gpio" => {
328 assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride); 273 let port_letter = name.chars().skip(4).next().unwrap();
329 let port_num = (p.address as u32 - gpio_base) / gpio_stride; 274 assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride);
330 275 let port_num = (p.address as u32 - gpio_base) / gpio_stride;
331 for pin_num in 0..16 { 276
332 let pin_name = format!("P{}{}", port_letter, pin_num); 277 for pin_num in 0..16 {
333 pin_table.push(vec![ 278 let pin_name = format!("P{}{}", port_letter, pin_num);
334 pin_name.clone(), 279 pin_table.push(vec![
335 name.clone(), 280 pin_name.clone(),
336 port_num.to_string(), 281 name.clone(),
337 pin_num.to_string(), 282 port_num.to_string(),
338 format!("EXTI{}", pin_num), 283 pin_num.to_string(),
339 ]); 284 format!("EXTI{}", pin_num),
340 } 285 ]);
341 } 286 }
342 _ => {}
343 } 287 }
288 _ => {}
289 }
344 290
345 // Workaround for clock registers being split on some chip families. Assume fields are 291 // Workaround for clock registers being split on some chip families. Assume fields are
346 // named after peripheral and look for first field matching and use that register. 292 // named after peripheral and look for first field matching and use that register.
347 let mut en = find_reg(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); 293 let mut en = find_reg(&rcc, "^.+ENR\\d*$", &format!("{}EN", name));
348 let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); 294 let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name));
349 295
350 if en.is_none() && name.ends_with("1") { 296 if en.is_none() && name.ends_with("1") {
351 en = find_reg( 297 en = find_reg(
352 &rcc, 298 &rcc,
353 "^.+ENR\\d*$", 299 "^.+ENR\\d*$",
354 &format!("{}EN", &name[..name.len() - 1]), 300 &format!("{}EN", &name[..name.len() - 1]),
355 ); 301 );
356 rst = find_reg( 302 rst = find_reg(
357 &rcc, 303 &rcc,
358 "^.+RSTR\\d*$", 304 "^.+RSTR\\d*$",
359 &format!("{}RST", &name[..name.len() - 1]), 305 &format!("{}RST", &name[..name.len() - 1]),
360 ); 306 );
361 } 307 }
362 308
363 match (en, rst) { 309 match (en, rst) {
364 (Some((enable_reg, enable_field)), reset_reg_field) => { 310 (Some((enable_reg, enable_field)), reset_reg_field) => {
365 let clock = match &p.clock { 311 let clock = match &p.clock {
366 Some(clock) => clock.as_str(), 312 Some(clock) => clock.as_str(),
367 None => { 313 None => {
368 // No clock was specified, derive the clock name from the enable register name. 314 // No clock was specified, derive the clock name from the enable register name.
369 // N.B. STM32G0 has only one APB bus but split ENR registers 315 // N.B. STM32G0 has only one APB bus but split ENR registers
370 // (e.g. APBENR1). 316 // (e.g. APBENR1).
371 Regex::new("([A-Z]+\\d*)ENR\\d*") 317 Regex::new("([A-Z]+\\d*)ENR\\d*")
372 .unwrap() 318 .unwrap()
373 .captures(enable_reg) 319 .captures(enable_reg)
374 .unwrap() 320 .unwrap()
375 .get(1) 321 .get(1)
376 .unwrap() 322 .unwrap()
377 .as_str() 323 .as_str()
378 }
379 };
380
381 let clock = if name.starts_with("TIM") {
382 format!("{}_tim", clock.to_ascii_lowercase())
383 } else {
384 clock.to_ascii_lowercase()
385 };
386
387 let mut row = Vec::with_capacity(6);
388 row.push(name.clone());
389 row.push(clock);
390 row.push(enable_reg.to_ascii_lowercase());
391
392 if let Some((reset_reg, reset_field)) = reset_reg_field {
393 row.push(reset_reg.to_ascii_lowercase());
394 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
395 row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
396 } else {
397 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
398 } 324 }
325 };
399 326
400 if !name.starts_with("GPIO") { 327 let clock = if name.starts_with("TIM") {
401 peripheral_rcc_table.push(row); 328 format!("{}_tim", clock.to_ascii_lowercase())
402 } else { 329 } else {
403 gpio_rcc_table.push(row); 330 clock.to_ascii_lowercase()
404 gpio_regs.insert(enable_reg.to_ascii_lowercase()); 331 };
405 } 332
406 } 333 let mut row = Vec::with_capacity(6);
407 (None, Some(_)) => { 334 row.push(name.clone());
408 println!("Unable to find enable register for {}", name) 335 row.push(clock);
336 row.push(enable_reg.to_ascii_lowercase());
337
338 if let Some((reset_reg, reset_field)) = reset_reg_field {
339 row.push(reset_reg.to_ascii_lowercase());
340 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
341 row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
342 } else {
343 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
409 } 344 }
410 (None, None) => { 345
411 println!("Unable to find enable and reset register for {}", name) 346 if !name.starts_with("GPIO") {
347 peripheral_rcc_table.push(row);
348 } else {
349 gpio_rcc_table.push(row);
350 gpio_regs.insert(enable_reg.to_ascii_lowercase());
412 } 351 }
413 } 352 }
353 (None, Some(_)) => {
354 println!("Unable to find enable register for {}", name)
355 }
356 (None, None) => {
357 println!("Unable to find enable and reset register for {}", name)
358 }
414 } 359 }
415
416 dev.peripherals.push(ir_peri);
417 } 360 }
418 361
419 for reg in gpio_regs { 362 dev.peripherals.push(ir_peri);
420 gpio_rcc_table.push(vec![reg]); 363 }
421 }
422
423 // We should always find GPIO RCC regs. If not, it means something
424 // is broken and GPIO won't work because it's not enabled.
425 assert!(!gpio_rcc_table.is_empty());
426
427 for (id, channel_info) in &core.dma_channels {
428 let mut row = Vec::new();
429 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
430 let bi = BlockInfo::parse(dma_peri.block.as_ref().unwrap());
431
432 row.push(id.clone());
433 row.push(channel_info.dma.clone());
434 row.push(bi.module.clone());
435 row.push(channel_info.channel.to_string());
436 if let Some(dmamux) = &channel_info.dmamux {
437 let dmamux_channel = channel_info.dmamux_channel.unwrap();
438 row.push(format!(
439 "{{dmamux: {}, dmamux_channel: {}}}",
440 dmamux, dmamux_channel
441 ));
442 } else {
443 row.push("{}".to_string());
444 }
445 364
446 dma_channels_table.push(row); 365 for reg in gpio_regs {
366 gpio_rcc_table.push(vec![reg]);
367 }
447 368
448 let dma_peri_name = channel_info.dma.clone(); 369 // We should always find GPIO RCC regs. If not, it means something
449 dma_channel_counts.insert( 370 // is broken and GPIO won't work because it's not enabled.
450 dma_peri_name.clone(), 371 assert!(!gpio_rcc_table.is_empty());
451 dma_channel_counts.get(&dma_peri_name).map_or(1, |v| v + 1), 372
452 ); 373 for (id, channel_info) in &core.dma_channels {
374 let mut row = Vec::new();
375 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
376 let bi = BlockInfo::parse(dma_peri.block.as_ref().unwrap());
377
378 row.push(id.clone());
379 row.push(channel_info.dma.clone());
380 row.push(bi.module.clone());
381 row.push(channel_info.channel.to_string());
382 if let Some(dmamux) = &channel_info.dmamux {
383 let dmamux_channel = channel_info.dmamux_channel.unwrap();
384 row.push(format!(
385 "{{dmamux: {}, dmamux_channel: {}}}",
386 dmamux, dmamux_channel
387 ));
388 } else {
389 row.push("{}".to_string());
453 } 390 }
454 391
455 for (name, &num) in &core.interrupts { 392 dma_channels_table.push(row);
456 dev.interrupts.push(ir::Interrupt {
457 name: name.clone(),
458 description: None,
459 value: num,
460 });
461 393
462 let name = name.to_ascii_uppercase(); 394 let dma_peri_name = channel_info.dma.clone();
395 dma_channel_counts.insert(
396 dma_peri_name.clone(),
397 dma_channel_counts.get(&dma_peri_name).map_or(1, |v| v + 1),
398 );
399 }
463 400
464 interrupt_table.push(vec![name.clone()]); 401 for (name, &num) in &core.interrupts {
402 dev.interrupts.push(ir::Interrupt {
403 name: name.clone(),
404 description: None,
405 value: num,
406 });
465 407
466 if name.contains("EXTI") { 408 let name = name.to_ascii_uppercase();
467 interrupt_table.push(vec!["EXTI".to_string(), name.clone()]); 409
468 } 410 interrupt_table.push(vec![name.clone()]);
411
412 if name.contains("EXTI") {
413 interrupt_table.push(vec!["EXTI".to_string(), name.clone()]);
469 } 414 }
415 }
470 416
471 ir.devices.insert("".to_string(), dev); 417 ir.devices.insert("".to_string(), dev);
472 418
473 let mut extra = format!( 419 let mut extra = format!(
474 "pub fn GPIO(n: usize) -> gpio::Gpio {{ 420 "pub fn GPIO(n: usize) -> gpio::Gpio {{
475 gpio::Gpio(({} + {}*n) as _) 421 gpio::Gpio(({} + {}*n) as _)
476 }}", 422 }}",
477 gpio_base, gpio_stride, 423 gpio_base, gpio_stride,
478 ); 424 );
479 425
480 let peripheral_version_table = peripheral_versions 426 let peripheral_version_table = peripheral_versions
481 .iter() 427 .iter()
482 .map(|(kind, version)| vec![kind.clone(), version.clone()]) 428 .map(|(kind, version)| vec![kind.clone(), version.clone()])
483 .collect(); 429 .collect();
484 430
485 make_table(&mut extra, "pins", &pin_table); 431 make_table(&mut extra, "pins", &pin_table);
486 make_table(&mut extra, "interrupts", &interrupt_table); 432 make_table(&mut extra, "interrupts", &interrupt_table);
487 make_table(&mut extra, "peripherals", &peripherals_table); 433 make_table(&mut extra, "peripherals", &peripherals_table);
488 make_table(&mut extra, "peripheral_versions", &peripheral_version_table); 434 make_table(&mut extra, "peripheral_versions", &peripheral_version_table);
489 make_table(&mut extra, "peripheral_pins", &peripheral_pins_table); 435 make_table(&mut extra, "peripheral_pins", &peripheral_pins_table);
490 make_table( 436 make_table(
491 &mut extra, 437 &mut extra,
492 "peripheral_dma_channels", 438 "peripheral_dma_channels",
493 &peripheral_dma_channels_table, 439 &peripheral_dma_channels_table,
494 ); 440 );
495 make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table); 441 make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table);
496 make_table(&mut extra, "gpio_rcc", &gpio_rcc_table); 442 make_table(&mut extra, "gpio_rcc", &gpio_rcc_table);
497 make_table(&mut extra, "dma_channels", &dma_channels_table); 443 make_table(&mut extra, "dma_channels", &dma_channels_table);
498 make_table(&mut extra, "dbgmcu", &dbgmcu_table); 444 make_table(&mut extra, "dbgmcu", &dbgmcu_table);
499 make_peripheral_counts(&mut extra, &peripheral_counts); 445 make_peripheral_counts(&mut extra, &peripheral_counts);
500 make_dma_channel_counts(&mut extra, &dma_channel_counts); 446 make_dma_channel_counts(&mut extra, &dma_channel_counts);
501 447
502 for (module, version) in peripheral_versions { 448 for (module, version) in peripheral_versions {
503 all_peripheral_versions.insert((module.clone(), version.clone())); 449 all_peripheral_versions.insert((module.clone(), version.clone()));
504 write!(
505 &mut extra,
506 "#[path=\"../../peripherals/{}_{}.rs\"] pub mod {};\n",
507 module, version, module
508 )
509 .unwrap();
510 }
511 write!( 450 write!(
512 &mut extra, 451 &mut extra,
513 "pub const CORE_INDEX: usize = {};\n", 452 "#[path=\"../../peripherals/{}_{}.rs\"] pub mod {};\n",
514 core_index 453 module, version, module
515 ) 454 )
516 .unwrap(); 455 .unwrap();
456 }
457 write!(
458 &mut extra,
459 "pub const CORE_INDEX: usize = {};\n",
460 core_index
461 )
462 .unwrap();
517 463
518 // Cleanups! 464 // Cleanups!
519 transform::sort::Sort {}.run(&mut ir).unwrap(); 465 transform::sort::Sort {}.run(&mut ir).unwrap();
520 transform::Sanitize {}.run(&mut ir).unwrap(); 466 transform::Sanitize {}.run(&mut ir).unwrap();
521 467
522 let chip_dir = if chip.cores.len() > 1 { 468 let chip_dir = options
523 out_dir.join("src/chips").join(format!( 469 .out_dir
524 "{}_{}", 470 .join("src/chips")
525 chip_name.to_ascii_lowercase(), 471 .join(chip_core_name.to_ascii_lowercase());
526 core_name.to_ascii_lowercase() 472 fs::create_dir_all(&chip_dir).unwrap();
527 ))
528 } else {
529 out_dir
530 .join("src/chips")
531 .join(chip_name.to_ascii_lowercase())
532 };
533 fs::create_dir_all(&chip_dir).unwrap();
534 473
535 let items = generate::render(&ir, &generate_opts).unwrap(); 474 let generate_opts = generate::Options {
536 let mut file = File::create(chip_dir.join("pac.rs")).unwrap(); 475 common_module: CommonModule::Builtin,
537 let data = items.to_string().replace("] ", "]\n"); 476 };
477 let items = generate::render(&ir, &generate_opts).unwrap();
478 let mut file = File::create(chip_dir.join("pac.rs")).unwrap();
479 let data = items.to_string().replace("] ", "]\n");
538 480
539 // Remove inner attributes like #![no_std] 481 // Remove inner attributes like #![no_std]
540 let re = Regex::new("# *! *\\[.*\\]").unwrap(); 482 let re = Regex::new("# *! *\\[.*\\]").unwrap();
541 let data = re.replace_all(&data, ""); 483 let data = re.replace_all(&data, "");
542 file.write_all(data.as_bytes()).unwrap(); 484 file.write_all(data.as_bytes()).unwrap();
543 file.write_all(extra.as_bytes()).unwrap(); 485 file.write_all(extra.as_bytes()).unwrap();
544 486
545 let mut device_x = String::new(); 487 let mut device_x = String::new();
546 488
547 for (name, _) in &core.interrupts { 489 for (name, _) in &core.interrupts {
548 write!( 490 write!(
549 &mut device_x, 491 &mut device_x,
550 "PROVIDE({} = DefaultHandler);\n", 492 "PROVIDE({} = DefaultHandler);\n",
551 name.to_ascii_uppercase() 493 name.to_ascii_uppercase()
552 ) 494 )
553 .unwrap(); 495 .unwrap();
554 } 496 }
555 497
556 File::create(chip_dir.join("device.x")) 498 File::create(chip_dir.join("device.x"))
557 .unwrap() 499 .unwrap()
558 .write_all(device_x.as_bytes()) 500 .write_all(device_x.as_bytes())
559 .unwrap(); 501 .unwrap();
502
503 // generate default memory.x
504 gen_memory_x(&chip_dir, &chip);
505}
506
507fn load_chip(options: &Options, name: &str) -> Chip {
508 let chip_path = options
509 .data_dir
510 .join("chips")
511 .join(&format!("{}.yaml", name));
512 let chip = fs::read(chip_path).expect(&format!("Could not load chip {}", name));
513 serde_yaml::from_slice(&chip).unwrap()
514}
515
516pub fn gen(options: Options) {
517 let generate_opts = generate::Options {
518 common_module: CommonModule::Builtin,
519 };
520
521 fs::create_dir_all(options.out_dir.join("src/peripherals")).unwrap();
522 fs::create_dir_all(options.out_dir.join("src/chips")).unwrap();
523
524 let mut all_peripheral_versions: HashSet<(String, String)> = HashSet::new();
525 let mut chip_core_names: Vec<String> = Vec::new();
560 526
561 // generate default memory.x 527 for chip_name in &options.chips {
562 gen_memory_x(&chip_dir, &chip); 528 let chip = load_chip(&options, chip_name);
529 for (core_index, core) in chip.cores.iter().enumerate() {
530 let chip_core_name = match chip.cores.len() {
531 1 => chip_name.clone(),
532 _ => format!("{}-{}", chip_name, core.name),
533 };
534
535 chip_core_names.push(chip_core_name.clone());
536 gen_chip(
537 &options,
538 &chip_core_name,
539 &chip,
540 core,
541 core_index,
542 &mut all_peripheral_versions,
543 )
544 }
563 } 545 }
564 546
565 for (module, version) in all_peripheral_versions { 547 for (module, version) in all_peripheral_versions {
566 println!("loading {} {}", module, version); 548 println!("loading {} {}", module, version);
567 549
568 let regs_path = Path::new(&data_dir) 550 let regs_path = Path::new(&options.data_dir)
569 .join("registers") 551 .join("registers")
570 .join(&format!("{}_{}.yaml", module, version)); 552 .join(&format!("{}_{}.yaml", module, version));
571 553
@@ -587,7 +569,8 @@ pub fn gen(options: Options) {
587 569
588 let items = generate::render(&ir, &generate_opts).unwrap(); 570 let items = generate::render(&ir, &generate_opts).unwrap();
589 let mut file = File::create( 571 let mut file = File::create(
590 out_dir 572 options
573 .out_dir
591 .join("src/peripherals") 574 .join("src/peripherals")
592 .join(format!("{}_{}.rs", module, version)), 575 .join(format!("{}_{}.rs", module, version)),
593 ) 576 )
@@ -606,29 +589,20 @@ pub fn gen(options: Options) {
606 let i = bytes_find(librs, PATHS_MARKER).unwrap(); 589 let i = bytes_find(librs, PATHS_MARKER).unwrap();
607 let mut paths = String::new(); 590 let mut paths = String::new();
608 591
609 for (chip, cores) in chip_cores.iter() { 592 for name in chip_core_names {
610 let x = chip.to_ascii_lowercase(); 593 let x = name.to_ascii_lowercase();
611 if let Some(c) = cores { 594 write!(
612 write!( 595 &mut paths,
613 &mut paths, 596 "#[cfg_attr(feature=\"{}\", path = \"chips/{}/pac.rs\")]",
614 "#[cfg_attr(feature=\"{}_{}\", path = \"chips/{}_{}/pac.rs\")]", 597 x, x
615 x, c, x, c 598 )
616 ) 599 .unwrap();
617 .unwrap();
618 } else {
619 write!(
620 &mut paths,
621 "#[cfg_attr(feature=\"{}\", path = \"chips/{}/pac.rs\")]",
622 x, x
623 )
624 .unwrap();
625 }
626 } 600 }
627 let mut contents: Vec<u8> = Vec::new(); 601 let mut contents: Vec<u8> = Vec::new();
628 contents.extend(&librs[..i]); 602 contents.extend(&librs[..i]);
629 contents.extend(paths.as_bytes()); 603 contents.extend(paths.as_bytes());
630 contents.extend(&librs[i + PATHS_MARKER.len()..]); 604 contents.extend(&librs[i + PATHS_MARKER.len()..]);
631 fs::write(out_dir.join("src").join("lib_inner.rs"), &contents).unwrap(); 605 fs::write(options.out_dir.join("src").join("lib_inner.rs"), &contents).unwrap();
632 606
633 // Generate src/lib.rs 607 // Generate src/lib.rs
634 const CUT_MARKER: &[u8] = b"// GEN CUT HERE"; 608 const CUT_MARKER: &[u8] = b"// GEN CUT HERE";
@@ -637,11 +611,11 @@ pub fn gen(options: Options) {
637 let mut contents: Vec<u8> = Vec::new(); 611 let mut contents: Vec<u8> = Vec::new();
638 contents.extend(&librs[..i]); 612 contents.extend(&librs[..i]);
639 contents.extend(b"include!(\"lib_inner.rs\");\n"); 613 contents.extend(b"include!(\"lib_inner.rs\");\n");
640 fs::write(out_dir.join("src").join("lib.rs"), contents).unwrap(); 614 fs::write(options.out_dir.join("src").join("lib.rs"), contents).unwrap();
641 615
642 // Generate src/common.rs 616 // Generate src/common.rs
643 fs::write( 617 fs::write(
644 out_dir.join("src").join("common.rs"), 618 options.out_dir.join("src").join("common.rs"),
645 generate::COMMON_MODULE, 619 generate::COMMON_MODULE,
646 ) 620 )
647 .unwrap(); 621 .unwrap();
@@ -654,10 +628,14 @@ pub fn gen(options: Options) {
654 let begin = bytes_find(&contents, BUILDDEP_BEGIN).unwrap(); 628 let begin = bytes_find(&contents, BUILDDEP_BEGIN).unwrap();
655 let end = bytes_find(&contents, BUILDDEP_END).unwrap() + BUILDDEP_END.len(); 629 let end = bytes_find(&contents, BUILDDEP_END).unwrap() + BUILDDEP_END.len();
656 contents.drain(begin..end); 630 contents.drain(begin..end);
657 fs::write(out_dir.join("Cargo.toml"), contents).unwrap(); 631 fs::write(options.out_dir.join("Cargo.toml"), contents).unwrap();
658 632
659 // Generate build.rs 633 // Generate build.rs
660 fs::write(out_dir.join("build.rs"), include_bytes!("assets/build.rs")).unwrap(); 634 fs::write(
635 options.out_dir.join("build.rs"),
636 include_bytes!("assets/build.rs"),
637 )
638 .unwrap();
661} 639}
662 640
663fn bytes_find(haystack: &[u8], needle: &[u8]) -> Option<usize> { 641fn bytes_find(haystack: &[u8], needle: &[u8]) -> Option<usize> {
diff --git a/stm32-metapac-gen/src/main.rs b/stm32-metapac-gen/src/main.rs
index 0380affc2..c4ea77145 100644
--- a/stm32-metapac-gen/src/main.rs
+++ b/stm32-metapac-gen/src/main.rs
@@ -17,7 +17,6 @@ fn main() {
17 .unwrap() 17 .unwrap()
18 .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string())) 18 .filter_map(|res| res.unwrap().file_name().to_str().map(|s| s.to_string()))
19 .filter(|s| s.ends_with(".yaml")) 19 .filter(|s| s.ends_with(".yaml"))
20 .filter(|s| !s.starts_with("STM32L1")) // cursed gpio stride
21 .filter(|s| !s.starts_with("STM32GBK")) // cursed weird STM32G4 20 .filter(|s| !s.starts_with("STM32GBK")) // cursed weird STM32G4
22 .map(|s| s.strip_suffix(".yaml").unwrap().to_string()) 21 .map(|s| s.strip_suffix(".yaml").unwrap().to_string())
23 .collect() 22 .collect()
diff --git a/stm32-metapac/Cargo.toml b/stm32-metapac/Cargo.toml
index 1395e7f60..1ca80d162 100644
--- a/stm32-metapac/Cargo.toml
+++ b/stm32-metapac/Cargo.toml
@@ -780,40 +780,40 @@ stm32h743xg = []
780stm32h743xi = [] 780stm32h743xi = []
781stm32h743zg = [] 781stm32h743zg = []
782stm32h743zi = [] 782stm32h743zi = []
783stm32h745bg_cm7 = [] 783stm32h745bg-cm7 = []
784stm32h745bg_cm4 = [] 784stm32h745bg-cm4 = []
785stm32h745bi_cm7 = [] 785stm32h745bi-cm7 = []
786stm32h745bi_cm4 = [] 786stm32h745bi-cm4 = []
787stm32h745ig_cm7 = [] 787stm32h745ig-cm7 = []
788stm32h745ig_cm4 = [] 788stm32h745ig-cm4 = []
789stm32h745ii_cm7 = [] 789stm32h745ii-cm7 = []
790stm32h745ii_cm4 = [] 790stm32h745ii-cm4 = []
791stm32h745xg_cm7 = [] 791stm32h745xg-cm7 = []
792stm32h745xg_cm4 = [] 792stm32h745xg-cm4 = []
793stm32h745xi_cm7 = [] 793stm32h745xi-cm7 = []
794stm32h745xi_cm4 = [] 794stm32h745xi-cm4 = []
795stm32h745zg_cm7 = [] 795stm32h745zg-cm7 = []
796stm32h745zg_cm4 = [] 796stm32h745zg-cm4 = []
797stm32h745zi_cm7 = [] 797stm32h745zi-cm7 = []
798stm32h745zi_cm4 = [] 798stm32h745zi-cm4 = []
799stm32h747ag_cm7 = [] 799stm32h747ag-cm7 = []
800stm32h747ag_cm4 = [] 800stm32h747ag-cm4 = []
801stm32h747ai_cm7 = [] 801stm32h747ai-cm7 = []
802stm32h747ai_cm4 = [] 802stm32h747ai-cm4 = []
803stm32h747bg_cm7 = [] 803stm32h747bg-cm7 = []
804stm32h747bg_cm4 = [] 804stm32h747bg-cm4 = []
805stm32h747bi_cm7 = [] 805stm32h747bi-cm7 = []
806stm32h747bi_cm4 = [] 806stm32h747bi-cm4 = []
807stm32h747ig_cm7 = [] 807stm32h747ig-cm7 = []
808stm32h747ig_cm4 = [] 808stm32h747ig-cm4 = []
809stm32h747ii_cm7 = [] 809stm32h747ii-cm7 = []
810stm32h747ii_cm4 = [] 810stm32h747ii-cm4 = []
811stm32h747xg_cm7 = [] 811stm32h747xg-cm7 = []
812stm32h747xg_cm4 = [] 812stm32h747xg-cm4 = []
813stm32h747xi_cm7 = [] 813stm32h747xi-cm7 = []
814stm32h747xi_cm4 = [] 814stm32h747xi-cm4 = []
815stm32h747zi_cm7 = [] 815stm32h747zi-cm7 = []
816stm32h747zi_cm4 = [] 816stm32h747zi-cm4 = []
817stm32h750ib = [] 817stm32h750ib = []
818stm32h750vb = [] 818stm32h750vb = []
819stm32h750xb = [] 819stm32h750xb = []
@@ -824,24 +824,24 @@ stm32h753ii = []
824stm32h753vi = [] 824stm32h753vi = []
825stm32h753xi = [] 825stm32h753xi = []
826stm32h753zi = [] 826stm32h753zi = []
827stm32h755bi_cm7 = [] 827stm32h755bi-cm7 = []
828stm32h755bi_cm4 = [] 828stm32h755bi-cm4 = []
829stm32h755ii_cm7 = [] 829stm32h755ii-cm7 = []
830stm32h755ii_cm4 = [] 830stm32h755ii-cm4 = []
831stm32h755xi_cm7 = [] 831stm32h755xi-cm7 = []
832stm32h755xi_cm4 = [] 832stm32h755xi-cm4 = []
833stm32h755zi_cm7 = [] 833stm32h755zi-cm7 = []
834stm32h755zi_cm4 = [] 834stm32h755zi-cm4 = []
835stm32h757ai_cm7 = [] 835stm32h757ai-cm7 = []
836stm32h757ai_cm4 = [] 836stm32h757ai-cm4 = []
837stm32h757bi_cm7 = [] 837stm32h757bi-cm7 = []
838stm32h757bi_cm4 = [] 838stm32h757bi-cm4 = []
839stm32h757ii_cm7 = [] 839stm32h757ii-cm7 = []
840stm32h757ii_cm4 = [] 840stm32h757ii-cm4 = []
841stm32h757xi_cm7 = [] 841stm32h757xi-cm7 = []
842stm32h757xi_cm4 = [] 842stm32h757xi-cm4 = []
843stm32h757zi_cm7 = [] 843stm32h757zi-cm7 = []
844stm32h757zi_cm4 = [] 844stm32h757zi-cm4 = []
845stm32h7a3ag = [] 845stm32h7a3ag = []
846stm32h7a3ai = [] 846stm32h7a3ai = []
847stm32h7a3ig = [] 847stm32h7a3ig = []
@@ -1255,16 +1255,16 @@ stm32wb55ve = []
1255stm32wb55vg = [] 1255stm32wb55vg = []
1256stm32wb55vy = [] 1256stm32wb55vy = []
1257stm32wb5mmg = [] 1257stm32wb5mmg = []
1258stm32wl54cc_cm4 = [] 1258stm32wl54cc-cm4 = []
1259stm32wl54cc_cm0p = [] 1259stm32wl54cc-cm0p = []
1260stm32wl54jc_cm4 = [] 1260stm32wl54jc-cm4 = []
1261stm32wl54jc_cm0p = [] 1261stm32wl54jc-cm0p = []
1262stm32wl55cc_cm4 = [] 1262stm32wl55cc-cm4 = []
1263stm32wl55cc_cm0p = [] 1263stm32wl55cc-cm0p = []
1264stm32wl55jc_cm4 = [] 1264stm32wl55jc-cm4 = []
1265stm32wl55jc_cm0p = [] 1265stm32wl55jc-cm0p = []
1266stm32wl55uc_cm4 = [] 1266stm32wl55uc-cm4 = []
1267stm32wl55uc_cm0p = [] 1267stm32wl55uc-cm0p = []
1268stm32wle4c8 = [] 1268stm32wle4c8 = []
1269stm32wle4cb = [] 1269stm32wle4cb = []
1270stm32wle4cc = [] 1270stm32wle4cc = []
diff --git a/stm32-metapac/build.rs b/stm32-metapac/build.rs
index d840d8fe0..7fd5a6b1f 100644
--- a/stm32-metapac/build.rs
+++ b/stm32-metapac/build.rs
@@ -2,48 +2,52 @@ use std::env;
2use std::path::PathBuf; 2use std::path::PathBuf;
3use stm32_metapac_gen::*; 3use stm32_metapac_gen::*;
4 4
5fn parse_chip_core(chip_and_core: &str) -> (String, Option<String>) {
6 let mut s = chip_and_core.split('-');
7 let chip_name: String = s.next().unwrap().to_string();
8 if let Some(c) = s.next() {
9 if c.starts_with("CM") {
10 return (chip_name, Some(c.to_ascii_lowercase()));
11 }
12 }
13
14 (chip_and_core.to_string(), None)
15}
16
5fn main() { 17fn main() {
6 let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); 18 let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
7 let data_dir = PathBuf::from("../stm32-data/data"); 19 let data_dir = PathBuf::from("../stm32-data/data");
8 20
9 println!("cwd: {:?}", env::current_dir()); 21 println!("cwd: {:?}", env::current_dir());
10 22
11 let chip_name = env::vars_os() 23 let chip_core_name = env::vars_os()
12 .map(|(a, _)| a.to_string_lossy().to_string()) 24 .map(|(a, _)| a.to_string_lossy().to_string())
13 .find(|x| x.starts_with("CARGO_FEATURE_STM32")) 25 .find(|x| x.starts_with("CARGO_FEATURE_STM32"))
14 .expect("No stm32xx Cargo feature enabled") 26 .expect("No stm32xx Cargo feature enabled")
15 .strip_prefix("CARGO_FEATURE_") 27 .strip_prefix("CARGO_FEATURE_")
16 .unwrap() 28 .unwrap()
17 .to_ascii_uppercase(); 29 .to_ascii_uppercase()
30 .replace('_', "-");
31
32 let (chip_name, _) = parse_chip_core(&chip_core_name);
18 33
19 gen(Options { 34 gen(Options {
20 out_dir: out_dir.clone(), 35 out_dir: out_dir.clone(),
21 data_dir: data_dir.clone(), 36 data_dir: data_dir.clone(),
22 chips: vec![chip_name.clone()], 37 chips: vec![chip_name],
23 }); 38 });
24 39
25 let mut s = chip_name.split('_');
26 let mut chip_name: String = s.next().unwrap().to_string();
27 if let Some(c) = s.next() {
28 if !c.starts_with("CM") {
29 chip_name.push('-');
30 } else {
31 chip_name.push('_');
32 }
33 chip_name.push_str(c);
34 }
35
36 println!( 40 println!(
37 "cargo:rustc-link-search={}/src/chips/{}", 41 "cargo:rustc-link-search={}/src/chips/{}",
38 out_dir.display(), 42 out_dir.display(),
39 chip_name.to_ascii_lowercase() 43 chip_core_name.to_ascii_lowercase()
40 ); 44 );
41 45
42 #[cfg(feature = "memory-x")] 46 #[cfg(feature = "memory-x")]
43 println!( 47 println!(
44 "cargo:rustc-link-search={}/src/chips/{}/memory_x/", 48 "cargo:rustc-link-search={}/src/chips/{}/memory_x/",
45 out_dir.display(), 49 out_dir.display(),
46 chip_name.to_ascii_lowercase() 50 chip_core_name.to_ascii_lowercase()
47 ); 51 );
48 52
49 println!("cargo:rerun-if-changed=build.rs"); 53 println!("cargo:rerun-if-changed=build.rs");