diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index a6434a7e..ed2b4c50 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -1,6 +1,6 @@ use std::env; +use std::fs; use std::path::PathBuf; -use std::process::Command; fn main() { let chip_name = env::vars_os() @@ -11,17 +11,72 @@ fn main() { .unwrap() .to_ascii_lowercase(); + struct Peripheral { + kind: String, + name: String, + } + + let mut peripherals: Vec = Vec::new(); + stm32_metapac::peripherals!( + ($kind:ident, $name:ident) => { + peripherals.push(Peripheral{ + kind: stringify!($kind).to_string(), + name: stringify!($name).to_string(), + }); + }; + ); + + let mut singletons: Vec = Vec::new(); + for p in peripherals { + match p.kind.as_str() { + // Generate singletons per pin, not per port + "gpio" => { + println!("{}", p.name); + let port_letter = p.name.strip_prefix("GPIO").unwrap(); + for pin_num in 0..16 { + singletons.push(format!("P{}{}", port_letter, pin_num)); + } + } + + // No singleton for these, the HAL handles them specially. + "exti" => {} + + // We *shouldn't* have singletons for these, but the HAL currently requires + // singletons, for using with RccPeripheral to enable/disable clocks to them. + //"rcc" => {} + //"dbgmcu" => {} + //"syscfg" => {} + //"dma" => {} + //"bdma" => {} + //"dmamux" => {} + + // For other peripherals, one singleton per peri + _ => singletons.push(p.name.clone()), + } + } + + // One singleton per EXTI line + for pin_num in 0..16 { + singletons.push(format!("EXTI{}", pin_num)); + } + + // One singleton per DMA channel + stm32_metapac::dma_channels! { + ($channel_peri:ident, $dma_peri:ident, $version:ident, $channel_num:expr, $ignore:tt) => { + singletons.push(stringify!($channel_peri).to_string()); + }; + } + let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); let out_file = out_dir.join("generated.rs").to_string_lossy().to_string(); - - let exit_code = Command::new("python3") - .args(&["gen.py", &chip_name, &out_file]) - .status() - .expect("failed to execute gen.py"); - - if !exit_code.success() { - panic!("gen.py exited with {:?}", exit_code) - } + fs::write( + out_file, + format!( + "embassy_hal_common::peripherals!({});", + singletons.join(",") + ), + ) + .unwrap(); stm32_metapac::peripheral_versions!( ($peri:ident, $version:ident) => { diff --git a/embassy-stm32/gen.py b/embassy-stm32/gen.py deleted file mode 100644 index e589f2f0..00000000 --- a/embassy-stm32/gen.py +++ /dev/null @@ -1,88 +0,0 @@ -import sys -import yaml -import re -import os -import re - -try: - from yaml import CSafeLoader as SafeLoader -except ImportError: - from yaml import SafeLoader - - -abspath = os.path.abspath(__file__) -dname = os.path.dirname(abspath) -os.chdir(dname) - -data_path = '../stm32-data/data' - -try: - _, chip_name, output_file = sys.argv -except: - raise Exception("Usage: gen.py STM32F429ZI_CM0 path/to/generated.rs") - -c = chip_name.split('_', 1) - -chip_name = c[0].upper() -core_name = None - -if len(c) > 1: - core_name = c[1].lower() - -# ======= load chip -with open(f'{data_path}/chips/{chip_name}.yaml', 'r') as f: - chip = yaml.load(f, Loader=SafeLoader) - -# ======= Generate! -with open(output_file, 'w') as f: - singletons = [] # USART1, PA5, EXTI8 - exti_interrupts = [] # EXTI IRQs, EXTI0, EXTI4_15 etc. - pins = set() # set of all present pins. PA4, PA5... - - # ========= peripherals - - singletons.extend((f'EXTI{x}' for x in range(16))) - num_dmas = 0 - - core = chip['cores'][0] - if core_name != None: - for c in chip['cores']: - if core_name == c['name']: - core = c - - for (name, peri) in core['peripherals'].items(): - if 'block' not in peri: - continue - - block = peri['block'] - block_mod, block_name_unparsed = block.rsplit('/') - block_mod, block_version = block_mod.rsplit('_') - block_name = '' - for b in block_name_unparsed.split('_'): - block_name += b.capitalize() - - custom_singletons = False - - if block_mod == 'gpio': - custom_singletons = True - port = name[4:] - port_num = ord(port) - ord('A') - - for pin_num in range(16): - pin = f'P{port}{pin_num}' - pins.add(pin) - singletons.append(pin) - - # if block_mod == 'dma': - # custom_singletons = True - # for ch_num in range(8): - # channel = f'{name}_CH{ch_num}' - # singletons.append(channel) - - if not custom_singletons: - singletons.append(name) - - for (channel_id, defn) in core['dma_channels'].items(): - singletons.append( channel_id ) - - f.write(f"embassy_hal_common::peripherals!({','.join(singletons)});")