diff options
| author | Rasmus Melchior Jacobsen <[email protected]> | 2023-03-25 05:57:15 +0100 |
|---|---|---|
| committer | Rasmus Melchior Jacobsen <[email protected]> | 2023-03-25 05:57:15 +0100 |
| commit | cccceb88f2c91adcbdc6c1d07d785a97742f996b (patch) | |
| tree | 45635622512a03d57562ec5cca26b3d940daa32a | |
| parent | d8b265856f73ae0e7985a6c2fe1a8f0fb811328d (diff) | |
Generate flash regions during build
| -rw-r--r-- | embassy-stm32/build.rs | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index dbfc1370d..892819120 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -5,7 +5,7 @@ use std::{env, fs}; | |||
| 5 | 5 | ||
| 6 | use proc_macro2::TokenStream; | 6 | use proc_macro2::TokenStream; |
| 7 | use quote::{format_ident, quote}; | 7 | use quote::{format_ident, quote}; |
| 8 | use stm32_metapac::metadata::METADATA; | 8 | use stm32_metapac::metadata::{MemoryRegionKind, METADATA}; |
| 9 | 9 | ||
| 10 | fn main() { | 10 | fn main() { |
| 11 | let chip_name = match env::vars() | 11 | let chip_name = match env::vars() |
| @@ -104,6 +104,68 @@ fn main() { | |||
| 104 | }); | 104 | }); |
| 105 | 105 | ||
| 106 | // ======== | 106 | // ======== |
| 107 | // Generate FLASH regions | ||
| 108 | let mut flash_regions = TokenStream::new(); | ||
| 109 | let flash_memory_regions = METADATA | ||
| 110 | .memory | ||
| 111 | .iter() | ||
| 112 | .filter(|x| x.kind == MemoryRegionKind::Flash || x.kind == MemoryRegionKind::Otp); | ||
| 113 | for region in flash_memory_regions.clone() { | ||
| 114 | let region_name = format_ident!("{}", region.name); | ||
| 115 | let base = region.address as usize; | ||
| 116 | let size = region.size as usize; | ||
| 117 | let settings = region.settings.as_ref().unwrap(); | ||
| 118 | let erase_size = settings.erase_size as usize; | ||
| 119 | let write_size = settings.write_size as usize; | ||
| 120 | let erase_value = settings.erase_value; | ||
| 121 | |||
| 122 | flash_regions.extend(quote! { | ||
| 123 | pub struct #region_name(()); | ||
| 124 | }); | ||
| 125 | |||
| 126 | flash_regions.extend(quote! { | ||
| 127 | impl crate::flash::FlashRegion for #region_name { | ||
| 128 | const BASE: usize = #base; | ||
| 129 | const SIZE: usize = #size; | ||
| 130 | const ERASE_SIZE: usize = #erase_size; | ||
| 131 | const WRITE_SIZE: usize = #write_size; | ||
| 132 | const ERASE_VALUE: u8 = #erase_value; | ||
| 133 | } | ||
| 134 | }); | ||
| 135 | } | ||
| 136 | |||
| 137 | let (fields, inits): (Vec<TokenStream>, Vec<TokenStream>) = flash_memory_regions | ||
| 138 | .map(|f| { | ||
| 139 | let field_name = format_ident!("{}", f.name.to_lowercase()); | ||
| 140 | let field_type = format_ident!("{}", f.name); | ||
| 141 | let field = quote! { | ||
| 142 | pub #field_name: #field_type | ||
| 143 | }; | ||
| 144 | let init = quote! { | ||
| 145 | #field_name: #field_type(()) | ||
| 146 | }; | ||
| 147 | |||
| 148 | (field, init) | ||
| 149 | }) | ||
| 150 | .unzip(); | ||
| 151 | |||
| 152 | flash_regions.extend(quote! { | ||
| 153 | pub struct FlashRegions { | ||
| 154 | #(#fields),* | ||
| 155 | } | ||
| 156 | |||
| 157 | impl FlashRegions { | ||
| 158 | pub(crate) const fn take() -> Self { | ||
| 159 | Self { | ||
| 160 | #(#inits),* | ||
| 161 | } | ||
| 162 | } | ||
| 163 | } | ||
| 164 | }); | ||
| 165 | |||
| 166 | g.extend(quote! { pub mod flash_regions { #flash_regions } }); | ||
| 167 | |||
| 168 | // ======== | ||
| 107 | // Generate DMA IRQs. | 169 | // Generate DMA IRQs. |
| 108 | 170 | ||
| 109 | let mut dma_irqs: HashMap<&str, Vec<(&str, &str)>> = HashMap::new(); | 171 | let mut dma_irqs: HashMap<&str, Vec<(&str, &str)>> = HashMap::new(); |
| @@ -558,11 +620,22 @@ fn main() { | |||
| 558 | // ======== | 620 | // ======== |
| 559 | // Write foreach_foo! macrotables | 621 | // Write foreach_foo! macrotables |
| 560 | 622 | ||
| 623 | let mut flash_regions_table: Vec<Vec<String>> = Vec::new(); | ||
| 561 | let mut interrupts_table: Vec<Vec<String>> = Vec::new(); | 624 | let mut interrupts_table: Vec<Vec<String>> = Vec::new(); |
| 562 | let mut peripherals_table: Vec<Vec<String>> = Vec::new(); | 625 | let mut peripherals_table: Vec<Vec<String>> = Vec::new(); |
| 563 | let mut pins_table: Vec<Vec<String>> = Vec::new(); | 626 | let mut pins_table: Vec<Vec<String>> = Vec::new(); |
| 564 | let mut dma_channels_table: Vec<Vec<String>> = Vec::new(); | 627 | let mut dma_channels_table: Vec<Vec<String>> = Vec::new(); |
| 565 | 628 | ||
| 629 | for m in METADATA | ||
| 630 | .memory | ||
| 631 | .iter() | ||
| 632 | .filter(|m| m.kind == MemoryRegionKind::Flash || m.kind == MemoryRegionKind::Otp) | ||
| 633 | { | ||
| 634 | let mut row = Vec::new(); | ||
| 635 | row.push(m.name.to_string()); | ||
| 636 | flash_regions_table.push(row); | ||
| 637 | } | ||
| 638 | |||
| 566 | let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as u32; | 639 | let gpio_base = METADATA.peripherals.iter().find(|p| p.name == "GPIOA").unwrap().address as u32; |
| 567 | let gpio_stride = 0x400; | 640 | let gpio_stride = 0x400; |
| 568 | 641 | ||
| @@ -659,6 +732,7 @@ fn main() { | |||
| 659 | 732 | ||
| 660 | let mut m = String::new(); | 733 | let mut m = String::new(); |
| 661 | 734 | ||
| 735 | make_table(&mut m, "foreach_flash_region", &flash_regions_table); | ||
| 662 | make_table(&mut m, "foreach_interrupt", &interrupts_table); | 736 | make_table(&mut m, "foreach_interrupt", &interrupts_table); |
| 663 | make_table(&mut m, "foreach_peripheral", &peripherals_table); | 737 | make_table(&mut m, "foreach_peripheral", &peripherals_table); |
| 664 | make_table(&mut m, "foreach_pin", &pins_table); | 738 | make_table(&mut m, "foreach_pin", &pins_table); |
