aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-05-31 17:32:29 +0000
committerGitHub <[email protected]>2024-05-31 17:32:29 +0000
commit441ca8f64d023b6685c13d651f469573b10efd1e (patch)
treeb5954fe04970b5080f6ab079cd4b56ab93f788a0
parent694ac3a51573421c90e350c6253e2f42b4ab0bb1 (diff)
parentbfb380e8ca8c220036739e6046df79ac784d935b (diff)
Merge pull request #3005 from honzasp/check-cfg
Emit cargo:rustc-check-cfg instructions from build.rs
-rw-r--r--embassy-executor/build.rs31
-rw-r--r--embassy-executor/build_common.rs109
-rw-r--r--embassy-hal-internal/build.rs30
-rw-r--r--embassy-hal-internal/build_common.rs109
-rwxr-xr-xembassy-nrf/src/qspi.rs2
-rw-r--r--embassy-stm32/Cargo.toml4
-rw-r--r--embassy-stm32/build.rs167
-rw-r--r--embassy-stm32/build_common.rs109
-rw-r--r--embassy-stm32/src/adc/mod.rs6
-rw-r--r--embassy-stm32/src/adc/v2.rs2
-rw-r--r--embassy-stm32/src/can/bxcan/mod.rs4
-rw-r--r--embassy-stm32/src/cryp/mod.rs4
-rw-r--r--embassy-stm32/src/dsihost.rs6
-rw-r--r--embassy-stm32/src/flash/mod.rs4
-rw-r--r--embassy-stm32/src/fmc.rs4
-rw-r--r--embassy-stm32/src/rcc/bd.rs6
-rw-r--r--embassy-stm32/src/rcc/f013.rs8
-rw-r--r--embassy-stm32/src/usb/usb.rs4
-rw-r--r--embassy-sync/build.rs32
-rw-r--r--embassy-sync/build_common.rs109
-rw-r--r--embassy-sync/src/lib.rs2
-rw-r--r--rust-toolchain-nightly.toml2
22 files changed, 574 insertions, 180 deletions
diff --git a/embassy-executor/build.rs b/embassy-executor/build.rs
index 07f31e3fb..8a41d7503 100644
--- a/embassy-executor/build.rs
+++ b/embassy-executor/build.rs
@@ -3,6 +3,9 @@ use std::fmt::Write;
3use std::path::PathBuf; 3use std::path::PathBuf;
4use std::{env, fs}; 4use std::{env, fs};
5 5
6#[path = "./build_common.rs"]
7mod common;
8
6static CONFIGS: &[(&str, usize)] = &[ 9static CONFIGS: &[(&str, usize)] = &[
7 // BEGIN AUTOGENERATED CONFIG FEATURES 10 // BEGIN AUTOGENERATED CONFIG FEATURES
8 // Generated by gen_config.py. DO NOT EDIT. 11 // Generated by gen_config.py. DO NOT EDIT.
@@ -91,30 +94,6 @@ fn main() {
91 let out_file = out_dir.join("config.rs").to_string_lossy().to_string(); 94 let out_file = out_dir.join("config.rs").to_string_lossy().to_string();
92 fs::write(out_file, data).unwrap(); 95 fs::write(out_file, data).unwrap();
93 96
94 // cortex-m targets 97 let mut rustc_cfgs = common::CfgSet::new();
95 let target = env::var("TARGET").unwrap(); 98 common::set_target_cfgs(&mut rustc_cfgs);
96
97 if target.starts_with("thumbv6m-") {
98 println!("cargo:rustc-cfg=cortex_m");
99 println!("cargo:rustc-cfg=armv6m");
100 } else if target.starts_with("thumbv7m-") {
101 println!("cargo:rustc-cfg=cortex_m");
102 println!("cargo:rustc-cfg=armv7m");
103 } else if target.starts_with("thumbv7em-") {
104 println!("cargo:rustc-cfg=cortex_m");
105 println!("cargo:rustc-cfg=armv7m");
106 println!("cargo:rustc-cfg=armv7em"); // (not currently used)
107 } else if target.starts_with("thumbv8m.base") {
108 println!("cargo:rustc-cfg=cortex_m");
109 println!("cargo:rustc-cfg=armv8m");
110 println!("cargo:rustc-cfg=armv8m_base");
111 } else if target.starts_with("thumbv8m.main") {
112 println!("cargo:rustc-cfg=cortex_m");
113 println!("cargo:rustc-cfg=armv8m");
114 println!("cargo:rustc-cfg=armv8m_main");
115 }
116
117 if target.ends_with("-eabihf") {
118 println!("cargo:rustc-cfg=has_fpu");
119 }
120} 99}
diff --git a/embassy-executor/build_common.rs b/embassy-executor/build_common.rs
new file mode 100644
index 000000000..2c65f8529
--- /dev/null
+++ b/embassy-executor/build_common.rs
@@ -0,0 +1,109 @@
1// NOTE: this file is copy-pasted between several Embassy crates, because there is no
2// straightforward way to share this code:
3// - it cannot be placed into the root of the repo and linked from each build.rs using `#[path =
4// "../build_common.rs"]`, because `cargo publish` requires that all files published with a crate
5// reside in the crate's directory,
6// - it cannot be symlinked from `embassy-xxx/build_common.rs` to `../build_common.rs`, because
7// symlinks don't work on Windows.
8
9use std::collections::HashSet;
10use std::env;
11use std::ffi::OsString;
12use std::process::Command;
13
14/// Helper for emitting cargo instruction for enabling configs (`cargo:rustc-cfg=X`) and declaring
15/// them (`cargo:rust-check-cfg=cfg(X)`).
16#[derive(Debug)]
17pub struct CfgSet {
18 enabled: HashSet<String>,
19 declared: HashSet<String>,
20 emit_declared: bool,
21}
22
23impl CfgSet {
24 pub fn new() -> Self {
25 Self {
26 enabled: HashSet::new(),
27 declared: HashSet::new(),
28 emit_declared: is_rustc_nightly(),
29 }
30 }
31
32 /// Enable a config, which can then be used in `#[cfg(...)]` for conditional compilation.
33 ///
34 /// All configs that can potentially be enabled should be unconditionally declared using
35 /// [`Self::declare()`].
36 pub fn enable(&mut self, cfg: impl AsRef<str>) {
37 if self.enabled.insert(cfg.as_ref().to_owned()) {
38 println!("cargo:rustc-cfg={}", cfg.as_ref());
39 }
40 }
41
42 pub fn enable_all(&mut self, cfgs: &[impl AsRef<str>]) {
43 for cfg in cfgs.iter() {
44 self.enable(cfg.as_ref());
45 }
46 }
47
48 /// Declare a valid config for conditional compilation, without enabling it.
49 ///
50 /// This enables rustc to check that the configs in `#[cfg(...)]` attributes are valid.
51 pub fn declare(&mut self, cfg: impl AsRef<str>) {
52 if self.declared.insert(cfg.as_ref().to_owned()) && self.emit_declared {
53 println!("cargo:rustc-check-cfg=cfg({})", cfg.as_ref());
54 }
55 }
56
57 pub fn declare_all(&mut self, cfgs: &[impl AsRef<str>]) {
58 for cfg in cfgs.iter() {
59 self.declare(cfg.as_ref());
60 }
61 }
62
63 pub fn set(&mut self, cfg: impl Into<String>, enable: bool) {
64 let cfg = cfg.into();
65 if enable {
66 self.enable(cfg.clone());
67 }
68 self.declare(cfg);
69 }
70}
71
72fn is_rustc_nightly() -> bool {
73 let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
74
75 let output = Command::new(rustc)
76 .arg("--version")
77 .output()
78 .expect("failed to run `rustc --version`");
79
80 String::from_utf8_lossy(&output.stdout).contains("nightly")
81}
82
83/// Sets configs that describe the target platform.
84pub fn set_target_cfgs(cfgs: &mut CfgSet) {
85 let target = env::var("TARGET").unwrap();
86
87 if target.starts_with("thumbv6m-") {
88 cfgs.enable_all(&["cortex_m", "armv6m"]);
89 } else if target.starts_with("thumbv7m-") {
90 cfgs.enable_all(&["cortex_m", "armv7m"]);
91 } else if target.starts_with("thumbv7em-") {
92 cfgs.enable_all(&["cortex_m", "armv7m", "armv7em"]);
93 } else if target.starts_with("thumbv8m.base") {
94 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_base"]);
95 } else if target.starts_with("thumbv8m.main") {
96 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_main"]);
97 }
98 cfgs.declare_all(&[
99 "cortex_m",
100 "armv6m",
101 "armv7m",
102 "armv7em",
103 "armv8m",
104 "armv8m_base",
105 "armv8m_main",
106 ]);
107
108 cfgs.set("has_fpu", target.ends_with("-eabihf"));
109}
diff --git a/embassy-hal-internal/build.rs b/embassy-hal-internal/build.rs
index 6fe82b44f..ecd2c0c9f 100644
--- a/embassy-hal-internal/build.rs
+++ b/embassy-hal-internal/build.rs
@@ -1,29 +1,7 @@
1use std::env; 1#[path = "./build_common.rs"]
2mod common;
2 3
3fn main() { 4fn main() {
4 let target = env::var("TARGET").unwrap(); 5 let mut cfgs = common::CfgSet::new();
5 6 common::set_target_cfgs(&mut cfgs);
6 if target.starts_with("thumbv6m-") {
7 println!("cargo:rustc-cfg=cortex_m");
8 println!("cargo:rustc-cfg=armv6m");
9 } else if target.starts_with("thumbv7m-") {
10 println!("cargo:rustc-cfg=cortex_m");
11 println!("cargo:rustc-cfg=armv7m");
12 } else if target.starts_with("thumbv7em-") {
13 println!("cargo:rustc-cfg=cortex_m");
14 println!("cargo:rustc-cfg=armv7m");
15 println!("cargo:rustc-cfg=armv7em"); // (not currently used)
16 } else if target.starts_with("thumbv8m.base") {
17 println!("cargo:rustc-cfg=cortex_m");
18 println!("cargo:rustc-cfg=armv8m");
19 println!("cargo:rustc-cfg=armv8m_base");
20 } else if target.starts_with("thumbv8m.main") {
21 println!("cargo:rustc-cfg=cortex_m");
22 println!("cargo:rustc-cfg=armv8m");
23 println!("cargo:rustc-cfg=armv8m_main");
24 }
25
26 if target.ends_with("-eabihf") {
27 println!("cargo:rustc-cfg=has_fpu");
28 }
29} 7}
diff --git a/embassy-hal-internal/build_common.rs b/embassy-hal-internal/build_common.rs
new file mode 100644
index 000000000..2c65f8529
--- /dev/null
+++ b/embassy-hal-internal/build_common.rs
@@ -0,0 +1,109 @@
1// NOTE: this file is copy-pasted between several Embassy crates, because there is no
2// straightforward way to share this code:
3// - it cannot be placed into the root of the repo and linked from each build.rs using `#[path =
4// "../build_common.rs"]`, because `cargo publish` requires that all files published with a crate
5// reside in the crate's directory,
6// - it cannot be symlinked from `embassy-xxx/build_common.rs` to `../build_common.rs`, because
7// symlinks don't work on Windows.
8
9use std::collections::HashSet;
10use std::env;
11use std::ffi::OsString;
12use std::process::Command;
13
14/// Helper for emitting cargo instruction for enabling configs (`cargo:rustc-cfg=X`) and declaring
15/// them (`cargo:rust-check-cfg=cfg(X)`).
16#[derive(Debug)]
17pub struct CfgSet {
18 enabled: HashSet<String>,
19 declared: HashSet<String>,
20 emit_declared: bool,
21}
22
23impl CfgSet {
24 pub fn new() -> Self {
25 Self {
26 enabled: HashSet::new(),
27 declared: HashSet::new(),
28 emit_declared: is_rustc_nightly(),
29 }
30 }
31
32 /// Enable a config, which can then be used in `#[cfg(...)]` for conditional compilation.
33 ///
34 /// All configs that can potentially be enabled should be unconditionally declared using
35 /// [`Self::declare()`].
36 pub fn enable(&mut self, cfg: impl AsRef<str>) {
37 if self.enabled.insert(cfg.as_ref().to_owned()) {
38 println!("cargo:rustc-cfg={}", cfg.as_ref());
39 }
40 }
41
42 pub fn enable_all(&mut self, cfgs: &[impl AsRef<str>]) {
43 for cfg in cfgs.iter() {
44 self.enable(cfg.as_ref());
45 }
46 }
47
48 /// Declare a valid config for conditional compilation, without enabling it.
49 ///
50 /// This enables rustc to check that the configs in `#[cfg(...)]` attributes are valid.
51 pub fn declare(&mut self, cfg: impl AsRef<str>) {
52 if self.declared.insert(cfg.as_ref().to_owned()) && self.emit_declared {
53 println!("cargo:rustc-check-cfg=cfg({})", cfg.as_ref());
54 }
55 }
56
57 pub fn declare_all(&mut self, cfgs: &[impl AsRef<str>]) {
58 for cfg in cfgs.iter() {
59 self.declare(cfg.as_ref());
60 }
61 }
62
63 pub fn set(&mut self, cfg: impl Into<String>, enable: bool) {
64 let cfg = cfg.into();
65 if enable {
66 self.enable(cfg.clone());
67 }
68 self.declare(cfg);
69 }
70}
71
72fn is_rustc_nightly() -> bool {
73 let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
74
75 let output = Command::new(rustc)
76 .arg("--version")
77 .output()
78 .expect("failed to run `rustc --version`");
79
80 String::from_utf8_lossy(&output.stdout).contains("nightly")
81}
82
83/// Sets configs that describe the target platform.
84pub fn set_target_cfgs(cfgs: &mut CfgSet) {
85 let target = env::var("TARGET").unwrap();
86
87 if target.starts_with("thumbv6m-") {
88 cfgs.enable_all(&["cortex_m", "armv6m"]);
89 } else if target.starts_with("thumbv7m-") {
90 cfgs.enable_all(&["cortex_m", "armv7m"]);
91 } else if target.starts_with("thumbv7em-") {
92 cfgs.enable_all(&["cortex_m", "armv7m", "armv7em"]);
93 } else if target.starts_with("thumbv8m.base") {
94 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_base"]);
95 } else if target.starts_with("thumbv8m.main") {
96 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_main"]);
97 }
98 cfgs.declare_all(&[
99 "cortex_m",
100 "armv6m",
101 "armv7m",
102 "armv7em",
103 "armv8m",
104 "armv8m_base",
105 "armv8m_main",
106 ]);
107
108 cfgs.set("has_fpu", target.ends_with("-eabihf"));
109}
diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs
index 060fe72cd..d40096edc 100755
--- a/embassy-nrf/src/qspi.rs
+++ b/embassy-nrf/src/qspi.rs
@@ -166,7 +166,7 @@ impl<'d, T: Instance> Qspi<'d, T> {
166 $pin.conf().write(|w| { 166 $pin.conf().write(|w| {
167 w.dir().output(); 167 w.dir().output();
168 w.drive().h0h1(); 168 w.drive().h0h1();
169 #[cfg(feature = "_nrf5340-s")] 169 #[cfg(all(feature = "_nrf5340", feature = "_s"))]
170 w.mcusel().peripheral(); 170 w.mcusel().peripheral();
171 w 171 w
172 }); 172 });
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 4f0d7356d..6a1dfec26 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -72,7 +72,7 @@ rand_core = "0.6.3"
72sdio-host = "0.5.0" 72sdio-host = "0.5.0"
73critical-section = "1.1" 73critical-section = "1.1"
74#stm32-metapac = { version = "15" } 74#stm32-metapac = { version = "15" }
75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad633a3e266151ea4d8fad630031a075ee02ab34" } 75stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-59b1f65bd109c3ef35782e6c44062208d0ef3d0e" }
76 76
77vcell = "0.1.3" 77vcell = "0.1.3"
78nb = "1.0.0" 78nb = "1.0.0"
@@ -97,7 +97,7 @@ proc-macro2 = "1.0.36"
97quote = "1.0.15" 97quote = "1.0.15"
98 98
99#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]} 99#stm32-metapac = { version = "15", default-features = false, features = ["metadata"]}
100stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-ad633a3e266151ea4d8fad630031a075ee02ab34", default-features = false, features = ["metadata"]} 100stm32-metapac = { git = "https://github.com/embassy-rs/stm32-data-generated", tag = "stm32-data-59b1f65bd109c3ef35782e6c44062208d0ef3d0e", default-features = false, features = ["metadata"] }
101 101
102[features] 102[features]
103default = ["rt"] 103default = ["rt"]
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 6c524ced6..6aedcc228 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -9,35 +9,16 @@ use proc_macro2::{Ident, TokenStream};
9use quote::{format_ident, quote}; 9use quote::{format_ident, quote};
10use stm32_metapac::metadata::ir::BitOffset; 10use stm32_metapac::metadata::ir::BitOffset;
11use stm32_metapac::metadata::{ 11use stm32_metapac::metadata::{
12 MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, METADATA, 12 MemoryRegionKind, PeripheralRccKernelClock, PeripheralRccRegister, PeripheralRegisters, StopMode, ALL_CHIPS,
13 ALL_PERIPHERAL_VERSIONS, METADATA,
13}; 14};
14 15
15fn main() { 16#[path = "./build_common.rs"]
16 let target = env::var("TARGET").unwrap(); 17mod common;
17
18 if target.starts_with("thumbv6m-") {
19 println!("cargo:rustc-cfg=cortex_m");
20 println!("cargo:rustc-cfg=armv6m");
21 } else if target.starts_with("thumbv7m-") {
22 println!("cargo:rustc-cfg=cortex_m");
23 println!("cargo:rustc-cfg=armv7m");
24 } else if target.starts_with("thumbv7em-") {
25 println!("cargo:rustc-cfg=cortex_m");
26 println!("cargo:rustc-cfg=armv7m");
27 println!("cargo:rustc-cfg=armv7em"); // (not currently used)
28 } else if target.starts_with("thumbv8m.base") {
29 println!("cargo:rustc-cfg=cortex_m");
30 println!("cargo:rustc-cfg=armv8m");
31 println!("cargo:rustc-cfg=armv8m_base");
32 } else if target.starts_with("thumbv8m.main") {
33 println!("cargo:rustc-cfg=cortex_m");
34 println!("cargo:rustc-cfg=armv8m");
35 println!("cargo:rustc-cfg=armv8m_main");
36 }
37 18
38 if target.ends_with("-eabihf") { 19fn main() {
39 println!("cargo:rustc-cfg=has_fpu"); 20 let mut cfgs = common::CfgSet::new();
40 } 21 common::set_target_cfgs(&mut cfgs);
41 22
42 let chip_name = match env::vars() 23 let chip_name = match env::vars()
43 .map(|(a, _)| a) 24 .map(|(a, _)| a)
@@ -56,8 +37,15 @@ fn main() {
56 37
57 for p in METADATA.peripherals { 38 for p in METADATA.peripherals {
58 if let Some(r) = &p.registers { 39 if let Some(r) = &p.registers {
59 println!("cargo:rustc-cfg={}", r.kind); 40 cfgs.enable(r.kind);
60 println!("cargo:rustc-cfg={}_{}", r.kind, r.version); 41 cfgs.enable(format!("{}_{}", r.kind, r.version));
42 }
43 }
44
45 for &(kind, versions) in ALL_PERIPHERAL_VERSIONS.iter() {
46 cfgs.declare(kind);
47 for &version in versions.iter() {
48 cfgs.declare(format!("{}_{}", kind, version));
61 } 49 }
62 } 50 }
63 51
@@ -67,7 +55,13 @@ fn main() {
67 let mut singletons: Vec<String> = Vec::new(); 55 let mut singletons: Vec<String> = Vec::new();
68 for p in METADATA.peripherals { 56 for p in METADATA.peripherals {
69 if let Some(r) = &p.registers { 57 if let Some(r) = &p.registers {
70 println!("cargo:rustc-cfg=peri_{}", p.name.to_ascii_lowercase()); 58 if r.kind == "adccommon" || r.kind == "sai" || r.kind == "ucpd" {
59 // TODO: should we emit this for all peripherals? if so, we will need a list of all
60 // possible peripherals across all chips, so that we can declare the configs
61 // (replacing the hard-coded list of `peri_*` cfgs below)
62 cfgs.enable(format!("peri_{}", p.name.to_ascii_lowercase()));
63 }
64
71 match r.kind { 65 match r.kind {
72 // Generate singletons per pin, not per port 66 // Generate singletons per pin, not per port
73 "gpio" => { 67 "gpio" => {
@@ -87,7 +81,7 @@ fn main() {
87 if pin.signal.starts_with("MCO") { 81 if pin.signal.starts_with("MCO") {
88 let name = pin.signal.replace('_', "").to_string(); 82 let name = pin.signal.replace('_', "").to_string();
89 if !singletons.contains(&name) { 83 if !singletons.contains(&name) {
90 println!("cargo:rustc-cfg={}", name.to_ascii_lowercase()); 84 cfgs.enable(name.to_ascii_lowercase());
91 singletons.push(name); 85 singletons.push(name);
92 } 86 }
93 } 87 }
@@ -106,6 +100,20 @@ fn main() {
106 } 100 }
107 } 101 }
108 102
103 cfgs.declare_all(&[
104 "peri_adc1_common",
105 "peri_adc3_common",
106 "peri_adc12_common",
107 "peri_adc34_common",
108 "peri_sai1",
109 "peri_sai2",
110 "peri_sai3",
111 "peri_sai4",
112 "peri_ucpd1",
113 "peri_ucpd2",
114 ]);
115 cfgs.declare_all(&["mco", "mco1", "mco2"]);
116
109 // One singleton per EXTI line 117 // One singleton per EXTI line
110 for pin_num in 0..16 { 118 for pin_num in 0..16 {
111 singletons.push(format!("EXTI{}", pin_num)); 119 singletons.push(format!("EXTI{}", pin_num));
@@ -221,7 +229,13 @@ fn main() {
221 }; 229 };
222 230
223 if !time_driver_singleton.is_empty() { 231 if !time_driver_singleton.is_empty() {
224 println!("cargo:rustc-cfg=time_driver_{}", time_driver_singleton.to_lowercase()); 232 cfgs.enable(format!("time_driver_{}", time_driver_singleton.to_lowercase()));
233 }
234 for tim in [
235 "tim1", "tim2", "tim3", "tim4", "tim5", "tim8", "tim9", "tim12", "tim15", "tim20", "tim21", "tim22", "tim23",
236 "tim24",
237 ] {
238 cfgs.declare(format!("time_driver_{}", tim));
225 } 239 }
226 240
227 // ======== 241 // ========
@@ -1593,54 +1607,65 @@ fn main() {
1593 rustfmt(&out_file); 1607 rustfmt(&out_file);
1594 1608
1595 // ======== 1609 // ========
1596 // Multicore 1610 // Configs for multicore and for targeting groups of chips
1597
1598 let mut s = chip_name.split('_');
1599 let mut chip_name: String = s.next().unwrap().to_string();
1600 let core_name = if let Some(c) = s.next() {
1601 if !c.starts_with("CM") {
1602 chip_name.push('_');
1603 chip_name.push_str(c);
1604 None
1605 } else {
1606 Some(c)
1607 }
1608 } else {
1609 None
1610 };
1611 1611
1612 if let Some(core) = core_name { 1612 fn get_chip_cfgs(chip_name: &str) -> Vec<String> {
1613 println!("cargo:rustc-cfg={}_{}", &chip_name[..chip_name.len() - 2], core); 1613 let mut cfgs = Vec::new();
1614 }
1615 1614
1616 // ======= 1615 // Multicore
1617 // Features for targeting groups of chips
1618 1616
1619 if &chip_name[..8] == "stm32wba" { 1617 let mut s = chip_name.split('_');
1620 println!("cargo:rustc-cfg={}", &chip_name[..8]); // stm32wba 1618 let mut chip_name: String = s.next().unwrap().to_string();
1621 println!("cargo:rustc-cfg={}", &chip_name[..10]); // stm32wba52 1619 let core_name = if let Some(c) = s.next() {
1622 println!("cargo:rustc-cfg=package_{}", &chip_name[10..11]); 1620 if !c.starts_with("CM") {
1623 println!("cargo:rustc-cfg=flashsize_{}", &chip_name[11..12]); 1621 chip_name.push('_');
1624 } else { 1622 chip_name.push_str(c);
1625 if &chip_name[..8] == "stm32h7r" || &chip_name[..8] == "stm32h7s" { 1623 None
1626 println!("cargo:rustc-cfg=stm32h7rs"); 1624 } else {
1625 Some(c)
1626 }
1627 } else { 1627 } else {
1628 println!("cargo:rustc-cfg={}", &chip_name[..7]); // stm32f4 1628 None
1629 };
1630
1631 if let Some(core) = core_name {
1632 cfgs.push(format!("{}_{}", &chip_name[..chip_name.len() - 2], core));
1629 } 1633 }
1630 println!("cargo:rustc-cfg={}", &chip_name[..9]); // stm32f429
1631 println!("cargo:rustc-cfg={}x", &chip_name[..8]); // stm32f42x
1632 println!("cargo:rustc-cfg={}x{}", &chip_name[..7], &chip_name[8..9]); // stm32f4x9
1633 println!("cargo:rustc-cfg=package_{}", &chip_name[9..10]);
1634 println!("cargo:rustc-cfg=flashsize_{}", &chip_name[10..11]);
1635 }
1636 1634
1637 // Mark the L4+ chips as they have many differences to regular L4. 1635 // Configs for targeting groups of chips
1638 if &chip_name[..7] == "stm32l4" { 1636 if &chip_name[..8] == "stm32wba" {
1639 if "pqrs".contains(&chip_name[7..8]) { 1637 cfgs.push(chip_name[..8].to_owned()); // stm32wba
1640 println!("cargo:rustc-cfg=stm32l4_plus"); 1638 cfgs.push(chip_name[..10].to_owned()); // stm32wba52
1639 cfgs.push(format!("package_{}", &chip_name[10..11]));
1640 cfgs.push(format!("flashsize_{}", &chip_name[11..12]));
1641 } else { 1641 } else {
1642 println!("cargo:rustc-cfg=stm32l4_nonplus"); 1642 if &chip_name[..8] == "stm32h7r" || &chip_name[..8] == "stm32h7s" {
1643 cfgs.push("stm32h7rs".to_owned());
1644 } else {
1645 cfgs.push(chip_name[..7].to_owned()); // stm32f4
1646 }
1647 cfgs.push(chip_name[..9].to_owned()); // stm32f429
1648 cfgs.push(format!("{}x", &chip_name[..8])); // stm32f42x
1649 cfgs.push(format!("{}x{}", &chip_name[..7], &chip_name[8..9])); // stm32f4x9
1650 cfgs.push(format!("package_{}", &chip_name[9..10]));
1651 cfgs.push(format!("flashsize_{}", &chip_name[10..11]));
1652 }
1653
1654 // Mark the L4+ chips as they have many differences to regular L4.
1655 if &chip_name[..7] == "stm32l4" {
1656 if "pqrs".contains(&chip_name[7..8]) {
1657 cfgs.push("stm32l4_plus".to_owned());
1658 } else {
1659 cfgs.push("stm32l4_nonplus".to_owned());
1660 }
1643 } 1661 }
1662
1663 cfgs
1664 }
1665
1666 cfgs.enable_all(&get_chip_cfgs(&chip_name));
1667 for &chip_name in ALL_CHIPS.iter() {
1668 cfgs.declare_all(&get_chip_cfgs(&chip_name.to_ascii_lowercase()));
1644 } 1669 }
1645 1670
1646 println!("cargo:rerun-if-changed=build.rs"); 1671 println!("cargo:rerun-if-changed=build.rs");
diff --git a/embassy-stm32/build_common.rs b/embassy-stm32/build_common.rs
new file mode 100644
index 000000000..2c65f8529
--- /dev/null
+++ b/embassy-stm32/build_common.rs
@@ -0,0 +1,109 @@
1// NOTE: this file is copy-pasted between several Embassy crates, because there is no
2// straightforward way to share this code:
3// - it cannot be placed into the root of the repo and linked from each build.rs using `#[path =
4// "../build_common.rs"]`, because `cargo publish` requires that all files published with a crate
5// reside in the crate's directory,
6// - it cannot be symlinked from `embassy-xxx/build_common.rs` to `../build_common.rs`, because
7// symlinks don't work on Windows.
8
9use std::collections::HashSet;
10use std::env;
11use std::ffi::OsString;
12use std::process::Command;
13
14/// Helper for emitting cargo instruction for enabling configs (`cargo:rustc-cfg=X`) and declaring
15/// them (`cargo:rust-check-cfg=cfg(X)`).
16#[derive(Debug)]
17pub struct CfgSet {
18 enabled: HashSet<String>,
19 declared: HashSet<String>,
20 emit_declared: bool,
21}
22
23impl CfgSet {
24 pub fn new() -> Self {
25 Self {
26 enabled: HashSet::new(),
27 declared: HashSet::new(),
28 emit_declared: is_rustc_nightly(),
29 }
30 }
31
32 /// Enable a config, which can then be used in `#[cfg(...)]` for conditional compilation.
33 ///
34 /// All configs that can potentially be enabled should be unconditionally declared using
35 /// [`Self::declare()`].
36 pub fn enable(&mut self, cfg: impl AsRef<str>) {
37 if self.enabled.insert(cfg.as_ref().to_owned()) {
38 println!("cargo:rustc-cfg={}", cfg.as_ref());
39 }
40 }
41
42 pub fn enable_all(&mut self, cfgs: &[impl AsRef<str>]) {
43 for cfg in cfgs.iter() {
44 self.enable(cfg.as_ref());
45 }
46 }
47
48 /// Declare a valid config for conditional compilation, without enabling it.
49 ///
50 /// This enables rustc to check that the configs in `#[cfg(...)]` attributes are valid.
51 pub fn declare(&mut self, cfg: impl AsRef<str>) {
52 if self.declared.insert(cfg.as_ref().to_owned()) && self.emit_declared {
53 println!("cargo:rustc-check-cfg=cfg({})", cfg.as_ref());
54 }
55 }
56
57 pub fn declare_all(&mut self, cfgs: &[impl AsRef<str>]) {
58 for cfg in cfgs.iter() {
59 self.declare(cfg.as_ref());
60 }
61 }
62
63 pub fn set(&mut self, cfg: impl Into<String>, enable: bool) {
64 let cfg = cfg.into();
65 if enable {
66 self.enable(cfg.clone());
67 }
68 self.declare(cfg);
69 }
70}
71
72fn is_rustc_nightly() -> bool {
73 let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
74
75 let output = Command::new(rustc)
76 .arg("--version")
77 .output()
78 .expect("failed to run `rustc --version`");
79
80 String::from_utf8_lossy(&output.stdout).contains("nightly")
81}
82
83/// Sets configs that describe the target platform.
84pub fn set_target_cfgs(cfgs: &mut CfgSet) {
85 let target = env::var("TARGET").unwrap();
86
87 if target.starts_with("thumbv6m-") {
88 cfgs.enable_all(&["cortex_m", "armv6m"]);
89 } else if target.starts_with("thumbv7m-") {
90 cfgs.enable_all(&["cortex_m", "armv7m"]);
91 } else if target.starts_with("thumbv7em-") {
92 cfgs.enable_all(&["cortex_m", "armv7m", "armv7em"]);
93 } else if target.starts_with("thumbv8m.base") {
94 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_base"]);
95 } else if target.starts_with("thumbv8m.main") {
96 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_main"]);
97 }
98 cfgs.declare_all(&[
99 "cortex_m",
100 "armv6m",
101 "armv7m",
102 "armv7em",
103 "armv8m",
104 "armv8m_base",
105 "armv8m_main",
106 ]);
107
108 cfgs.set("has_fpu", target.ends_with("-eabihf"));
109}
diff --git a/embassy-stm32/src/adc/mod.rs b/embassy-stm32/src/adc/mod.rs
index 040ee9c53..0c22a7dae 100644
--- a/embassy-stm32/src/adc/mod.rs
+++ b/embassy-stm32/src/adc/mod.rs
@@ -71,9 +71,9 @@ pub(crate) trait SealedAdcChannel<T> {
71/// Performs a busy-wait delay for a specified number of microseconds. 71/// Performs a busy-wait delay for a specified number of microseconds.
72#[allow(unused)] 72#[allow(unused)]
73pub(crate) fn blocking_delay_us(us: u32) { 73pub(crate) fn blocking_delay_us(us: u32) {
74 #[cfg(time)] 74 #[cfg(feature = "time")]
75 embassy_time::block_for(embassy_time::Duration::from_micros(us)); 75 embassy_time::block_for(embassy_time::Duration::from_micros(us as u64));
76 #[cfg(not(time))] 76 #[cfg(not(feature = "time"))]
77 { 77 {
78 let freq = unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 as u64; 78 let freq = unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 as u64;
79 let us = us as u64; 79 let us = us as u64;
diff --git a/embassy-stm32/src/adc/v2.rs b/embassy-stm32/src/adc/v2.rs
index 77e8bb56f..e3175dff5 100644
--- a/embassy-stm32/src/adc/v2.rs
+++ b/embassy-stm32/src/adc/v2.rs
@@ -31,7 +31,7 @@ impl AdcChannel<ADC1> for Temperature {}
31impl super::SealedAdcChannel<ADC1> for Temperature { 31impl super::SealedAdcChannel<ADC1> for Temperature {
32 fn channel(&self) -> u8 { 32 fn channel(&self) -> u8 {
33 cfg_if::cfg_if! { 33 cfg_if::cfg_if! {
34 if #[cfg(any(stm32f2, stm32f40, stm32f41))] { 34 if #[cfg(any(stm32f2, stm32f40x, stm32f41x))] {
35 16 35 16
36 } else { 36 } else {
37 18 37 18
diff --git a/embassy-stm32/src/can/bxcan/mod.rs b/embassy-stm32/src/can/bxcan/mod.rs
index 69e20e909..9f7df1e71 100644
--- a/embassy-stm32/src/can/bxcan/mod.rs
+++ b/embassy-stm32/src/can/bxcan/mod.rs
@@ -1132,8 +1132,8 @@ foreach_peripheral!(
1132 (can, CAN1) => { 1132 (can, CAN1) => {
1133 cfg_if::cfg_if! { 1133 cfg_if::cfg_if! {
1134 if #[cfg(all( 1134 if #[cfg(all(
1135 any(stm32l4, stm32f72, stm32f73), 1135 any(stm32l4, stm32f72x, stm32f73x),
1136 not(any(stm32l49, stm32l4a)) 1136 not(any(stm32l49x, stm32l4ax))
1137 ))] { 1137 ))] {
1138 // Most L4 devices and some F7 devices use the name "CAN1" 1138 // Most L4 devices and some F7 devices use the name "CAN1"
1139 // even if there is no "CAN2" peripheral. 1139 // even if there is no "CAN2" peripheral.
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs
index ad118ef6e..8d600c73c 100644
--- a/embassy-stm32/src/cryp/mod.rs
+++ b/embassy-stm32/src/cryp/mod.rs
@@ -744,7 +744,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Aes
744 } else { 744 } else {
745 aad_header[0] = 0xFF; 745 aad_header[0] = 0xFF;
746 aad_header[1] = 0xFE; 746 aad_header[1] = 0xFE;
747 let aad_len_bytes: [u8; 4] = aad_len.to_be_bytes(); 747 let aad_len_bytes: [u8; 4] = (aad_len as u32).to_be_bytes();
748 aad_header[2] = aad_len_bytes[0]; 748 aad_header[2] = aad_len_bytes[0];
749 aad_header[3] = aad_len_bytes[1]; 749 aad_header[3] = aad_len_bytes[1];
750 aad_header[4] = aad_len_bytes[2]; 750 aad_header[4] = aad_len_bytes[2];
@@ -765,7 +765,7 @@ impl<'c, const KEY_SIZE: usize, const TAG_SIZE: usize, const IV_SIZE: usize> Aes
765 block0[0] |= ((((TAG_SIZE as u8) - 2) >> 1) & 0x07) << 3; 765 block0[0] |= ((((TAG_SIZE as u8) - 2) >> 1) & 0x07) << 3;
766 block0[0] |= ((15 - (iv.len() as u8)) - 1) & 0x07; 766 block0[0] |= ((15 - (iv.len() as u8)) - 1) & 0x07;
767 block0[1..1 + iv.len()].copy_from_slice(iv); 767 block0[1..1 + iv.len()].copy_from_slice(iv);
768 let payload_len_bytes: [u8; 4] = payload_len.to_be_bytes(); 768 let payload_len_bytes: [u8; 4] = (payload_len as u32).to_be_bytes();
769 if iv.len() <= 11 { 769 if iv.len() <= 11 {
770 block0[12] = payload_len_bytes[0]; 770 block0[12] = payload_len_bytes[0];
771 } else if payload_len_bytes[0] > 0 { 771 } else if payload_len_bytes[0] > 0 {
diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs
index dc58bca92..e1fb3b0b0 100644
--- a/embassy-stm32/src/dsihost.rs
+++ b/embassy-stm32/src/dsihost.rs
@@ -11,9 +11,9 @@ use crate::{peripherals, Peripheral};
11 11
12/// Performs a busy-wait delay for a specified number of microseconds. 12/// Performs a busy-wait delay for a specified number of microseconds.
13pub fn blocking_delay_ms(ms: u32) { 13pub fn blocking_delay_ms(ms: u32) {
14 #[cfg(time)] 14 #[cfg(feature = "time")]
15 embassy_time::block_for(embassy_time::Duration::from_millis(ms)); 15 embassy_time::block_for(embassy_time::Duration::from_millis(ms as u64));
16 #[cfg(not(time))] 16 #[cfg(not(feature = "time"))]
17 cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 1_000 * ms); 17 cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 1_000 * ms);
18} 18}
19 19
diff --git a/embassy-stm32/src/flash/mod.rs b/embassy-stm32/src/flash/mod.rs
index 8c6ca2471..ce2d1a04c 100644
--- a/embassy-stm32/src/flash/mod.rs
+++ b/embassy-stm32/src/flash/mod.rs
@@ -96,7 +96,7 @@ pub enum FlashBank {
96#[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")] 96#[cfg_attr(any(flash_f1, flash_f3), path = "f1f3.rs")]
97#[cfg_attr(flash_f4, path = "f4.rs")] 97#[cfg_attr(flash_f4, path = "f4.rs")]
98#[cfg_attr(flash_f7, path = "f7.rs")] 98#[cfg_attr(flash_f7, path = "f7.rs")]
99#[cfg_attr(any(flash_g0, flash_g4), path = "g.rs")] 99#[cfg_attr(any(flash_g0, flash_g4c2, flash_g4c3, flash_g4c4), path = "g.rs")]
100#[cfg_attr(flash_h7, path = "h7.rs")] 100#[cfg_attr(flash_h7, path = "h7.rs")]
101#[cfg_attr(flash_h7ab, path = "h7.rs")] 101#[cfg_attr(flash_h7ab, path = "h7.rs")]
102#[cfg_attr(flash_u5, path = "u5.rs")] 102#[cfg_attr(flash_u5, path = "u5.rs")]
@@ -105,7 +105,7 @@ pub enum FlashBank {
105#[cfg_attr( 105#[cfg_attr(
106 not(any( 106 not(any(
107 flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f3, flash_f4, flash_f7, flash_g0, 107 flash_l0, flash_l1, flash_l4, flash_wl, flash_wb, flash_f0, flash_f1, flash_f3, flash_f4, flash_f7, flash_g0,
108 flash_g4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0 108 flash_g4c2, flash_g4c3, flash_g4c4, flash_h7, flash_h7ab, flash_u5, flash_h50, flash_u0
109 )), 109 )),
110 path = "other.rs" 110 path = "other.rs"
111)] 111)]
diff --git a/embassy-stm32/src/fmc.rs b/embassy-stm32/src/fmc.rs
index 0df64f711..82d8089f4 100644
--- a/embassy-stm32/src/fmc.rs
+++ b/embassy-stm32/src/fmc.rs
@@ -35,7 +35,7 @@ where
35 // fmc v1 and v2 does not have the fmcen bit 35 // fmc v1 and v2 does not have the fmcen bit
36 // fsmc v1, v2 and v3 does not have the fmcen bit 36 // fsmc v1, v2 and v3 does not have the fmcen bit
37 // This is a "not" because it is expected that all future versions have this bit 37 // This is a "not" because it is expected that all future versions have this bit
38 #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1, fmc_v4)))] 38 #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fmc_v4)))]
39 T::REGS.bcr1().modify(|r| r.set_fmcen(true)); 39 T::REGS.bcr1().modify(|r| r.set_fmcen(true));
40 #[cfg(any(fmc_v4))] 40 #[cfg(any(fmc_v4))]
41 T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true)); 41 T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
@@ -61,7 +61,7 @@ where
61 // fmc v1 and v2 does not have the fmcen bit 61 // fmc v1 and v2 does not have the fmcen bit
62 // fsmc v1, v2 and v3 does not have the fmcen bit 62 // fsmc v1, v2 and v3 does not have the fmcen bit
63 // This is a "not" because it is expected that all future versions have this bit 63 // This is a "not" because it is expected that all future versions have this bit
64 #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fsmc_v2x3, fsmc_v3x1, fmc_v4)))] 64 #[cfg(not(any(fmc_v1x3, fmc_v2x1, fsmc_v1x0, fsmc_v1x3, fmc_v4)))]
65 T::REGS.bcr1().modify(|r| r.set_fmcen(true)); 65 T::REGS.bcr1().modify(|r| r.set_fmcen(true));
66 #[cfg(any(fmc_v4))] 66 #[cfg(any(fmc_v4))]
67 T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true)); 67 T::REGS.nor_psram().bcr1().modify(|r| r.set_fmcen(true));
diff --git a/embassy-stm32/src/rcc/bd.rs b/embassy-stm32/src/rcc/bd.rs
index f3ac4fdbe..4e9c18594 100644
--- a/embassy-stm32/src/rcc/bd.rs
+++ b/embassy-stm32/src/rcc/bd.rs
@@ -33,7 +33,7 @@ pub enum LseDrive {
33} 33}
34 34
35// All families but these have the LSEDRV register 35// All families but these have the LSEDRV register
36#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] 36#[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f410, rcc_l1)))]
37impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv { 37impl From<LseDrive> for crate::pac::rcc::vals::Lsedrv {
38 fn from(value: LseDrive) -> Self { 38 fn from(value: LseDrive) -> Self {
39 use crate::pac::rcc::vals::Lsedrv; 39 use crate::pac::rcc::vals::Lsedrv;
@@ -186,7 +186,7 @@ impl LsConfig {
186 } 186 }
187 ok &= reg.lseon() == lse_en; 187 ok &= reg.lseon() == lse_en;
188 ok &= reg.lsebyp() == lse_byp; 188 ok &= reg.lsebyp() == lse_byp;
189 #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] 189 #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f410, rcc_l1)))]
190 if let Some(lse_drv) = lse_drv { 190 if let Some(lse_drv) = lse_drv {
191 ok &= reg.lsedrv() == lse_drv.into(); 191 ok &= reg.lsedrv() == lse_drv.into();
192 } 192 }
@@ -224,7 +224,7 @@ impl LsConfig {
224 224
225 if lse_en { 225 if lse_en {
226 bdcr().modify(|w| { 226 bdcr().modify(|w| {
227 #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f400, rcc_f410, rcc_l1)))] 227 #[cfg(not(any(rcc_f1, rcc_f1cl, rcc_f100, rcc_f2, rcc_f4, rcc_f410, rcc_l1)))]
228 if let Some(lse_drv) = lse_drv { 228 if let Some(lse_drv) = lse_drv {
229 w.set_lsedrv(lse_drv.into()); 229 w.set_lsedrv(lse_drv.into());
230 } 230 }
diff --git a/embassy-stm32/src/rcc/f013.rs b/embassy-stm32/src/rcc/f013.rs
index 1c951a22b..63dc27bdd 100644
--- a/embassy-stm32/src/rcc/f013.rs
+++ b/embassy-stm32/src/rcc/f013.rs
@@ -95,7 +95,7 @@ pub struct Config {
95 95
96 #[cfg(all(stm32f3, not(rcc_f37)))] 96 #[cfg(all(stm32f3, not(rcc_f37)))]
97 pub adc: AdcClockSource, 97 pub adc: AdcClockSource,
98 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 98 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
99 pub adc34: AdcClockSource, 99 pub adc34: AdcClockSource,
100 100
101 /// Per-peripheral kernel clock selection muxes 101 /// Per-peripheral kernel clock selection muxes
@@ -125,7 +125,7 @@ impl Default for Config {
125 125
126 #[cfg(all(stm32f3, not(rcc_f37)))] 126 #[cfg(all(stm32f3, not(rcc_f37)))]
127 adc: AdcClockSource::Hclk(AdcHclkPrescaler::Div1), 127 adc: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
128 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 128 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
129 adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1), 129 adc34: AdcClockSource::Hclk(AdcHclkPrescaler::Div1),
130 130
131 mux: Default::default(), 131 mux: Default::default(),
@@ -339,7 +339,7 @@ pub(crate) unsafe fn init(config: Config) {
339 } 339 }
340 }; 340 };
341 341
342 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 342 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
343 let adc34 = { 343 let adc34 = {
344 #[cfg(peri_adc3_common)] 344 #[cfg(peri_adc3_common)]
345 let common = crate::pac::ADC3_COMMON; 345 let common = crate::pac::ADC3_COMMON;
@@ -404,7 +404,7 @@ pub(crate) unsafe fn init(config: Config) {
404 hclk1: Some(hclk), 404 hclk1: Some(hclk),
405 #[cfg(all(stm32f3, not(rcc_f37)))] 405 #[cfg(all(stm32f3, not(rcc_f37)))]
406 adc: Some(adc), 406 adc: Some(adc),
407 #[cfg(all(stm32f3, not(rcc_f37), adc3_common))] 407 #[cfg(all(stm32f3, not(rcc_f37), any(peri_adc3_common, peri_adc34_common)))]
408 adc34: Some(adc34), 408 adc34: Some(adc34),
409 rtc: rtc, 409 rtc: rtc,
410 hsi48: hsi48, 410 hsi48: hsi48,
diff --git a/embassy-stm32/src/usb/usb.rs b/embassy-stm32/src/usb/usb.rs
index 81a2d2623..b6c88ac9a 100644
--- a/embassy-stm32/src/usb/usb.rs
+++ b/embassy-stm32/src/usb/usb.rs
@@ -267,9 +267,9 @@ impl<'d, T: Instance> Driver<'d, T> {
267 w.set_fres(true); 267 w.set_fres(true);
268 }); 268 });
269 269
270 #[cfg(time)] 270 #[cfg(feature = "time")]
271 embassy_time::block_for(embassy_time::Duration::from_millis(100)); 271 embassy_time::block_for(embassy_time::Duration::from_millis(100));
272 #[cfg(not(time))] 272 #[cfg(not(feature = "time"))]
273 cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 10); 273 cortex_m::asm::delay(unsafe { crate::rcc::get_freqs() }.sys.unwrap().0 / 10);
274 274
275 #[cfg(not(usb_v4))] 275 #[cfg(not(usb_v4))]
diff --git a/embassy-sync/build.rs b/embassy-sync/build.rs
index afd76dad1..ecd2c0c9f 100644
--- a/embassy-sync/build.rs
+++ b/embassy-sync/build.rs
@@ -1,31 +1,7 @@
1use std::env; 1#[path = "./build_common.rs"]
2mod common;
2 3
3fn main() { 4fn main() {
4 println!("cargo:rerun-if-changed=build.rs"); 5 let mut cfgs = common::CfgSet::new();
5 6 common::set_target_cfgs(&mut cfgs);
6 let target = env::var("TARGET").unwrap();
7
8 if target.starts_with("thumbv6m-") {
9 println!("cargo:rustc-cfg=cortex_m");
10 println!("cargo:rustc-cfg=armv6m");
11 } else if target.starts_with("thumbv7m-") {
12 println!("cargo:rustc-cfg=cortex_m");
13 println!("cargo:rustc-cfg=armv7m");
14 } else if target.starts_with("thumbv7em-") {
15 println!("cargo:rustc-cfg=cortex_m");
16 println!("cargo:rustc-cfg=armv7m");
17 println!("cargo:rustc-cfg=armv7em"); // (not currently used)
18 } else if target.starts_with("thumbv8m.base") {
19 println!("cargo:rustc-cfg=cortex_m");
20 println!("cargo:rustc-cfg=armv8m");
21 println!("cargo:rustc-cfg=armv8m_base");
22 } else if target.starts_with("thumbv8m.main") {
23 println!("cargo:rustc-cfg=cortex_m");
24 println!("cargo:rustc-cfg=armv8m");
25 println!("cargo:rustc-cfg=armv8m_main");
26 }
27
28 if target.ends_with("-eabihf") {
29 println!("cargo:rustc-cfg=has_fpu");
30 }
31} 7}
diff --git a/embassy-sync/build_common.rs b/embassy-sync/build_common.rs
new file mode 100644
index 000000000..2c65f8529
--- /dev/null
+++ b/embassy-sync/build_common.rs
@@ -0,0 +1,109 @@
1// NOTE: this file is copy-pasted between several Embassy crates, because there is no
2// straightforward way to share this code:
3// - it cannot be placed into the root of the repo and linked from each build.rs using `#[path =
4// "../build_common.rs"]`, because `cargo publish` requires that all files published with a crate
5// reside in the crate's directory,
6// - it cannot be symlinked from `embassy-xxx/build_common.rs` to `../build_common.rs`, because
7// symlinks don't work on Windows.
8
9use std::collections::HashSet;
10use std::env;
11use std::ffi::OsString;
12use std::process::Command;
13
14/// Helper for emitting cargo instruction for enabling configs (`cargo:rustc-cfg=X`) and declaring
15/// them (`cargo:rust-check-cfg=cfg(X)`).
16#[derive(Debug)]
17pub struct CfgSet {
18 enabled: HashSet<String>,
19 declared: HashSet<String>,
20 emit_declared: bool,
21}
22
23impl CfgSet {
24 pub fn new() -> Self {
25 Self {
26 enabled: HashSet::new(),
27 declared: HashSet::new(),
28 emit_declared: is_rustc_nightly(),
29 }
30 }
31
32 /// Enable a config, which can then be used in `#[cfg(...)]` for conditional compilation.
33 ///
34 /// All configs that can potentially be enabled should be unconditionally declared using
35 /// [`Self::declare()`].
36 pub fn enable(&mut self, cfg: impl AsRef<str>) {
37 if self.enabled.insert(cfg.as_ref().to_owned()) {
38 println!("cargo:rustc-cfg={}", cfg.as_ref());
39 }
40 }
41
42 pub fn enable_all(&mut self, cfgs: &[impl AsRef<str>]) {
43 for cfg in cfgs.iter() {
44 self.enable(cfg.as_ref());
45 }
46 }
47
48 /// Declare a valid config for conditional compilation, without enabling it.
49 ///
50 /// This enables rustc to check that the configs in `#[cfg(...)]` attributes are valid.
51 pub fn declare(&mut self, cfg: impl AsRef<str>) {
52 if self.declared.insert(cfg.as_ref().to_owned()) && self.emit_declared {
53 println!("cargo:rustc-check-cfg=cfg({})", cfg.as_ref());
54 }
55 }
56
57 pub fn declare_all(&mut self, cfgs: &[impl AsRef<str>]) {
58 for cfg in cfgs.iter() {
59 self.declare(cfg.as_ref());
60 }
61 }
62
63 pub fn set(&mut self, cfg: impl Into<String>, enable: bool) {
64 let cfg = cfg.into();
65 if enable {
66 self.enable(cfg.clone());
67 }
68 self.declare(cfg);
69 }
70}
71
72fn is_rustc_nightly() -> bool {
73 let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
74
75 let output = Command::new(rustc)
76 .arg("--version")
77 .output()
78 .expect("failed to run `rustc --version`");
79
80 String::from_utf8_lossy(&output.stdout).contains("nightly")
81}
82
83/// Sets configs that describe the target platform.
84pub fn set_target_cfgs(cfgs: &mut CfgSet) {
85 let target = env::var("TARGET").unwrap();
86
87 if target.starts_with("thumbv6m-") {
88 cfgs.enable_all(&["cortex_m", "armv6m"]);
89 } else if target.starts_with("thumbv7m-") {
90 cfgs.enable_all(&["cortex_m", "armv7m"]);
91 } else if target.starts_with("thumbv7em-") {
92 cfgs.enable_all(&["cortex_m", "armv7m", "armv7em"]);
93 } else if target.starts_with("thumbv8m.base") {
94 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_base"]);
95 } else if target.starts_with("thumbv8m.main") {
96 cfgs.enable_all(&["cortex_m", "armv8m", "armv8m_main"]);
97 }
98 cfgs.declare_all(&[
99 "cortex_m",
100 "armv6m",
101 "armv7m",
102 "armv7em",
103 "armv8m",
104 "armv8m_base",
105 "armv8m_main",
106 ]);
107
108 cfgs.set("has_fpu", target.ends_with("-eabihf"));
109}
diff --git a/embassy-sync/src/lib.rs b/embassy-sync/src/lib.rs
index 1873483f9..a5eee8d02 100644
--- a/embassy-sync/src/lib.rs
+++ b/embassy-sync/src/lib.rs
@@ -1,4 +1,4 @@
1#![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] 1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(async_fn_in_trait)] 2#![allow(async_fn_in_trait)]
3#![allow(clippy::new_without_default)] 3#![allow(clippy::new_without_default)]
4#![doc = include_str!("../README.md")] 4#![doc = include_str!("../README.md")]
diff --git a/rust-toolchain-nightly.toml b/rust-toolchain-nightly.toml
index ac160b995..2143c1b2d 100644
--- a/rust-toolchain-nightly.toml
+++ b/rust-toolchain-nightly.toml
@@ -1,5 +1,5 @@
1[toolchain] 1[toolchain]
2channel = "nightly-2024-04-14" 2channel = "nightly-2024-05-20"
3components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ] 3components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ]
4targets = [ 4targets = [
5 "thumbv7em-none-eabi", 5 "thumbv7em-none-eabi",