aboutsummaryrefslogtreecommitdiff
path: root/embassy-mspm0/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-mspm0/build.rs')
-rw-r--r--embassy-mspm0/build.rs116
1 files changed, 97 insertions, 19 deletions
diff --git a/embassy-mspm0/build.rs b/embassy-mspm0/build.rs
index d294bc422..ac40adbdf 100644
--- a/embassy-mspm0/build.rs
+++ b/embassy-mspm0/build.rs
@@ -16,21 +16,22 @@ use quote::{format_ident, quote};
16mod common; 16mod common;
17 17
18fn main() { 18fn main() {
19 generate_code();
20 interrupt_group_linker_magic();
21}
22
23fn generate_code() {
24 let mut cfgs = common::CfgSet::new(); 19 let mut cfgs = common::CfgSet::new();
25 common::set_target_cfgs(&mut cfgs); 20 common::set_target_cfgs(&mut cfgs);
26 21
22 generate_code(&mut cfgs);
23 select_gpio_features(&mut cfgs);
24 interrupt_group_linker_magic();
25}
26
27fn generate_code(cfgs: &mut CfgSet) {
27 #[cfg(any(feature = "rt"))] 28 #[cfg(any(feature = "rt"))]
28 println!( 29 println!(
29 "cargo:rustc-link-search={}", 30 "cargo:rustc-link-search={}",
30 PathBuf::from(env::var_os("OUT_DIR").unwrap()).display(), 31 PathBuf::from(env::var_os("OUT_DIR").unwrap()).display(),
31 ); 32 );
32 33
33 cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1"]); 34 cfgs.declare_all(&["gpio_pb", "gpio_pc", "int_group1", "unicomm"]);
34 35
35 let chip_name = match env::vars() 36 let chip_name = match env::vars()
36 .map(|(a, _)| a) 37 .map(|(a, _)| a)
@@ -53,9 +54,9 @@ fn generate_code() {
53 cfgs.declare_all(&get_chip_cfgs(&chip)); 54 cfgs.declare_all(&get_chip_cfgs(&chip));
54 } 55 }
55 56
56 let mut singletons = get_singletons(&mut cfgs); 57 let mut singletons = get_singletons(cfgs);
57 58
58 time_driver(&mut singletons, &mut cfgs); 59 time_driver(&mut singletons, cfgs);
59 60
60 let mut g = TokenStream::new(); 61 let mut g = TokenStream::new();
61 62
@@ -68,7 +69,7 @@ fn generate_code() {
68 g.extend(generate_pin_trait_impls()); 69 g.extend(generate_pin_trait_impls());
69 g.extend(generate_groups()); 70 g.extend(generate_groups());
70 g.extend(generate_dma_channel_count()); 71 g.extend(generate_dma_channel_count());
71 g.extend(generate_adc_constants(&mut cfgs)); 72 g.extend(generate_adc_constants(cfgs));
72 73
73 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); 74 let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
74 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string(); 75 let out_file = out_dir.join("_generated.rs").to_string_lossy().to_string();
@@ -115,6 +116,14 @@ fn get_chip_cfgs(chip_name: &str) -> Vec<String> {
115 cfgs.push("mspm0g351x".to_string()); 116 cfgs.push("mspm0g351x".to_string());
116 } 117 }
117 118
119 if chip_name.starts_with("mspm0g518") {
120 cfgs.push("mspm0g518x".to_string());
121 }
122
123 if chip_name.starts_with("mspm0h321") {
124 cfgs.push("mspm0h321x".to_string());
125 }
126
118 if chip_name.starts_with("mspm0l110") { 127 if chip_name.starts_with("mspm0l110") {
119 cfgs.push("mspm0l110x".to_string()); 128 cfgs.push("mspm0l110x".to_string());
120 } 129 }
@@ -189,8 +198,15 @@ fn generate_groups() -> TokenStream {
189 use crate::pac::#group_enum; 198 use crate::pac::#group_enum;
190 199
191 let group = crate::pac::CPUSS.int_group(#group_number); 200 let group = crate::pac::CPUSS.int_group(#group_number);
192 // MUST subtract by 1 since 0 is NO_INTR 201 let stat = group.iidx().read().stat();
193 let iidx = group.iidx().read().stat().to_bits() - 1; 202
203 // check for spurious interrupts
204 if stat == crate::pac::cpuss::vals::Iidx::NO_INTR {
205 return;
206 }
207
208 // MUST subtract by 1 because NO_INTR offsets IIDX values.
209 let iidx = stat.to_bits() - 1;
194 210
195 let Ok(group) = #group_enum::try_from(iidx as u8) else { 211 let Ok(group) = #group_enum::try_from(iidx as u8) else {
196 return; 212 return;
@@ -208,7 +224,7 @@ fn generate_groups() -> TokenStream {
208 224
209 #[cfg(feature = "rt")] 225 #[cfg(feature = "rt")]
210 mod group_vectors { 226 mod group_vectors {
211 extern "Rust" { 227 unsafe extern "Rust" {
212 #(#group_vectors)* 228 #(#group_vectors)*
213 } 229 }
214 } 230 }
@@ -288,6 +304,15 @@ fn get_singletons(cfgs: &mut common::CfgSet) -> Vec<Singleton> {
288 // by the HAL. 304 // by the HAL.
289 "iomux" | "cpuss" => true, 305 "iomux" | "cpuss" => true,
290 306
307 // Unicomm instances get their own singletons, but we need to enable a cfg for unicomm drivers.
308 "unicomm" => {
309 cfgs.enable("unicomm");
310 false
311 }
312
313 // TODO: Remove after TIMB is fixed
314 "tim" if peripheral.name.starts_with("TIMB") => true,
315
291 _ => false, 316 _ => false,
292 }; 317 };
293 318
@@ -411,6 +436,8 @@ fn time_driver(singletons: &mut Vec<Singleton>, cfgs: &mut CfgSet) {
411 // Verify the selected timer is available 436 // Verify the selected timer is available
412 let selected_timer = match time_driver.as_ref().map(|x| x.as_ref()) { 437 let selected_timer = match time_driver.as_ref().map(|x| x.as_ref()) {
413 None => "", 438 None => "",
439 // TODO: Fix TIMB0
440 // Some("timb0") => "TIMB0",
414 Some("timg0") => "TIMG0", 441 Some("timg0") => "TIMG0",
415 Some("timg1") => "TIMG1", 442 Some("timg1") => "TIMG1",
416 Some("timg2") => "TIMG2", 443 Some("timg2") => "TIMG2",
@@ -428,16 +455,17 @@ fn time_driver(singletons: &mut Vec<Singleton>, cfgs: &mut CfgSet) {
428 Some("tima1") => "TIMA1", 455 Some("tima1") => "TIMA1",
429 Some("any") => { 456 Some("any") => {
430 // Order of timer candidates: 457 // Order of timer candidates:
431 // 1. 16-bit, 2 channel 458 // 1. Basic timers
432 // 2. 16-bit, 2 channel with shadow registers 459 // 2. 16-bit, 2 channel
433 // 3. 16-bit, 4 channel 460 // 3. 16-bit, 2 channel with shadow registers
434 // 4. 16-bit with QEI 461 // 4. 16-bit, 4 channel
435 // 5. Advanced timers 462 // 5. 16-bit with QEI
463 // 6. Advanced timers
436 // 464 //
437 // TODO: Select RTC first if available
438 // TODO: 32-bit timers are not considered yet 465 // TODO: 32-bit timers are not considered yet
439 [ 466 [
440 // 16-bit, 2 channel 467 // basic timers. No PWM pins
468 // "TIMB0", // 16-bit, 2 channel
441 "TIMG0", "TIMG1", "TIMG2", "TIMG3", // 16-bit, 2 channel with shadow registers 469 "TIMG0", "TIMG1", "TIMG2", "TIMG3", // 16-bit, 2 channel with shadow registers
442 "TIMG4", "TIMG5", "TIMG6", "TIMG7", // 16-bit, 4 channel 470 "TIMG4", "TIMG5", "TIMG6", "TIMG7", // 16-bit, 4 channel
443 "TIMG14", // 16-bit with QEI 471 "TIMG14", // 16-bit with QEI
@@ -507,6 +535,8 @@ fn generate_timers() -> TokenStream {
507 .peripherals 535 .peripherals
508 .iter() 536 .iter()
509 .filter(|p| p.name.starts_with("TIM")) 537 .filter(|p| p.name.starts_with("TIM"))
538 // TODO: Fix TIMB when used at time driver.
539 .filter(|p| !p.name.starts_with("TIMB"))
510 .map(|peripheral| { 540 .map(|peripheral| {
511 let name = Ident::new(&peripheral.name, Span::call_site()); 541 let name = Ident::new(&peripheral.name, Span::call_site());
512 let timers = &*TIMERS; 542 let timers = &*TIMERS;
@@ -579,6 +609,7 @@ fn generate_peripheral_instances() -> TokenStream {
579 "i2c" => Some(quote! { impl_i2c_instance!(#peri, #fifo_size); }), 609 "i2c" => Some(quote! { impl_i2c_instance!(#peri, #fifo_size); }),
580 "wwdt" => Some(quote! { impl_wwdt_instance!(#peri); }), 610 "wwdt" => Some(quote! { impl_wwdt_instance!(#peri); }),
581 "adc" => Some(quote! { impl_adc_instance!(#peri); }), 611 "adc" => Some(quote! { impl_adc_instance!(#peri); }),
612 "mathacl" => Some(quote! { impl_mathacl_instance!(#peri); }),
582 _ => None, 613 _ => None,
583 }; 614 };
584 615
@@ -646,6 +677,35 @@ fn generate_pin_trait_impls() -> TokenStream {
646 } 677 }
647} 678}
648 679
680fn select_gpio_features(cfgs: &mut CfgSet) {
681 cfgs.declare_all(&[
682 "gpioa_interrupt",
683 "gpioa_group",
684 "gpiob_interrupt",
685 "gpiob_group",
686 "gpioc_group",
687 ]);
688
689 for interrupt in METADATA.interrupts.iter() {
690 match interrupt.name {
691 "GPIOA" => cfgs.enable("gpioa_interrupt"),
692 "GPIOB" => cfgs.enable("gpiob_interrupt"),
693 _ => (),
694 }
695 }
696
697 for group in METADATA.interrupt_groups.iter() {
698 for interrupt in group.interrupts {
699 match interrupt.name {
700 "GPIOA" => cfgs.enable("gpioa_group"),
701 "GPIOB" => cfgs.enable("gpiob_group"),
702 "GPIOC" => cfgs.enable("gpioc_group"),
703 _ => (),
704 }
705 }
706 }
707}
708
649/// rustfmt a given path. 709/// rustfmt a given path.
650/// Failures are logged to stderr and ignored. 710/// Failures are logged to stderr and ignored.
651fn rustfmt(path: impl AsRef<Path>) { 711fn rustfmt(path: impl AsRef<Path>) {
@@ -688,6 +748,24 @@ struct TimerDesc {
688const TIMERS: LazyLock<HashMap<String, TimerDesc>> = LazyLock::new(|| { 748const TIMERS: LazyLock<HashMap<String, TimerDesc>> = LazyLock::new(|| {
689 let mut map = HashMap::new(); 749 let mut map = HashMap::new();
690 map.insert( 750 map.insert(
751 "TIMB0".into(),
752 TimerDesc {
753 bits: 16,
754 prescaler: true,
755 repeat_counter: false,
756 ccp_channels_internal: 2,
757 ccp_channels_external: 2,
758 external_pwm_channels: 0,
759 phase_load: false,
760 shadow_load: false,
761 shadow_ccs: false,
762 deadband: false,
763 fault_handler: false,
764 qei_hall: false,
765 },
766 );
767
768 map.insert(
691 "TIMG0".into(), 769 "TIMG0".into(),
692 TimerDesc { 770 TimerDesc {
693 bits: 16, 771 bits: 16,