summaryrefslogtreecommitdiff
path: root/stm32-metapac-gen
diff options
context:
space:
mode:
authorDario Nieuwenhuis <dirbaio@dirbaio.net>2022-02-09 00:28:05 +0100
committerDario Nieuwenhuis <dirbaio@dirbaio.net>2022-02-09 00:28:05 +0100
commit4d73d87b40ae9530681c8d0461810aae85430669 (patch)
treea4e89d12a8420a0d0cb47d009b7b14dc8dca7439 /stm32-metapac-gen
parent2cf79f6569a7d65d70599a62642c7bc353abd692 (diff)
downloadembassy-4d73d87b40ae9530681c8d0461810aae85430669.zip
stm32-metapac: add option to generate chip metadata as a rust const.
Diffstat (limited to 'stm32-metapac-gen')
-rw-r--r--stm32-metapac-gen/src/assets/metadata.rs97
-rw-r--r--stm32-metapac-gen/src/lib.rs74
2 files changed, 164 insertions, 7 deletions
diff --git a/stm32-metapac-gen/src/assets/metadata.rs b/stm32-metapac-gen/src/assets/metadata.rs
new file mode 100644
index 00000000..7fe49ceb
--- /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<PeripheralRegisters>,
+ pub rcc: Option<PeripheralRcc>,
+ 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<PeripheralRccRegister>,
+ pub reset: Option<PeripheralRccRegister>,
+}
+
+#[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<u32>,
+}
+
+#[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<u32>,
+}
diff --git a/stm32-metapac-gen/src/lib.rs b/stm32-metapac-gen/src/lib.rs
index fd8da8a6..ccf737ef 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<String, u8>) {
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();
@@ -425,6 +432,38 @@ pub fn gen_chip(
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
File::create(chip_dir.join("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";