aboutsummaryrefslogtreecommitdiff
path: root/embassy-nxp/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-nxp/build.rs')
-rw-r--r--embassy-nxp/build.rs136
1 files changed, 136 insertions, 0 deletions
diff --git a/embassy-nxp/build.rs b/embassy-nxp/build.rs
new file mode 100644
index 000000000..6c10d0e69
--- /dev/null
+++ b/embassy-nxp/build.rs
@@ -0,0 +1,136 @@
1use std::io::Write;
2use std::path::{Path, PathBuf};
3use std::process::Command;
4use std::{env, fs};
5
6use cfg_aliases::cfg_aliases;
7#[cfg(feature = "_rt1xxx")]
8use nxp_pac::metadata;
9#[allow(unused)]
10use proc_macro2::TokenStream;
11#[allow(unused)]
12use quote::quote;
13
14#[path = "./build_common.rs"]
15mod common;
16
17fn main() {
18 let mut cfgs = common::CfgSet::new();
19 common::set_target_cfgs(&mut cfgs);
20
21 let chip_name = match env::vars()
22 .map(|(a, _)| a)
23 .filter(|x| x.starts_with("CARGO_FEATURE_MIMXRT") || x.starts_with("CARGO_FEATURE_LPC"))
24 .get_one()
25 {
26 Ok(x) => x,
27 Err(GetOneError::None) => panic!("No mimxrt/lpc Cargo feature enabled"),
28 Err(GetOneError::Multiple) => panic!("Multiple mimxrt/lpc Cargo features enabled"),
29 }
30 .strip_prefix("CARGO_FEATURE_")
31 .unwrap()
32 .to_ascii_lowercase();
33
34 cfg_aliases! {
35 rt1xxx: { feature = "mimxrt1011" },
36 gpio1: { feature = "mimxrt1011" },
37 gpio2: { feature = "mimxrt1011" },
38 gpio5: { feature = "mimxrt1011" },
39 }
40
41 eprintln!("chip: {chip_name}");
42
43 generate_code();
44}
45
46#[cfg(feature = "_rt1xxx")]
47fn generate_iomuxc() -> TokenStream {
48 use proc_macro2::{Ident, Span};
49
50 let pads = metadata::iomuxc::IOMUXC_REGISTERS.iter().map(|registers| {
51 let name = Ident::new(&registers.name, Span::call_site());
52 let address = registers.pad_ctl;
53
54 quote! {
55 pub const #name: u32 = #address;
56 }
57 });
58
59 let muxes = metadata::iomuxc::IOMUXC_REGISTERS.iter().map(|registers| {
60 let name = Ident::new(&registers.name, Span::call_site());
61 let address = registers.mux_ctl;
62
63 quote! {
64 pub const #name: u32 = #address;
65 }
66 });
67
68 quote! {
69 pub mod iomuxc {
70 pub mod pads {
71 #(#pads)*
72 }
73
74 pub mod muxes {
75 #(#muxes)*
76 }
77 }
78 }
79}
80
81fn generate_code() {
82 #[allow(unused)]
83 use std::fmt::Write;
84
85 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
86 #[allow(unused_mut)]
87 let mut output = String::new();
88
89 #[cfg(feature = "_rt1xxx")]
90 writeln!(&mut output, "{}", generate_iomuxc()).unwrap();
91
92 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
93 fs::write(&out_file, output).unwrap();
94 rustfmt(&out_file);
95}
96
97/// rustfmt a given path.
98/// Failures are logged to stderr and ignored.
99fn rustfmt(path: impl AsRef<Path>) {
100 let path = path.as_ref();
101 match Command::new("rustfmt").args([path]).output() {
102 Err(e) => {
103 eprintln!("failed to exec rustfmt {:?}: {:?}", path, e);
104 }
105 Ok(out) => {
106 if !out.status.success() {
107 eprintln!("rustfmt {:?} failed:", path);
108 eprintln!("=== STDOUT:");
109 std::io::stderr().write_all(&out.stdout).unwrap();
110 eprintln!("=== STDERR:");
111 std::io::stderr().write_all(&out.stderr).unwrap();
112 }
113 }
114 }
115}
116
117enum GetOneError {
118 None,
119 Multiple,
120}
121
122trait IteratorExt: Iterator {
123 fn get_one(self) -> Result<Self::Item, GetOneError>;
124}
125
126impl<T: Iterator> IteratorExt for T {
127 fn get_one(mut self) -> Result<Self::Item, GetOneError> {
128 match self.next() {
129 None => Err(GetOneError::None),
130 Some(res) => match self.next() {
131 Some(_) => Err(GetOneError::Multiple),
132 None => Ok(res),
133 },
134 }
135 }
136}