aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-11-24 01:00:22 +0000
committerGitHub <[email protected]>2021-11-24 01:00:22 +0000
commit8fea6c94f6d0978042554eb6b154706d8f7a9fd5 (patch)
tree5780b0642693ef798dda6226f98778663f646582
parente725d22fd461c36f049341bbbf3f1f8f5717ebf0 (diff)
parentf9934fb56b5afdcf18df28aa8290c8d048886c2b (diff)
Merge #501
501: stm32-metapac cleanups r=Dirbaio a=Dirbaio Co-authored-by: Dario Nieuwenhuis <[email protected]>
-rw-r--r--.github/workflows/rust.yml11
-rwxr-xr-xci.sh9
-rw-r--r--embassy-stm32/Cargo.toml118
-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/data.rs105
-rw-r--r--stm32-metapac-gen/src/lib.rs961
-rw-r--r--stm32-metapac-gen/src/main.rs1
-rw-r--r--stm32-metapac/Cargo.toml131
-rw-r--r--stm32-metapac/build.rs36
11 files changed, 709 insertions, 699 deletions
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 055089bd9..7904c3856 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -12,7 +12,7 @@ env:
12jobs: 12jobs:
13 all: 13 all:
14 runs-on: ubuntu-20.04 14 runs-on: ubuntu-20.04
15 needs: [build, test, metapac_gen] 15 needs: [build, test]
16 steps: 16 steps:
17 - name: Done 17 - name: Done
18 run: exit 0 18 run: exit 0
@@ -45,12 +45,3 @@ jobs:
45 - uses: actions/checkout@v2 45 - uses: actions/checkout@v2
46 - name: Test 46 - name: Test
47 run: cd embassy && cargo test 47 run: cd embassy && cargo test
48
49 metapac_gen:
50 runs-on: ubuntu-latest
51 steps:
52 - uses: actions/checkout@v2
53 with:
54 submodules: true
55 - name: Generate pregenerated metapac
56 run: cd stm32-metapac-gen; cargo run --release
diff --git a/ci.sh b/ci.sh
index 601123863..8c6c2eebe 100755
--- a/ci.sh
+++ b/ci.sh
@@ -7,6 +7,13 @@ export RUSTFLAGS=-Dwarnings
7 7
8find -name '*.rs' -not -path '*target*' -not -path '*stm32-metapac-gen/out/*' | xargs rustfmt --check --skip-children --unstable-features --edition 2018 8find -name '*.rs' -not -path '*target*' -not -path '*stm32-metapac-gen/out/*' | xargs rustfmt --check --skip-children --unstable-features --edition 2018
9 9
10# Generate stm32-metapac
11# for some reason Cargo stomps the cache if we don't specify --target.
12# This happens with vanilla Cargo, not just cargo-batch. Bug?
13(cd stm32-metapac-gen; cargo run --release --target x86_64-unknown-linux-gnu)
14rm -rf stm32-metapac
15mv stm32-metapac-gen/out stm32-metapac
16
10cargo batch \ 17cargo batch \
11 --- build --release --manifest-path embassy/Cargo.toml --target thumbv7em-none-eabi \ 18 --- build --release --manifest-path embassy/Cargo.toml --target thumbv7em-none-eabi \
12 --- build --release --manifest-path embassy/Cargo.toml --target thumbv7em-none-eabi --features log,executor-agnostic \ 19 --- build --release --manifest-path embassy/Cargo.toml --target thumbv7em-none-eabi --features log,executor-agnostic \
@@ -28,7 +35,7 @@ cargo batch \
28 --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52840,defmt \ 35 --- 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 \ 36 --- 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 \ 37 --- 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 \ 38 --- 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 \ 39 --- 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 \ 40 --- 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 \ 41 --- 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..364c48f60 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -34,8 +34,6 @@ cfg-if = "1.0.0"
34 34
35[build-dependencies] 35[build-dependencies]
36stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false } 36stm32-metapac = { version = "0.1.0", path = "../stm32-metapac", default-features = false }
37serde = { version = "1.0.130", features = [ "derive" ] }
38serde_yaml = "0.8.21"
39 37
40[features] 38[features]
41sdmmc-rs = ["embedded-sdmmc"] 39sdmmc-rs = ["embedded-sdmmc"]
@@ -615,40 +613,40 @@ stm32h743xg = [ "stm32-metapac/stm32h743xg" ]
615stm32h743xi = [ "stm32-metapac/stm32h743xi" ] 613stm32h743xi = [ "stm32-metapac/stm32h743xi" ]
616stm32h743zg = [ "stm32-metapac/stm32h743zg" ] 614stm32h743zg = [ "stm32-metapac/stm32h743zg" ]
617stm32h743zi = [ "stm32-metapac/stm32h743zi" ] 615stm32h743zi = [ "stm32-metapac/stm32h743zi" ]
618stm32h745bg_cm7 = [ "stm32-metapac/stm32h745bg_cm7" ] 616stm32h745bg-cm7 = [ "stm32-metapac/stm32h745bg-cm7" ]
619stm32h745bg_cm4 = [ "stm32-metapac/stm32h745bg_cm4" ] 617stm32h745bg-cm4 = [ "stm32-metapac/stm32h745bg-cm4" ]
620stm32h745bi_cm7 = [ "stm32-metapac/stm32h745bi_cm7" ] 618stm32h745bi-cm7 = [ "stm32-metapac/stm32h745bi-cm7" ]
621stm32h745bi_cm4 = [ "stm32-metapac/stm32h745bi_cm4" ] 619stm32h745bi-cm4 = [ "stm32-metapac/stm32h745bi-cm4" ]
622stm32h745ig_cm7 = [ "stm32-metapac/stm32h745ig_cm7" ] 620stm32h745ig-cm7 = [ "stm32-metapac/stm32h745ig-cm7" ]
623stm32h745ig_cm4 = [ "stm32-metapac/stm32h745ig_cm4" ] 621stm32h745ig-cm4 = [ "stm32-metapac/stm32h745ig-cm4" ]
624stm32h745ii_cm7 = [ "stm32-metapac/stm32h745ii_cm7" ] 622stm32h745ii-cm7 = [ "stm32-metapac/stm32h745ii-cm7" ]
625stm32h745ii_cm4 = [ "stm32-metapac/stm32h745ii_cm4" ] 623stm32h745ii-cm4 = [ "stm32-metapac/stm32h745ii-cm4" ]
626stm32h745xg_cm7 = [ "stm32-metapac/stm32h745xg_cm7" ] 624stm32h745xg-cm7 = [ "stm32-metapac/stm32h745xg-cm7" ]
627stm32h745xg_cm4 = [ "stm32-metapac/stm32h745xg_cm4" ] 625stm32h745xg-cm4 = [ "stm32-metapac/stm32h745xg-cm4" ]
628stm32h745xi_cm7 = [ "stm32-metapac/stm32h745xi_cm7" ] 626stm32h745xi-cm7 = [ "stm32-metapac/stm32h745xi-cm7" ]
629stm32h745xi_cm4 = [ "stm32-metapac/stm32h745xi_cm4" ] 627stm32h745xi-cm4 = [ "stm32-metapac/stm32h745xi-cm4" ]
630stm32h745zg_cm7 = [ "stm32-metapac/stm32h745zg_cm7" ] 628stm32h745zg-cm7 = [ "stm32-metapac/stm32h745zg-cm7" ]
631stm32h745zg_cm4 = [ "stm32-metapac/stm32h745zg_cm4" ] 629stm32h745zg-cm4 = [ "stm32-metapac/stm32h745zg-cm4" ]
632stm32h745zi_cm7 = [ "stm32-metapac/stm32h745zi_cm7" ] 630stm32h745zi-cm7 = [ "stm32-metapac/stm32h745zi-cm7" ]
633stm32h745zi_cm4 = [ "stm32-metapac/stm32h745zi_cm4" ] 631stm32h745zi-cm4 = [ "stm32-metapac/stm32h745zi-cm4" ]
634stm32h747ag_cm7 = [ "stm32-metapac/stm32h747ag_cm7" ] 632stm32h747ag-cm7 = [ "stm32-metapac/stm32h747ag-cm7" ]
635stm32h747ag_cm4 = [ "stm32-metapac/stm32h747ag_cm4" ] 633stm32h747ag-cm4 = [ "stm32-metapac/stm32h747ag-cm4" ]
636stm32h747ai_cm7 = [ "stm32-metapac/stm32h747ai_cm7" ] 634stm32h747ai-cm7 = [ "stm32-metapac/stm32h747ai-cm7" ]
637stm32h747ai_cm4 = [ "stm32-metapac/stm32h747ai_cm4" ] 635stm32h747ai-cm4 = [ "stm32-metapac/stm32h747ai-cm4" ]
638stm32h747bg_cm7 = [ "stm32-metapac/stm32h747bg_cm7" ] 636stm32h747bg-cm7 = [ "stm32-metapac/stm32h747bg-cm7" ]
639stm32h747bg_cm4 = [ "stm32-metapac/stm32h747bg_cm4" ] 637stm32h747bg-cm4 = [ "stm32-metapac/stm32h747bg-cm4" ]
640stm32h747bi_cm7 = [ "stm32-metapac/stm32h747bi_cm7" ] 638stm32h747bi-cm7 = [ "stm32-metapac/stm32h747bi-cm7" ]
641stm32h747bi_cm4 = [ "stm32-metapac/stm32h747bi_cm4" ] 639stm32h747bi-cm4 = [ "stm32-metapac/stm32h747bi-cm4" ]
642stm32h747ig_cm7 = [ "stm32-metapac/stm32h747ig_cm7" ] 640stm32h747ig-cm7 = [ "stm32-metapac/stm32h747ig-cm7" ]
643stm32h747ig_cm4 = [ "stm32-metapac/stm32h747ig_cm4" ] 641stm32h747ig-cm4 = [ "stm32-metapac/stm32h747ig-cm4" ]
644stm32h747ii_cm7 = [ "stm32-metapac/stm32h747ii_cm7" ] 642stm32h747ii-cm7 = [ "stm32-metapac/stm32h747ii-cm7" ]
645stm32h747ii_cm4 = [ "stm32-metapac/stm32h747ii_cm4" ] 643stm32h747ii-cm4 = [ "stm32-metapac/stm32h747ii-cm4" ]
646stm32h747xg_cm7 = [ "stm32-metapac/stm32h747xg_cm7" ] 644stm32h747xg-cm7 = [ "stm32-metapac/stm32h747xg-cm7" ]
647stm32h747xg_cm4 = [ "stm32-metapac/stm32h747xg_cm4" ] 645stm32h747xg-cm4 = [ "stm32-metapac/stm32h747xg-cm4" ]
648stm32h747xi_cm7 = [ "stm32-metapac/stm32h747xi_cm7" ] 646stm32h747xi-cm7 = [ "stm32-metapac/stm32h747xi-cm7" ]
649stm32h747xi_cm4 = [ "stm32-metapac/stm32h747xi_cm4" ] 647stm32h747xi-cm4 = [ "stm32-metapac/stm32h747xi-cm4" ]
650stm32h747zi_cm7 = [ "stm32-metapac/stm32h747zi_cm7" ] 648stm32h747zi-cm7 = [ "stm32-metapac/stm32h747zi-cm7" ]
651stm32h747zi_cm4 = [ "stm32-metapac/stm32h747zi_cm4" ] 649stm32h747zi-cm4 = [ "stm32-metapac/stm32h747zi-cm4" ]
652stm32h750ib = [ "stm32-metapac/stm32h750ib" ] 650stm32h750ib = [ "stm32-metapac/stm32h750ib" ]
653stm32h750vb = [ "stm32-metapac/stm32h750vb" ] 651stm32h750vb = [ "stm32-metapac/stm32h750vb" ]
654stm32h750xb = [ "stm32-metapac/stm32h750xb" ] 652stm32h750xb = [ "stm32-metapac/stm32h750xb" ]
@@ -659,24 +657,24 @@ stm32h753ii = [ "stm32-metapac/stm32h753ii" ]
659stm32h753vi = [ "stm32-metapac/stm32h753vi" ] 657stm32h753vi = [ "stm32-metapac/stm32h753vi" ]
660stm32h753xi = [ "stm32-metapac/stm32h753xi" ] 658stm32h753xi = [ "stm32-metapac/stm32h753xi" ]
661stm32h753zi = [ "stm32-metapac/stm32h753zi" ] 659stm32h753zi = [ "stm32-metapac/stm32h753zi" ]
662stm32h755bi_cm7 = [ "stm32-metapac/stm32h755bi_cm7" ] 660stm32h755bi-cm7 = [ "stm32-metapac/stm32h755bi-cm7" ]
663stm32h755bi_cm4 = [ "stm32-metapac/stm32h755bi_cm4" ] 661stm32h755bi-cm4 = [ "stm32-metapac/stm32h755bi-cm4" ]
664stm32h755ii_cm7 = [ "stm32-metapac/stm32h755ii_cm7" ] 662stm32h755ii-cm7 = [ "stm32-metapac/stm32h755ii-cm7" ]
665stm32h755ii_cm4 = [ "stm32-metapac/stm32h755ii_cm4" ] 663stm32h755ii-cm4 = [ "stm32-metapac/stm32h755ii-cm4" ]
666stm32h755xi_cm7 = [ "stm32-metapac/stm32h755xi_cm7" ] 664stm32h755xi-cm7 = [ "stm32-metapac/stm32h755xi-cm7" ]
667stm32h755xi_cm4 = [ "stm32-metapac/stm32h755xi_cm4" ] 665stm32h755xi-cm4 = [ "stm32-metapac/stm32h755xi-cm4" ]
668stm32h755zi_cm7 = [ "stm32-metapac/stm32h755zi_cm7" ] 666stm32h755zi-cm7 = [ "stm32-metapac/stm32h755zi-cm7" ]
669stm32h755zi_cm4 = [ "stm32-metapac/stm32h755zi_cm4" ] 667stm32h755zi-cm4 = [ "stm32-metapac/stm32h755zi-cm4" ]
670stm32h757ai_cm7 = [ "stm32-metapac/stm32h757ai_cm7" ] 668stm32h757ai-cm7 = [ "stm32-metapac/stm32h757ai-cm7" ]
671stm32h757ai_cm4 = [ "stm32-metapac/stm32h757ai_cm4" ] 669stm32h757ai-cm4 = [ "stm32-metapac/stm32h757ai-cm4" ]
672stm32h757bi_cm7 = [ "stm32-metapac/stm32h757bi_cm7" ] 670stm32h757bi-cm7 = [ "stm32-metapac/stm32h757bi-cm7" ]
673stm32h757bi_cm4 = [ "stm32-metapac/stm32h757bi_cm4" ] 671stm32h757bi-cm4 = [ "stm32-metapac/stm32h757bi-cm4" ]
674stm32h757ii_cm7 = [ "stm32-metapac/stm32h757ii_cm7" ] 672stm32h757ii-cm7 = [ "stm32-metapac/stm32h757ii-cm7" ]
675stm32h757ii_cm4 = [ "stm32-metapac/stm32h757ii_cm4" ] 673stm32h757ii-cm4 = [ "stm32-metapac/stm32h757ii-cm4" ]
676stm32h757xi_cm7 = [ "stm32-metapac/stm32h757xi_cm7" ] 674stm32h757xi-cm7 = [ "stm32-metapac/stm32h757xi-cm7" ]
677stm32h757xi_cm4 = [ "stm32-metapac/stm32h757xi_cm4" ] 675stm32h757xi-cm4 = [ "stm32-metapac/stm32h757xi-cm4" ]
678stm32h757zi_cm7 = [ "stm32-metapac/stm32h757zi_cm7" ] 676stm32h757zi-cm7 = [ "stm32-metapac/stm32h757zi-cm7" ]
679stm32h757zi_cm4 = [ "stm32-metapac/stm32h757zi_cm4" ] 677stm32h757zi-cm4 = [ "stm32-metapac/stm32h757zi-cm4" ]
680stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ] 678stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ]
681stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ] 679stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ]
682stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ] 680stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ]
@@ -1066,10 +1064,10 @@ stm32wb55vc = [ "stm32-metapac/stm32wb55vc" ]
1066stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ] 1064stm32wb55ve = [ "stm32-metapac/stm32wb55ve" ]
1067stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ] 1065stm32wb55vg = [ "stm32-metapac/stm32wb55vg" ]
1068stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ] 1066stm32wb55vy = [ "stm32-metapac/stm32wb55vy" ]
1069stm32wl55cc_cm4 = [ "stm32-metapac/stm32wl55cc_cm4" ] 1067stm32wl55cc-cm4 = [ "stm32-metapac/stm32wl55cc-cm4" ]
1070stm32wl55cc_cm0p = [ "stm32-metapac/stm32wl55cc_cm0p" ] 1068stm32wl55cc-cm0p = [ "stm32-metapac/stm32wl55cc-cm0p" ]
1071stm32wl55jc_cm4 = [ "stm32-metapac/stm32wl55jc_cm4" ] 1069stm32wl55jc-cm4 = [ "stm32-metapac/stm32wl55jc-cm4" ]
1072stm32wl55jc_cm0p = [ "stm32-metapac/stm32wl55jc_cm0p" ] 1070stm32wl55jc-cm0p = [ "stm32-metapac/stm32wl55jc-cm0p" ]
1073stm32wl55uc_cm4 = [ "stm32-metapac/stm32wl55uc_cm4" ] 1071stm32wl55uc-cm4 = [ "stm32-metapac/stm32wl55uc-cm4" ]
1074stm32wl55uc_cm0p = [ "stm32-metapac/stm32wl55uc_cm0p" ] 1072stm32wl55uc-cm0p = [ "stm32-metapac/stm32wl55uc-cm0p" ]
1075# END GENERATED FEATURES 1073# 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 1c9411151..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/data.rs b/stm32-metapac-gen/src/data.rs
new file mode 100644
index 000000000..deaf09d3e
--- /dev/null
+++ b/stm32-metapac-gen/src/data.rs
@@ -0,0 +1,105 @@
1use serde::Deserialize;
2use std::collections::{BTreeMap, HashMap};
3
4#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
5pub struct Chip {
6 pub name: String,
7 pub family: String,
8 pub line: String,
9 pub cores: Vec<Core>,
10 pub flash: Memory,
11 pub ram: Memory,
12 pub packages: Vec<Package>,
13}
14
15#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
16pub struct Memory {
17 pub bytes: u32,
18 pub regions: HashMap<String, MemoryRegion>,
19}
20
21#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
22pub struct MemoryRegion {
23 pub base: u32,
24 pub bytes: Option<u32>,
25}
26
27#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
28pub struct Core {
29 pub name: String,
30 pub peripherals: BTreeMap<String, Peripheral>,
31 pub interrupts: BTreeMap<String, u32>,
32 pub dma_channels: BTreeMap<String, DmaChannel>,
33}
34
35#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
36pub struct Package {
37 pub name: String,
38 pub package: String,
39}
40
41#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
42pub struct Peripheral {
43 pub address: u64,
44 #[serde(default)]
45 pub kind: Option<String>,
46 #[serde(default)]
47 pub block: Option<String>,
48 #[serde(default)]
49 pub clock: Option<String>,
50 #[serde(default)]
51 pub pins: Vec<Pin>,
52 #[serde(default)]
53 pub dma_channels: BTreeMap<String, Vec<PeripheralDmaChannel>>,
54 #[serde(default)]
55 pub interrupts: BTreeMap<String, String>,
56}
57
58#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
59pub struct Pin {
60 pub pin: String,
61 pub signal: String,
62 pub af: Option<String>,
63}
64
65#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
66pub struct DmaChannel {
67 pub dma: String,
68 pub channel: u32,
69 pub dmamux: Option<String>,
70 pub dmamux_channel: Option<u32>,
71}
72
73#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Hash)]
74pub struct PeripheralDmaChannel {
75 pub channel: Option<String>,
76 pub dmamux: Option<String>,
77 pub request: Option<u32>,
78}
79
80pub struct BlockInfo {
81 /// usart_v1/USART -> usart
82 pub module: String,
83 /// usart_v1/USART -> v1
84 pub version: String,
85 /// usart_v1/USART -> USART
86 pub block: String,
87}
88
89impl BlockInfo {
90 pub fn parse(s: &str) -> Self {
91 let mut s = s.split('/');
92 let module = s.next().unwrap();
93 let block = s.next().unwrap();
94 assert!(s.next().is_none());
95 let mut s = module.split('_');
96 let module = s.next().unwrap();
97 let version = s.next().unwrap();
98 assert!(s.next().is_none());
99 Self {
100 module: module.to_string(),
101 version: version.to_string(),
102 block: block.to_string(),
103 }
104 }
105}
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index 3480ac364..9fe3be55c 100644
--- a/stm32-metapac-gen/src/lib.rs
+++ b/stm32-metapac-gen/src/lib.rs
@@ -1,121 +1,21 @@
1use chiptool::generate::CommonModule; 1use chiptool::generate::CommonModule;
2use chiptool::ir::IR; 2use chiptool::ir::IR;
3use proc_macro2::TokenStream;
3use regex::Regex; 4use regex::Regex;
4use serde::Deserialize;
5use std::collections::{BTreeMap, HashMap, HashSet}; 5use std::collections::{BTreeMap, HashMap, HashSet};
6use std::env;
7use std::fmt::Write as _; 6use std::fmt::Write as _;
8use std::fs; 7use std::fs;
9use std::fs::File; 8use std::fs::File;
10use std::io::Write; 9use std::io::Write;
11use std::path::Path; 10use std::path::Path;
12use std::path::PathBuf; 11use std::path::PathBuf;
12use std::str::FromStr;
13 13
14use chiptool::util::ToSanitizedSnakeCase; 14use chiptool::util::ToSanitizedSnakeCase;
15use chiptool::{generate, ir, transform}; 15use chiptool::{generate, ir, transform};
16 16
17#[derive(Debug, Eq, PartialEq, Clone, Deserialize)] 17mod data;
18pub struct Chip { 18use data::*;
19 pub name: String,
20 pub family: String,
21 pub line: String,
22 pub cores: Vec<Core>,
23 pub flash: Memory,
24 pub ram: Memory,
25 pub packages: Vec<Package>,
26}
27
28#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
29pub struct Memory {
30 pub bytes: u32,
31 pub regions: HashMap<String, MemoryRegion>,
32}
33
34#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
35pub struct MemoryRegion {
36 pub base: u32,
37 pub bytes: Option<u32>,
38}
39
40#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
41pub struct Core {
42 pub name: String,
43 pub peripherals: BTreeMap<String, Peripheral>,
44 pub interrupts: BTreeMap<String, u32>,
45 pub dma_channels: BTreeMap<String, DmaChannel>,
46}
47
48#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
49pub struct Package {
50 pub name: String,
51 pub package: String,
52}
53
54#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
55pub struct Peripheral {
56 pub address: u64,
57 #[serde(default)]
58 pub kind: Option<String>,
59 #[serde(default)]
60 pub block: Option<String>,
61 #[serde(default)]
62 pub clock: Option<String>,
63 #[serde(default)]
64 pub pins: Vec<Pin>,
65 #[serde(default)]
66 pub dma_channels: BTreeMap<String, Vec<PeripheralDmaChannel>>,
67 #[serde(default)]
68 pub interrupts: BTreeMap<String, String>,
69}
70
71#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
72pub struct Pin {
73 pub pin: String,
74 pub signal: String,
75 pub af: Option<String>,
76}
77
78#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
79pub struct DmaChannel {
80 pub dma: String,
81 pub channel: u32,
82 pub dmamux: Option<String>,
83 pub dmamux_channel: Option<u32>,
84}
85
86#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Hash)]
87pub struct PeripheralDmaChannel {
88 pub channel: Option<String>,
89 pub dmamux: Option<String>,
90 pub request: Option<u32>,
91}
92
93struct BlockInfo {
94 /// usart_v1/USART -> usart
95 module: String,
96 /// usart_v1/USART -> v1
97 version: String,
98 /// usart_v1/USART -> USART
99 block: String,
100}
101
102impl BlockInfo {
103 fn parse(s: &str) -> Self {
104 let mut s = s.split("/");
105 let module = s.next().unwrap();
106 let block = s.next().unwrap();
107 assert!(s.next().is_none());
108 let mut s = module.split("_");
109 let module = s.next().unwrap();
110 let version = s.next().unwrap();
111 assert!(s.next().is_none());
112 Self {
113 module: module.to_string(),
114 version: version.to_string(),
115 block: block.to_string(),
116 }
117 }
118}
119 19
120fn find_reg<'c>(rcc: &'c ir::IR, reg_regex: &str, field_name: &str) -> Option<(&'c str, &'c str)> { 20fn find_reg<'c>(rcc: &'c ir::IR, reg_regex: &str, field_name: &str) -> Option<(&'c str, &'c str)> {
121 let reg_regex = Regex::new(reg_regex).unwrap(); 21 let reg_regex = Regex::new(reg_regex).unwrap();
@@ -199,474 +99,477 @@ pub struct Options {
199 pub data_dir: PathBuf, 99 pub data_dir: PathBuf,
200} 100}
201 101
202pub fn gen(options: Options) { 102pub fn gen_chip(
203 let generate_opts = generate::Options { 103 options: &Options,
204 common_module: CommonModule::Builtin, 104 chip_core_name: &str,
105 chip: &Chip,
106 core: &Core,
107 core_index: usize,
108 all_peripheral_versions: &mut HashSet<(String, String)>,
109) {
110 let mut ir = ir::IR::new();
111
112 let mut dev = ir::Device {
113 interrupts: Vec::new(),
114 peripherals: Vec::new(),
205 }; 115 };
206 116
207 let out_dir = options.out_dir; 117 // Load DBGMCU register for chip
208 let data_dir = options.data_dir; 118 let mut dbgmcu: Option<ir::IR> = core.peripherals.iter().find_map(|(name, p)| {
209 119 if name == "DBGMCU" {
210 fs::create_dir_all(out_dir.join("src/peripherals")).unwrap(); 120 p.block.as_ref().map(|block| {
211 fs::create_dir_all(out_dir.join("src/chips")).unwrap(); 121 let bi = BlockInfo::parse(block);
212 122 let dbgmcu_reg_path = options
213 println!("cwd: {:?}", env::current_dir()); 123 .data_dir
214 124 .join("registers")
215 let mut all_peripheral_versions: HashSet<(String, String)> = HashSet::new(); 125 .join(&format!("{}_{}.yaml", bi.module, bi.version));
216 let mut chip_cores: BTreeMap<String, Option<String>> = BTreeMap::new(); 126 serde_yaml::from_reader(File::open(dbgmcu_reg_path).unwrap()).unwrap()
217 127 })
218 for chip_name in &options.chips {
219 let mut s = chip_name.split('_');
220 let mut chip_name: String = s.next().unwrap().to_string();
221 let core_name: Option<&str> = if let Some(c) = s.next() {
222 if !c.starts_with("CM") {
223 println!("Core not detected, adding as variant");
224 chip_name.push('-');
225 chip_name.push_str(c);
226 None
227 } else {
228 println!("Detected core {}", c);
229 Some(c)
230 }
231 } else { 128 } else {
232 None 129 None
233 }; 130 }
234 131 });
235 chip_cores.insert( 132
236 chip_name.to_string(), 133 // Load RCC register for chip
237 core_name.map(|s| s.to_ascii_lowercase().to_string()), 134 let (_, rcc) = core
238 ); 135 .peripherals
239 136 .iter()
240 let chip_path = data_dir.join("chips").join(&format!("{}.yaml", chip_name)); 137 .find(|(name, _)| name == &"RCC")
241 println!("chip_path: {:?}", chip_path); 138 .expect("RCC peripheral missing");
242 let chip = fs::read(chip_path).unwrap(); 139
243 let chip: Chip = serde_yaml::from_slice(&chip).unwrap(); 140 let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
244 141 let bi = BlockInfo::parse(&rcc_block);
245 println!("looking for core {:?}", core_name); 142 let rcc_reg_path = options
246 let core: Option<(&Core, usize)> = if let Some(core_name) = core_name { 143 .data_dir
247 let core_name = core_name.to_ascii_lowercase(); 144 .join("registers")
248 let mut c = None; 145 .join(&format!("{}_{}.yaml", bi.module, bi.version));
249 let mut idx = 0; 146 let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap();
250 for (i, core) in chip.cores.iter().enumerate() { 147
251 if core.name == core_name { 148 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
252 c = Some(core); 149 let mut pin_table: Vec<Vec<String>> = Vec::new();
253 idx = i; 150 let mut interrupt_table: Vec<Vec<String>> = Vec::new();
254 break; 151 let mut peripherals_table: Vec<Vec<String>> = Vec::new();
255 } 152 let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new();
153 let mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new();
154 let mut dma_channels_table: Vec<Vec<String>> = Vec::new();
155 let mut peripheral_dma_channels_table: Vec<Vec<String>> = Vec::new();
156 let mut peripheral_counts: BTreeMap<String, u8> = BTreeMap::new();
157 let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new();
158 let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
159 let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
160 let mut gpio_regs: HashSet<String> = HashSet::new();
161
162 let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address as u32;
163 let gpio_stride = 0x400;
164
165 let number_suffix_re = Regex::new("^(.*?)[0-9]*$").unwrap();
166
167 if let Some(ref mut reg) = dbgmcu {
168 if let Some(ref cr) = reg.fieldsets.get("CR") {
169 for field in cr.fields.iter().filter(|e| e.name.contains("DBG")) {
170 let mut fn_name = String::new();
171 fn_name.push_str("set_");
172 fn_name.push_str(&field.name.to_sanitized_snake_case());
173 dbgmcu_table.push(vec!["cr".into(), fn_name]);
256 } 174 }
257 c.map(|c| (c, idx)) 175 }
258 } else { 176 }
259 Some((&chip.cores[0], 0))
260 };
261
262 let (core, core_index) = core.unwrap();
263 let core_name = &core.name;
264
265 let mut ir = ir::IR::new();
266 177
267 let mut dev = ir::Device { 178 for (name, p) in &core.peripherals {
268 interrupts: Vec::new(), 179 let captures = number_suffix_re.captures(&name).unwrap();
269 peripherals: Vec::new(), 180 let root_peri_name = captures.get(1).unwrap().as_str().to_string();
181 peripheral_counts.insert(
182 root_peri_name.clone(),
183 peripheral_counts.get(&root_peri_name).map_or(1, |v| v + 1),
184 );
185 let mut ir_peri = ir::Peripheral {
186 name: name.clone(),
187 array: None,
188 base_address: p.address,
189 block: None,
190 description: None,
191 interrupts: HashMap::new(),
270 }; 192 };
271 193
272 // Load DBGMCU register for chip 194 if let Some(block) = &p.block {
273 let mut dbgmcu: Option<ir::IR> = core.peripherals.iter().find_map(|(name, p)| { 195 let bi = BlockInfo::parse(block);
274 if name == "DBGMCU" {
275 p.block.as_ref().map(|block| {
276 let bi = BlockInfo::parse(block);
277 let dbgmcu_reg_path = data_dir
278 .join("registers")
279 .join(&format!("{}_{}.yaml", bi.module, bi.version));
280 serde_yaml::from_reader(File::open(dbgmcu_reg_path).unwrap()).unwrap()
281 })
282 } else {
283 None
284 }
285 });
286 196
287 // Load RCC register for chip
288 let (_, rcc) = core
289 .peripherals
290 .iter()
291 .find(|(name, _)| name == &"RCC")
292 .expect("RCC peripheral missing");
293
294 let rcc_block = rcc.block.as_ref().expect("RCC peripheral has no block");
295 let bi = BlockInfo::parse(&rcc_block);
296 let rcc_reg_path = data_dir
297 .join("registers")
298 .join(&format!("{}_{}.yaml", bi.module, bi.version));
299 let rcc: IR = serde_yaml::from_reader(File::open(rcc_reg_path).unwrap()).unwrap();
300
301 let mut peripheral_versions: BTreeMap<String, String> = BTreeMap::new();
302 let mut pin_table: Vec<Vec<String>> = Vec::new();
303 let mut interrupt_table: Vec<Vec<String>> = Vec::new();
304 let mut peripherals_table: Vec<Vec<String>> = Vec::new();
305 let mut peripheral_pins_table: Vec<Vec<String>> = Vec::new();
306 let mut peripheral_rcc_table: Vec<Vec<String>> = Vec::new();
307 let mut dma_channels_table: Vec<Vec<String>> = Vec::new();
308 let mut peripheral_dma_channels_table: Vec<Vec<String>> = Vec::new();
309 let mut peripheral_counts: BTreeMap<String, u8> = BTreeMap::new();
310 let mut dma_channel_counts: BTreeMap<String, u8> = BTreeMap::new();
311 let mut dbgmcu_table: Vec<Vec<String>> = Vec::new();
312 let mut gpio_rcc_table: Vec<Vec<String>> = Vec::new();
313 let mut gpio_regs: HashSet<String> = HashSet::new();
314
315 let gpio_base = core.peripherals.get(&"GPIOA".to_string()).unwrap().address as u32;
316 let gpio_stride = 0x400;
317
318 let number_suffix_re = Regex::new("^(.*?)[0-9]*$").unwrap();
319
320 if let Some(ref mut reg) = dbgmcu {
321 if let Some(ref cr) = reg.fieldsets.get("CR") {
322 for field in cr.fields.iter().filter(|e| e.name.contains("DBG")) {
323 let mut fn_name = String::new();
324 fn_name.push_str("set_");
325 fn_name.push_str(&field.name.to_sanitized_snake_case());
326 dbgmcu_table.push(vec!["cr".into(), fn_name]);
327 }
328 }
329 }
330
331 for (name, p) in &core.peripherals {
332 let captures = number_suffix_re.captures(&name).unwrap();
333 let root_peri_name = captures.get(1).unwrap().as_str().to_string();
334 peripheral_counts.insert( 197 peripheral_counts.insert(
335 root_peri_name.clone(), 198 bi.module.clone(),
336 peripheral_counts.get(&root_peri_name).map_or(1, |v| v + 1), 199 peripheral_counts.get(&bi.module).map_or(1, |v| v + 1),
337 ); 200 );
338 let mut ir_peri = ir::Peripheral {
339 name: name.clone(),
340 array: None,
341 base_address: p.address,
342 block: None,
343 description: None,
344 interrupts: HashMap::new(),
345 };
346
347 if let Some(block) = &p.block {
348 let bi = BlockInfo::parse(block);
349
350 peripheral_counts.insert(
351 bi.module.clone(),
352 peripheral_counts.get(&bi.module).map_or(1, |v| v + 1),
353 );
354 201
355 for pin in &p.pins { 202 for pin in &p.pins {
356 let mut row = Vec::new(); 203 let mut row = Vec::new();
357 row.push(name.clone()); 204 row.push(name.clone());
358 row.push(bi.module.clone()); 205 row.push(bi.module.clone());
359 row.push(bi.block.clone()); 206 row.push(bi.block.clone());
360 row.push(pin.pin.clone()); 207 row.push(pin.pin.clone());
361 row.push(pin.signal.clone()); 208 row.push(pin.signal.clone());
362 if let Some(ref af) = pin.af { 209 if let Some(ref af) = pin.af {
363 row.push(af.clone()); 210 row.push(af.clone());
364 }
365 peripheral_pins_table.push(row);
366 } 211 }
212 peripheral_pins_table.push(row);
213 }
367 214
368 for (signal, irq_name) in &p.interrupts { 215 for (signal, irq_name) in &p.interrupts {
216 let mut row = Vec::new();
217 row.push(name.clone());
218 row.push(bi.module.clone());
219 row.push(bi.block.clone());
220 row.push(signal.clone());
221 row.push(irq_name.to_ascii_uppercase());
222 interrupt_table.push(row)
223 }
224
225 for (request, dma_channels) in &p.dma_channels {
226 for channel in dma_channels.iter() {
369 let mut row = Vec::new(); 227 let mut row = Vec::new();
370 row.push(name.clone()); 228 row.push(name.clone());
371 row.push(bi.module.clone()); 229 row.push(bi.module.clone());
372 row.push(bi.block.clone()); 230 row.push(bi.block.clone());
373 row.push(signal.clone()); 231 row.push(request.clone());
374 row.push(irq_name.to_ascii_uppercase()); 232 row.push(if let Some(channel) = &channel.channel {
375 interrupt_table.push(row) 233 format!("{{channel: {}}}", channel)
376 } 234 } else if let Some(dmamux) = &channel.dmamux {
377 235 format!("{{dmamux: {}}}", dmamux)
378 for (request, dma_channels) in &p.dma_channels { 236 } else {
379 for channel in dma_channels.iter() { 237 unreachable!();
380 let mut row = Vec::new(); 238 });
381 row.push(name.clone()); 239
382 row.push(bi.module.clone()); 240 row.push(if let Some(request) = channel.request {
383 row.push(bi.block.clone()); 241 request.to_string()
384 row.push(request.clone()); 242 } else {
385 row.push(if let Some(channel) = &channel.channel { 243 "()".to_string()
386 format!("{{channel: {}}}", channel) 244 });
387 } else if let Some(dmamux) = &channel.dmamux { 245
388 format!("{{dmamux: {}}}", dmamux) 246 if peripheral_dma_channels_table
389 } else { 247 .iter()
390 unreachable!(); 248 .find(|a| a[..a.len() - 1] == row[..row.len() - 1])
391 }); 249 .is_none()
392 250 {
393 row.push(if let Some(request) = channel.request { 251 peripheral_dma_channels_table.push(row);
394 request.to_string()
395 } else {
396 "()".to_string()
397 });
398
399 if peripheral_dma_channels_table
400 .iter()
401 .find(|a| a[..a.len() - 1] == row[..row.len() - 1])
402 .is_none()
403 {
404 peripheral_dma_channels_table.push(row);
405 }
406 } 252 }
407 } 253 }
254 }
408 255
409 let mut peripheral_row = Vec::new(); 256 let mut peripheral_row = Vec::new();
410 peripheral_row.push(bi.module.clone()); 257 peripheral_row.push(bi.module.clone());
411 peripheral_row.push(name.clone()); 258 peripheral_row.push(name.clone());
412 peripherals_table.push(peripheral_row); 259 peripherals_table.push(peripheral_row);
413 260
414 if let Some(old_version) = 261 if let Some(old_version) =
415 peripheral_versions.insert(bi.module.clone(), bi.version.clone()) 262 peripheral_versions.insert(bi.module.clone(), bi.version.clone())
416 { 263 {
417 if old_version != bi.version { 264 if old_version != bi.version {
418 panic!( 265 panic!(
419 "Peripheral {} has multiple versions: {} and {}", 266 "Peripheral {} has multiple versions: {} and {}",
420 bi.module, old_version, bi.version 267 bi.module, old_version, bi.version
421 ); 268 );
422 }
423 } 269 }
424 ir_peri.block = Some(format!("{}::{}", bi.module, bi.block)); 270 }
425 271 ir_peri.block = Some(format!("{}::{}", bi.module, bi.block));
426 match bi.module.as_str() { 272
427 "gpio" => { 273 match bi.module.as_str() {
428 let port_letter = name.chars().skip(4).next().unwrap(); 274 "gpio" => {
429 assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride); 275 let port_letter = name.chars().skip(4).next().unwrap();
430 let port_num = (p.address as u32 - gpio_base) / gpio_stride; 276 assert_eq!(0, (p.address as u32 - gpio_base) % gpio_stride);
431 277 let port_num = (p.address as u32 - gpio_base) / gpio_stride;
432 for pin_num in 0..16 { 278
433 let pin_name = format!("P{}{}", port_letter, pin_num); 279 for pin_num in 0..16 {
434 pin_table.push(vec![ 280 let pin_name = format!("P{}{}", port_letter, pin_num);
435 pin_name.clone(), 281 pin_table.push(vec![
436 name.clone(), 282 pin_name.clone(),
437 port_num.to_string(), 283 name.clone(),
438 pin_num.to_string(), 284 port_num.to_string(),
439 format!("EXTI{}", pin_num), 285 pin_num.to_string(),
440 ]); 286 format!("EXTI{}", pin_num),
441 } 287 ]);
442 } 288 }
443 _ => {}
444 } 289 }
290 _ => {}
291 }
445 292
446 // Workaround for clock registers being split on some chip families. Assume fields are 293 // Workaround for clock registers being split on some chip families. Assume fields are
447 // named after peripheral and look for first field matching and use that register. 294 // named after peripheral and look for first field matching and use that register.
448 let mut en = find_reg(&rcc, "^.+ENR\\d*$", &format!("{}EN", name)); 295 let mut en = find_reg(&rcc, "^.+ENR\\d*$", &format!("{}EN", name));
449 let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name)); 296 let mut rst = find_reg(&rcc, "^.+RSTR\\d*$", &format!("{}RST", name));
450 297
451 if en.is_none() && name.ends_with("1") { 298 if en.is_none() && name.ends_with("1") {
452 en = find_reg( 299 en = find_reg(
453 &rcc, 300 &rcc,
454 "^.+ENR\\d*$", 301 "^.+ENR\\d*$",
455 &format!("{}EN", &name[..name.len() - 1]), 302 &format!("{}EN", &name[..name.len() - 1]),
456 ); 303 );
457 rst = find_reg( 304 rst = find_reg(
458 &rcc, 305 &rcc,
459 "^.+RSTR\\d*$", 306 "^.+RSTR\\d*$",
460 &format!("{}RST", &name[..name.len() - 1]), 307 &format!("{}RST", &name[..name.len() - 1]),
461 ); 308 );
462 } 309 }
463 310
464 match (en, rst) { 311 match (en, rst) {
465 (Some((enable_reg, enable_field)), reset_reg_field) => { 312 (Some((enable_reg, enable_field)), reset_reg_field) => {
466 let clock = match &p.clock { 313 let clock = match &p.clock {
467 Some(clock) => clock.as_str(), 314 Some(clock) => clock.as_str(),
468 None => { 315 None => {
469 // No clock was specified, derive the clock name from the enable register name. 316 // No clock was specified, derive the clock name from the enable register name.
470 // N.B. STM32G0 has only one APB bus but split ENR registers 317 // N.B. STM32G0 has only one APB bus but split ENR registers
471 // (e.g. APBENR1). 318 // (e.g. APBENR1).
472 Regex::new("([A-Z]+\\d*)ENR\\d*") 319 Regex::new("([A-Z]+\\d*)ENR\\d*")
473 .unwrap() 320 .unwrap()
474 .captures(enable_reg) 321 .captures(enable_reg)
475 .unwrap() 322 .unwrap()
476 .get(1) 323 .get(1)
477 .unwrap() 324 .unwrap()
478 .as_str() 325 .as_str()
479 }
480 };
481
482 let clock = if name.starts_with("TIM") {
483 format!("{}_tim", clock.to_ascii_lowercase())
484 } else {
485 clock.to_ascii_lowercase()
486 };
487
488 let mut row = Vec::with_capacity(6);
489 row.push(name.clone());
490 row.push(clock);
491 row.push(enable_reg.to_ascii_lowercase());
492
493 if let Some((reset_reg, reset_field)) = reset_reg_field {
494 row.push(reset_reg.to_ascii_lowercase());
495 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
496 row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
497 } else {
498 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
499 } 326 }
327 };
500 328
501 if !name.starts_with("GPIO") { 329 let clock = if name.starts_with("TIM") {
502 peripheral_rcc_table.push(row); 330 format!("{}_tim", clock.to_ascii_lowercase())
503 } else { 331 } else {
504 gpio_rcc_table.push(row); 332 clock.to_ascii_lowercase()
505 gpio_regs.insert(enable_reg.to_ascii_lowercase()); 333 };
506 } 334
507 } 335 let mut row = Vec::with_capacity(6);
508 (None, Some(_)) => { 336 row.push(name.clone());
509 println!("Unable to find enable register for {}", name) 337 row.push(clock);
338 row.push(enable_reg.to_ascii_lowercase());
339
340 if let Some((reset_reg, reset_field)) = reset_reg_field {
341 row.push(reset_reg.to_ascii_lowercase());
342 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
343 row.push(format!("set_{}", reset_field.to_ascii_lowercase()));
344 } else {
345 row.push(format!("set_{}", enable_field.to_ascii_lowercase()));
510 } 346 }
511 (None, None) => { 347
512 println!("Unable to find enable and reset register for {}", name) 348 if !name.starts_with("GPIO") {
349 peripheral_rcc_table.push(row);
350 } else {
351 gpio_rcc_table.push(row);
352 gpio_regs.insert(enable_reg.to_ascii_lowercase());
513 } 353 }
514 } 354 }
355 (None, Some(_)) => {
356 println!("Unable to find enable register for {}", name)
357 }
358 (None, None) => {
359 println!("Unable to find enable and reset register for {}", name)
360 }
515 } 361 }
516
517 dev.peripherals.push(ir_peri);
518 }
519
520 for reg in gpio_regs {
521 gpio_rcc_table.push(vec![reg]);
522 } 362 }
523 363
524 // We should always find GPIO RCC regs. If not, it means something 364 dev.peripherals.push(ir_peri);
525 // is broken and GPIO won't work because it's not enabled. 365 }
526 assert!(!gpio_rcc_table.is_empty());
527
528 for (id, channel_info) in &core.dma_channels {
529 let mut row = Vec::new();
530 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
531 let bi = BlockInfo::parse(dma_peri.block.as_ref().unwrap());
532
533 row.push(id.clone());
534 row.push(channel_info.dma.clone());
535 row.push(bi.module.clone());
536 row.push(channel_info.channel.to_string());
537 if let Some(dmamux) = &channel_info.dmamux {
538 let dmamux_channel = channel_info.dmamux_channel.unwrap();
539 row.push(format!(
540 "{{dmamux: {}, dmamux_channel: {}}}",
541 dmamux, dmamux_channel
542 ));
543 } else {
544 row.push("{}".to_string());
545 }
546 366
547 dma_channels_table.push(row); 367 for reg in gpio_regs {
368 gpio_rcc_table.push(vec![reg]);
369 }
548 370
549 let dma_peri_name = channel_info.dma.clone(); 371 // We should always find GPIO RCC regs. If not, it means something
550 dma_channel_counts.insert( 372 // is broken and GPIO won't work because it's not enabled.
551 dma_peri_name.clone(), 373 assert!(!gpio_rcc_table.is_empty());
552 dma_channel_counts.get(&dma_peri_name).map_or(1, |v| v + 1), 374
553 ); 375 for (id, channel_info) in &core.dma_channels {
376 let mut row = Vec::new();
377 let dma_peri = core.peripherals.get(&channel_info.dma).unwrap();
378 let bi = BlockInfo::parse(dma_peri.block.as_ref().unwrap());
379
380 row.push(id.clone());
381 row.push(channel_info.dma.clone());
382 row.push(bi.module.clone());
383 row.push(channel_info.channel.to_string());
384 if let Some(dmamux) = &channel_info.dmamux {
385 let dmamux_channel = channel_info.dmamux_channel.unwrap();
386 row.push(format!(
387 "{{dmamux: {}, dmamux_channel: {}}}",
388 dmamux, dmamux_channel
389 ));
390 } else {
391 row.push("{}".to_string());
554 } 392 }
555 393
556 for (name, &num) in &core.interrupts { 394 dma_channels_table.push(row);
557 dev.interrupts.push(ir::Interrupt { 395
558 name: name.clone(), 396 let dma_peri_name = channel_info.dma.clone();
559 description: None, 397 dma_channel_counts.insert(
560 value: num, 398 dma_peri_name.clone(),
561 }); 399 dma_channel_counts.get(&dma_peri_name).map_or(1, |v| v + 1),
400 );
401 }
402
403 for (name, &num) in &core.interrupts {
404 dev.interrupts.push(ir::Interrupt {
405 name: name.clone(),
406 description: None,
407 value: num,
408 });
562 409
563 let name = name.to_ascii_uppercase(); 410 let name = name.to_ascii_uppercase();
564 411
565 interrupt_table.push(vec![name.clone()]); 412 interrupt_table.push(vec![name.clone()]);
566 413
567 if name.contains("EXTI") { 414 if name.contains("EXTI") {
568 interrupt_table.push(vec!["EXTI".to_string(), name.clone()]); 415 interrupt_table.push(vec!["EXTI".to_string(), name.clone()]);
569 }
570 } 416 }
417 }
571 418
572 ir.devices.insert("".to_string(), dev); 419 ir.devices.insert("".to_string(), dev);
573 420
574 let mut extra = format!( 421 let mut extra = format!(
575 "pub fn GPIO(n: usize) -> gpio::Gpio {{ 422 "pub fn GPIO(n: usize) -> gpio::Gpio {{
576 gpio::Gpio(({} + {}*n) as _) 423 gpio::Gpio(({} + {}*n) as _)
577 }}", 424 }}",
578 gpio_base, gpio_stride, 425 gpio_base, gpio_stride,
579 ); 426 );
580 427
581 let peripheral_version_table = peripheral_versions 428 for (module, version) in &peripheral_versions {
582 .iter() 429 all_peripheral_versions.insert((module.clone(), version.clone()));
583 .map(|(kind, version)| vec![kind.clone(), version.clone()])
584 .collect();
585
586 make_table(&mut extra, "pins", &pin_table);
587 make_table(&mut extra, "interrupts", &interrupt_table);
588 make_table(&mut extra, "peripherals", &peripherals_table);
589 make_table(&mut extra, "peripheral_versions", &peripheral_version_table);
590 make_table(&mut extra, "peripheral_pins", &peripheral_pins_table);
591 make_table(
592 &mut extra,
593 "peripheral_dma_channels",
594 &peripheral_dma_channels_table,
595 );
596 make_table(&mut extra, "peripheral_rcc", &peripheral_rcc_table);
597 make_table(&mut extra, "gpio_rcc", &gpio_rcc_table);
598 make_table(&mut extra, "dma_channels", &dma_channels_table);
599 make_table(&mut extra, "dbgmcu", &dbgmcu_table);
600 make_peripheral_counts(&mut extra, &peripheral_counts);
601 make_dma_channel_counts(&mut extra, &dma_channel_counts);
602
603 for (module, version) in peripheral_versions {
604 all_peripheral_versions.insert((module.clone(), version.clone()));
605 write!(
606 &mut extra,
607 "#[path=\"../../peripherals/{}_{}.rs\"] pub mod {};\n",
608 module, version, module
609 )
610 .unwrap();
611 }
612 write!( 430 write!(
613 &mut extra, 431 &mut extra,
614 "pub const CORE_INDEX: usize = {};\n", 432 "#[path=\"../../peripherals/{}_{}.rs\"] pub mod {};\n",
615 core_index 433 module, version, module
616 ) 434 )
617 .unwrap(); 435 .unwrap();
436 }
437 write!(
438 &mut extra,
439 "pub const CORE_INDEX: usize = {};\n",
440 core_index
441 )
442 .unwrap();
618 443
619 // Cleanups! 444 // Cleanups!
620 transform::sort::Sort {}.run(&mut ir).unwrap(); 445 transform::sort::Sort {}.run(&mut ir).unwrap();
621 transform::Sanitize {}.run(&mut ir).unwrap(); 446 transform::Sanitize {}.run(&mut ir).unwrap();
622 447
623 let chip_dir = if chip.cores.len() > 1 { 448 // ==============================
624 out_dir.join("src/chips").join(format!( 449 // Setup chip dir
625 "{}_{}",
626 chip_name.to_ascii_lowercase(),
627 core_name.to_ascii_lowercase()
628 ))
629 } else {
630 out_dir
631 .join("src/chips")
632 .join(chip_name.to_ascii_lowercase())
633 };
634 fs::create_dir_all(&chip_dir).unwrap();
635 450
636 let items = generate::render(&ir, &generate_opts).unwrap(); 451 let chip_dir = options
637 let mut file = File::create(chip_dir.join("pac.rs")).unwrap(); 452 .out_dir
638 let data = items.to_string().replace("] ", "]\n"); 453 .join("src/chips")
454 .join(chip_core_name.to_ascii_lowercase());
455 fs::create_dir_all(&chip_dir).unwrap();
639 456
640 // Remove inner attributes like #![no_std] 457 // ==============================
641 let re = Regex::new("# *! *\\[.*\\]").unwrap(); 458 // generate pac.rs
642 let data = re.replace_all(&data, "");
643 file.write_all(data.as_bytes()).unwrap();
644 file.write_all(extra.as_bytes()).unwrap();
645 459
646 let mut device_x = String::new(); 460 let data = generate::render(&ir, &gen_opts()).unwrap().to_string();
461 let data = data.replace("] ", "]\n");
647 462
648 for (name, _) in &core.interrupts { 463 // Remove inner attributes like #![no_std]
649 write!( 464 let data = Regex::new("# *! *\\[.*\\]").unwrap().replace_all(&data, "");
650 &mut device_x,
651 "PROVIDE({} = DefaultHandler);\n",
652 name.to_ascii_uppercase()
653 )
654 .unwrap();
655 }
656 465
657 File::create(chip_dir.join("device.x")) 466 let mut file = File::create(chip_dir.join("pac.rs")).unwrap();
658 .unwrap() 467 file.write_all(data.as_bytes()).unwrap();
659 .write_all(device_x.as_bytes()) 468 file.write_all(extra.as_bytes()).unwrap();
660 .unwrap(); 469
470 let mut device_x = String::new();
471
472 for (name, _) in &core.interrupts {
473 write!(
474 &mut device_x,
475 "PROVIDE({} = DefaultHandler);\n",
476 name.to_ascii_uppercase()
477 )
478 .unwrap();
479 }
480
481 // ==============================
482 // generate mod.rs
483
484 let mut data = String::new();
485
486 write!(&mut data, "#[cfg(feature=\"pac\")] mod pac;").unwrap();
487 write!(&mut data, "#[cfg(feature=\"pac\")] pub use pac::*; ").unwrap();
488
489 let peripheral_version_table = peripheral_versions
490 .iter()
491 .map(|(kind, version)| vec![kind.clone(), version.clone()])
492 .collect();
493
494 make_table(&mut data, "pins", &pin_table);
495 make_table(&mut data, "interrupts", &interrupt_table);
496 make_table(&mut data, "peripherals", &peripherals_table);
497 make_table(&mut data, "peripheral_versions", &peripheral_version_table);
498 make_table(&mut data, "peripheral_pins", &peripheral_pins_table);
499 make_table(
500 &mut data,
501 "peripheral_dma_channels",
502 &peripheral_dma_channels_table,
503 );
504 make_table(&mut data, "peripheral_rcc", &peripheral_rcc_table);
505 make_table(&mut data, "gpio_rcc", &gpio_rcc_table);
506 make_table(&mut data, "dma_channels", &dma_channels_table);
507 make_table(&mut data, "dbgmcu", &dbgmcu_table);
508 make_peripheral_counts(&mut data, &peripheral_counts);
509 make_dma_channel_counts(&mut data, &dma_channel_counts);
510
511 let mut file = File::create(chip_dir.join("mod.rs")).unwrap();
512 file.write_all(data.as_bytes()).unwrap();
513
514 // ==============================
515 // generate device.x
516
517 File::create(chip_dir.join("device.x"))
518 .unwrap()
519 .write_all(device_x.as_bytes())
520 .unwrap();
521
522 // ==============================
523 // generate default memory.x
524 gen_memory_x(&chip_dir, &chip);
525}
526
527fn load_chip(options: &Options, name: &str) -> Chip {
528 let chip_path = options
529 .data_dir
530 .join("chips")
531 .join(&format!("{}.yaml", name));
532 let chip = fs::read(chip_path).expect(&format!("Could not load chip {}", name));
533 serde_yaml::from_slice(&chip).unwrap()
534}
535
536fn gen_opts() -> generate::Options {
537 generate::Options {
538 common_module: CommonModule::External(TokenStream::from_str("crate::common").unwrap()),
539 }
540}
541
542pub fn gen(options: Options) {
543 fs::create_dir_all(options.out_dir.join("src/peripherals")).unwrap();
544 fs::create_dir_all(options.out_dir.join("src/chips")).unwrap();
545
546 let mut all_peripheral_versions: HashSet<(String, String)> = HashSet::new();
547 let mut chip_core_names: Vec<String> = Vec::new();
548
549 for chip_name in &options.chips {
550 let chip = load_chip(&options, chip_name);
551 for (core_index, core) in chip.cores.iter().enumerate() {
552 let chip_core_name = match chip.cores.len() {
553 1 => chip_name.clone(),
554 _ => format!("{}-{}", chip_name, core.name),
555 };
661 556
662 // generate default memory.x 557 chip_core_names.push(chip_core_name.clone());
663 gen_memory_x(&chip_dir, &chip); 558 gen_chip(
559 &options,
560 &chip_core_name,
561 &chip,
562 core,
563 core_index,
564 &mut all_peripheral_versions,
565 )
566 }
664 } 567 }
665 568
666 for (module, version) in all_peripheral_versions { 569 for (module, version) in all_peripheral_versions {
667 println!("loading {} {}", module, version); 570 println!("loading {} {}", module, version);
668 571
669 let regs_path = Path::new(&data_dir) 572 let regs_path = Path::new(&options.data_dir)
670 .join("registers") 573 .join("registers")
671 .join(&format!("{}_{}.yaml", module, version)); 574 .join(&format!("{}_{}.yaml", module, version));
672 575
@@ -686,9 +589,10 @@ pub fn gen(options: Options) {
686 transform::sort::Sort {}.run(&mut ir).unwrap(); 589 transform::sort::Sort {}.run(&mut ir).unwrap();
687 transform::Sanitize {}.run(&mut ir).unwrap(); 590 transform::Sanitize {}.run(&mut ir).unwrap();
688 591
689 let items = generate::render(&ir, &generate_opts).unwrap(); 592 let items = generate::render(&ir, &gen_opts()).unwrap();
690 let mut file = File::create( 593 let mut file = File::create(
691 out_dir 594 options
595 .out_dir
692 .join("src/peripherals") 596 .join("src/peripherals")
693 .join(format!("{}_{}.rs", module, version)), 597 .join(format!("{}_{}.rs", module, version)),
694 ) 598 )
@@ -707,29 +611,20 @@ pub fn gen(options: Options) {
707 let i = bytes_find(librs, PATHS_MARKER).unwrap(); 611 let i = bytes_find(librs, PATHS_MARKER).unwrap();
708 let mut paths = String::new(); 612 let mut paths = String::new();
709 613
710 for (chip, cores) in chip_cores.iter() { 614 for name in chip_core_names {
711 let x = chip.to_ascii_lowercase(); 615 let x = name.to_ascii_lowercase();
712 if let Some(c) = cores { 616 write!(
713 write!( 617 &mut paths,
714 &mut paths, 618 "#[cfg_attr(feature=\"{}\", path = \"chips/{}/mod.rs\")]",
715 "#[cfg_attr(feature=\"{}_{}\", path = \"chips/{}_{}/pac.rs\")]", 619 x, x
716 x, c, x, c 620 )
717 ) 621 .unwrap();
718 .unwrap();
719 } else {
720 write!(
721 &mut paths,
722 "#[cfg_attr(feature=\"{}\", path = \"chips/{}/pac.rs\")]",
723 x, x
724 )
725 .unwrap();
726 }
727 } 622 }
728 let mut contents: Vec<u8> = Vec::new(); 623 let mut contents: Vec<u8> = Vec::new();
729 contents.extend(&librs[..i]); 624 contents.extend(&librs[..i]);
730 contents.extend(paths.as_bytes()); 625 contents.extend(paths.as_bytes());
731 contents.extend(&librs[i + PATHS_MARKER.len()..]); 626 contents.extend(&librs[i + PATHS_MARKER.len()..]);
732 fs::write(out_dir.join("src").join("lib_inner.rs"), &contents).unwrap(); 627 fs::write(options.out_dir.join("src").join("lib_inner.rs"), &contents).unwrap();
733 628
734 // Generate src/lib.rs 629 // Generate src/lib.rs
735 const CUT_MARKER: &[u8] = b"// GEN CUT HERE"; 630 const CUT_MARKER: &[u8] = b"// GEN CUT HERE";
@@ -738,11 +633,11 @@ pub fn gen(options: Options) {
738 let mut contents: Vec<u8> = Vec::new(); 633 let mut contents: Vec<u8> = Vec::new();
739 contents.extend(&librs[..i]); 634 contents.extend(&librs[..i]);
740 contents.extend(b"include!(\"lib_inner.rs\");\n"); 635 contents.extend(b"include!(\"lib_inner.rs\");\n");
741 fs::write(out_dir.join("src").join("lib.rs"), contents).unwrap(); 636 fs::write(options.out_dir.join("src").join("lib.rs"), contents).unwrap();
742 637
743 // Generate src/common.rs 638 // Generate src/common.rs
744 fs::write( 639 fs::write(
745 out_dir.join("src").join("common.rs"), 640 options.out_dir.join("src").join("common.rs"),
746 generate::COMMON_MODULE, 641 generate::COMMON_MODULE,
747 ) 642 )
748 .unwrap(); 643 .unwrap();
@@ -755,10 +650,14 @@ pub fn gen(options: Options) {
755 let begin = bytes_find(&contents, BUILDDEP_BEGIN).unwrap(); 650 let begin = bytes_find(&contents, BUILDDEP_BEGIN).unwrap();
756 let end = bytes_find(&contents, BUILDDEP_END).unwrap() + BUILDDEP_END.len(); 651 let end = bytes_find(&contents, BUILDDEP_END).unwrap() + BUILDDEP_END.len();
757 contents.drain(begin..end); 652 contents.drain(begin..end);
758 fs::write(out_dir.join("Cargo.toml"), contents).unwrap(); 653 fs::write(options.out_dir.join("Cargo.toml"), contents).unwrap();
759 654
760 // Generate build.rs 655 // Generate build.rs
761 fs::write(out_dir.join("build.rs"), include_bytes!("assets/build.rs")).unwrap(); 656 fs::write(
657 options.out_dir.join("build.rs"),
658 include_bytes!("assets/build.rs"),
659 )
660 .unwrap();
762} 661}
763 662
764fn bytes_find(haystack: &[u8], needle: &[u8]) -> Option<usize> { 663fn 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..7411e6cec 100644
--- a/stm32-metapac/Cargo.toml
+++ b/stm32-metapac/Cargo.toml
@@ -16,6 +16,13 @@ regex = "1.5.4"
16# END BUILD DEPENDENCIES 16# END BUILD DEPENDENCIES
17 17
18[features] 18[features]
19default = ["pac"]
20
21# Build the actual PAC. Set by default.
22# If not set, only the macrotables will be generated. You may want to not set it
23# if you're using stm32-metapac from a build.rs script to use the macros.
24pac = []
25
19rt = ["cortex-m-rt/device"] 26rt = ["cortex-m-rt/device"]
20memory-x = [] 27memory-x = []
21 28
@@ -780,40 +787,40 @@ stm32h743xg = []
780stm32h743xi = [] 787stm32h743xi = []
781stm32h743zg = [] 788stm32h743zg = []
782stm32h743zi = [] 789stm32h743zi = []
783stm32h745bg_cm7 = [] 790stm32h745bg-cm7 = []
784stm32h745bg_cm4 = [] 791stm32h745bg-cm4 = []
785stm32h745bi_cm7 = [] 792stm32h745bi-cm7 = []
786stm32h745bi_cm4 = [] 793stm32h745bi-cm4 = []
787stm32h745ig_cm7 = [] 794stm32h745ig-cm7 = []
788stm32h745ig_cm4 = [] 795stm32h745ig-cm4 = []
789stm32h745ii_cm7 = [] 796stm32h745ii-cm7 = []
790stm32h745ii_cm4 = [] 797stm32h745ii-cm4 = []
791stm32h745xg_cm7 = [] 798stm32h745xg-cm7 = []
792stm32h745xg_cm4 = [] 799stm32h745xg-cm4 = []
793stm32h745xi_cm7 = [] 800stm32h745xi-cm7 = []
794stm32h745xi_cm4 = [] 801stm32h745xi-cm4 = []
795stm32h745zg_cm7 = [] 802stm32h745zg-cm7 = []
796stm32h745zg_cm4 = [] 803stm32h745zg-cm4 = []
797stm32h745zi_cm7 = [] 804stm32h745zi-cm7 = []
798stm32h745zi_cm4 = [] 805stm32h745zi-cm4 = []
799stm32h747ag_cm7 = [] 806stm32h747ag-cm7 = []
800stm32h747ag_cm4 = [] 807stm32h747ag-cm4 = []
801stm32h747ai_cm7 = [] 808stm32h747ai-cm7 = []
802stm32h747ai_cm4 = [] 809stm32h747ai-cm4 = []
803stm32h747bg_cm7 = [] 810stm32h747bg-cm7 = []
804stm32h747bg_cm4 = [] 811stm32h747bg-cm4 = []
805stm32h747bi_cm7 = [] 812stm32h747bi-cm7 = []
806stm32h747bi_cm4 = [] 813stm32h747bi-cm4 = []
807stm32h747ig_cm7 = [] 814stm32h747ig-cm7 = []
808stm32h747ig_cm4 = [] 815stm32h747ig-cm4 = []
809stm32h747ii_cm7 = [] 816stm32h747ii-cm7 = []
810stm32h747ii_cm4 = [] 817stm32h747ii-cm4 = []
811stm32h747xg_cm7 = [] 818stm32h747xg-cm7 = []
812stm32h747xg_cm4 = [] 819stm32h747xg-cm4 = []
813stm32h747xi_cm7 = [] 820stm32h747xi-cm7 = []
814stm32h747xi_cm4 = [] 821stm32h747xi-cm4 = []
815stm32h747zi_cm7 = [] 822stm32h747zi-cm7 = []
816stm32h747zi_cm4 = [] 823stm32h747zi-cm4 = []
817stm32h750ib = [] 824stm32h750ib = []
818stm32h750vb = [] 825stm32h750vb = []
819stm32h750xb = [] 826stm32h750xb = []
@@ -824,24 +831,24 @@ stm32h753ii = []
824stm32h753vi = [] 831stm32h753vi = []
825stm32h753xi = [] 832stm32h753xi = []
826stm32h753zi = [] 833stm32h753zi = []
827stm32h755bi_cm7 = [] 834stm32h755bi-cm7 = []
828stm32h755bi_cm4 = [] 835stm32h755bi-cm4 = []
829stm32h755ii_cm7 = [] 836stm32h755ii-cm7 = []
830stm32h755ii_cm4 = [] 837stm32h755ii-cm4 = []
831stm32h755xi_cm7 = [] 838stm32h755xi-cm7 = []
832stm32h755xi_cm4 = [] 839stm32h755xi-cm4 = []
833stm32h755zi_cm7 = [] 840stm32h755zi-cm7 = []
834stm32h755zi_cm4 = [] 841stm32h755zi-cm4 = []
835stm32h757ai_cm7 = [] 842stm32h757ai-cm7 = []
836stm32h757ai_cm4 = [] 843stm32h757ai-cm4 = []
837stm32h757bi_cm7 = [] 844stm32h757bi-cm7 = []
838stm32h757bi_cm4 = [] 845stm32h757bi-cm4 = []
839stm32h757ii_cm7 = [] 846stm32h757ii-cm7 = []
840stm32h757ii_cm4 = [] 847stm32h757ii-cm4 = []
841stm32h757xi_cm7 = [] 848stm32h757xi-cm7 = []
842stm32h757xi_cm4 = [] 849stm32h757xi-cm4 = []
843stm32h757zi_cm7 = [] 850stm32h757zi-cm7 = []
844stm32h757zi_cm4 = [] 851stm32h757zi-cm4 = []
845stm32h7a3ag = [] 852stm32h7a3ag = []
846stm32h7a3ai = [] 853stm32h7a3ai = []
847stm32h7a3ig = [] 854stm32h7a3ig = []
@@ -1255,16 +1262,16 @@ stm32wb55ve = []
1255stm32wb55vg = [] 1262stm32wb55vg = []
1256stm32wb55vy = [] 1263stm32wb55vy = []
1257stm32wb5mmg = [] 1264stm32wb5mmg = []
1258stm32wl54cc_cm4 = [] 1265stm32wl54cc-cm4 = []
1259stm32wl54cc_cm0p = [] 1266stm32wl54cc-cm0p = []
1260stm32wl54jc_cm4 = [] 1267stm32wl54jc-cm4 = []
1261stm32wl54jc_cm0p = [] 1268stm32wl54jc-cm0p = []
1262stm32wl55cc_cm4 = [] 1269stm32wl55cc-cm4 = []
1263stm32wl55cc_cm0p = [] 1270stm32wl55cc-cm0p = []
1264stm32wl55jc_cm4 = [] 1271stm32wl55jc-cm4 = []
1265stm32wl55jc_cm0p = [] 1272stm32wl55jc-cm0p = []
1266stm32wl55uc_cm4 = [] 1273stm32wl55uc-cm4 = []
1267stm32wl55uc_cm0p = [] 1274stm32wl55uc-cm0p = []
1268stm32wle4c8 = [] 1275stm32wle4c8 = []
1269stm32wle4cb = [] 1276stm32wle4cb = []
1270stm32wle4cc = [] 1277stm32wle4cc = []
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");