diff --git a/stm32-metapac-gen/src/assets/metadata.rs b/stm32-metapac-gen/src/assets/metadata.rs new file mode 100644 index 000000000..7fe49ceba --- /dev/null +++ b/stm32-metapac-gen/src/assets/metadata.rs @@ -0,0 +1,97 @@ +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct Metadata { + pub name: &'static str, + pub family: &'static str, + pub line: &'static str, + pub memory: &'static [MemoryRegion], + pub peripherals: &'static [Peripheral], + pub interrupts: &'static [Interrupt], + pub dma_channels: &'static [DmaChannel], +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct MemoryRegion { + pub name: &'static str, + pub kind: MemoryRegionKind, + pub address: u32, + pub size: u32, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub enum MemoryRegionKind { + Flash, + Ram, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct Interrupt { + pub name: &'static str, + pub number: u32, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct Package { + pub name: &'static str, + pub package: &'static str, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct Peripheral { + pub name: &'static str, + pub address: u64, + pub registers: Option, + pub rcc: Option, + pub pins: &'static [PeripheralPin], + pub dma_channels: &'static [PeripheralDmaChannel], + pub interrupts: &'static [PeripheralInterrupt], +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct PeripheralRegisters { + pub kind: &'static str, + pub version: &'static str, + pub block: &'static str, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct PeripheralInterrupt { + pub signal: &'static str, + pub interrupt: &'static str, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct PeripheralRcc { + pub clock: &'static str, + pub enable: Option, + pub reset: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct PeripheralRccRegister { + pub register: &'static str, + pub field: &'static str, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct PeripheralPin { + pub pin: &'static str, + pub signal: &'static str, + pub af: Option<&'static str>, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct DmaChannel { + pub name: &'static str, + pub dma: &'static str, + pub channel: u32, + pub dmamux: Option<&'static str>, + pub dmamux_channel: Option, +} + +#[derive(Debug, Eq, PartialEq, Clone)] +pub struct PeripheralDmaChannel { + pub signal: &'static str, + pub channel: Option<&'static str>, + pub dmamux: Option<&'static str>, + pub request: Option, +} diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs index fd8da8a6f..ccf737eff 100644 --- a/stm32-metapac-gen/src/lib.rs +++ b/stm32-metapac-gen/src/lib.rs @@ -16,6 +16,17 @@ use chiptool::{generate, ir, transform}; mod data; use data::*; +#[derive(Debug, Eq, PartialEq, Clone)] +struct Metadata<'a> { + name: &'a str, + family: &'a str, + line: &'a str, + memory: &'a [MemoryRegion], + peripherals: &'a [Peripheral], + interrupts: &'a [Interrupt], + dma_channels: &'a [DmaChannel], +} + fn make_peripheral_counts(out: &mut String, data: &BTreeMap) { write!( out, @@ -384,12 +395,7 @@ pub fn gen_chip( let mut device_x = String::new(); for irq in &core.interrupts { - write!( - &mut device_x, - "PROVIDE({} = DefaultHandler);\n", - irq.name.to_ascii_uppercase() - ) - .unwrap(); + write!(&mut device_x, "PROVIDE({} = DefaultHandler);\n", irq.name).unwrap(); } // ============================== @@ -397,6 +403,7 @@ pub fn gen_chip( let mut data = String::new(); + write!(&mut data, "#[cfg(feature=\"metadata\")] pub mod metadata;").unwrap(); write!(&mut data, "#[cfg(feature=\"pac\")] mod pac;").unwrap(); write!(&mut data, "#[cfg(feature=\"pac\")] pub use pac::*; ").unwrap(); @@ -424,6 +431,38 @@ pub fn gen_chip( let mut file = File::create(chip_dir.join("mod.rs")).unwrap(); file.write_all(data.as_bytes()).unwrap(); + // ============================== + // generate metadata.rs + + let metadata = Metadata { + name: &chip.name, + family: &chip.family, + line: &chip.line, + memory: &chip.memory, + peripherals: &core.peripherals, + interrupts: &core.interrupts, + dma_channels: &core.dma_channels, + }; + let metadata = format!("{:#?}", metadata); + let metadata = metadata.replace("[\n", "&[\n"); + let metadata = metadata.replace("[],\n", "&[],\n"); + + let mut data = String::new(); + + write!( + &mut data, + " + include!(\"../../metadata.rs\"); + use MemoryRegionKind::*; + pub const METADATA: Metadata = {}; + ", + metadata + ) + .unwrap(); + + let mut file = File::create(chip_dir.join("metadata.rs")).unwrap(); + file.write_all(data.as_bytes()).unwrap(); + // ============================== // generate device.x @@ -462,7 +501,21 @@ pub fn gen(options: Options) { for chip_name in &options.chips { println!("Generating {}...", chip_name); - let chip = load_chip(&options, chip_name); + let mut chip = load_chip(&options, chip_name); + + // Cleanup + for core in &mut chip.cores { + for irq in &mut core.interrupts { + irq.name = irq.name.to_ascii_uppercase(); + } + for p in &mut core.peripherals { + for irq in &mut p.interrupts { + irq.interrupt = irq.interrupt.to_ascii_uppercase(); + } + } + } + + // Generate for (core_index, core) in chip.cores.iter().enumerate() { let chip_core_name = match chip.cores.len() { 1 => chip_name.clone(), @@ -557,6 +610,13 @@ pub fn gen(options: Options) { ) .unwrap(); + // Generate src/metadata.rs + fs::write( + options.out_dir.join("src").join("metadata.rs"), + include_bytes!("assets/metadata.rs"), + ) + .unwrap(); + // Generate Cargo.toml const BUILDDEP_BEGIN: &[u8] = b"# BEGIN BUILD DEPENDENCIES"; const BUILDDEP_END: &[u8] = b"# END BUILD DEPENDENCIES"; diff --git a/stm32-metapac/Cargo.toml b/stm32-metapac/Cargo.toml index 4115da349..5642af46e 100644 --- a/stm32-metapac/Cargo.toml +++ b/stm32-metapac/Cargo.toml @@ -19,10 +19,14 @@ regex = "1.5.4" default = ["pac"] # Build the actual PAC. Set by default. -# If not set, only the macrotables will be generated. You may want to not set it -# if you're using stm32-metapac from a build.rs script to use the macros. +# If you just want the metadata, unset it with `default-features = false`. pac = [] +# Build the chip metadata. +# If set, a const `stm32_metapac::METADATA` will be exported, containing all the +# metadata for the currently selected chip. +metadata = [] + rt = ["cortex-m-rt/device"] memory-x = []