aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-02-09 00:28:05 +0100
committerDario Nieuwenhuis <[email protected]>2022-02-09 00:28:05 +0100
commit4d73d87b40ae9530681c8d0461810aae85430669 (patch)
treea4e89d12a8420a0d0cb47d009b7b14dc8dca7439
parent2cf79f6569a7d65d70599a62642c7bc353abd692 (diff)
stm32-metapac: add option to generate chip metadata as a rust const.
-rw-r--r--stm32-metapac-gen/src/assets/metadata.rs97
-rw-r--r--stm32-metapac-gen/src/lib.rs74
-rw-r--r--stm32-metapac/Cargo.toml8
3 files changed, 170 insertions, 9 deletions
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 @@
1#[derive(Debug, Eq, PartialEq, Clone)]
2pub struct Metadata {
3 pub name: &'static str,
4 pub family: &'static str,
5 pub line: &'static str,
6 pub memory: &'static [MemoryRegion],
7 pub peripherals: &'static [Peripheral],
8 pub interrupts: &'static [Interrupt],
9 pub dma_channels: &'static [DmaChannel],
10}
11
12#[derive(Debug, Eq, PartialEq, Clone)]
13pub struct MemoryRegion {
14 pub name: &'static str,
15 pub kind: MemoryRegionKind,
16 pub address: u32,
17 pub size: u32,
18}
19
20#[derive(Debug, Eq, PartialEq, Clone)]
21pub enum MemoryRegionKind {
22 Flash,
23 Ram,
24}
25
26#[derive(Debug, Eq, PartialEq, Clone)]
27pub struct Interrupt {
28 pub name: &'static str,
29 pub number: u32,
30}
31
32#[derive(Debug, Eq, PartialEq, Clone)]
33pub struct Package {
34 pub name: &'static str,
35 pub package: &'static str,
36}
37
38#[derive(Debug, Eq, PartialEq, Clone)]
39pub struct Peripheral {
40 pub name: &'static str,
41 pub address: u64,
42 pub registers: Option<PeripheralRegisters>,
43 pub rcc: Option<PeripheralRcc>,
44 pub pins: &'static [PeripheralPin],
45 pub dma_channels: &'static [PeripheralDmaChannel],
46 pub interrupts: &'static [PeripheralInterrupt],
47}
48
49#[derive(Debug, Eq, PartialEq, Clone)]
50pub struct PeripheralRegisters {
51 pub kind: &'static str,
52 pub version: &'static str,
53 pub block: &'static str,
54}
55
56#[derive(Debug, Eq, PartialEq, Clone)]
57pub struct PeripheralInterrupt {
58 pub signal: &'static str,
59 pub interrupt: &'static str,
60}
61
62#[derive(Debug, Eq, PartialEq, Clone)]
63pub struct PeripheralRcc {
64 pub clock: &'static str,
65 pub enable: Option<PeripheralRccRegister>,
66 pub reset: Option<PeripheralRccRegister>,
67}
68
69#[derive(Debug, Eq, PartialEq, Clone)]
70pub struct PeripheralRccRegister {
71 pub register: &'static str,
72 pub field: &'static str,
73}
74
75#[derive(Debug, Eq, PartialEq, Clone)]
76pub struct PeripheralPin {
77 pub pin: &'static str,
78 pub signal: &'static str,
79 pub af: Option<&'static str>,
80}
81
82#[derive(Debug, Eq, PartialEq, Clone)]
83pub struct DmaChannel {
84 pub name: &'static str,
85 pub dma: &'static str,
86 pub channel: u32,
87 pub dmamux: Option<&'static str>,
88 pub dmamux_channel: Option<u32>,
89}
90
91#[derive(Debug, Eq, PartialEq, Clone)]
92pub struct PeripheralDmaChannel {
93 pub signal: &'static str,
94 pub channel: Option<&'static str>,
95 pub dmamux: Option<&'static str>,
96 pub request: Option<u32>,
97}
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};
16mod data; 16mod data;
17use data::*; 17use data::*;
18 18
19#[derive(Debug, Eq, PartialEq, Clone)]
20struct Metadata<'a> {
21 name: &'a str,
22 family: &'a str,
23 line: &'a str,
24 memory: &'a [MemoryRegion],
25 peripherals: &'a [Peripheral],
26 interrupts: &'a [Interrupt],
27 dma_channels: &'a [DmaChannel],
28}
29
19fn make_peripheral_counts(out: &mut String, data: &BTreeMap<String, u8>) { 30fn make_peripheral_counts(out: &mut String, data: &BTreeMap<String, u8>) {
20 write!( 31 write!(
21 out, 32 out,
@@ -384,12 +395,7 @@ pub fn gen_chip(
384 let mut device_x = String::new(); 395 let mut device_x = String::new();
385 396
386 for irq in &core.interrupts { 397 for irq in &core.interrupts {
387 write!( 398 write!(&mut device_x, "PROVIDE({} = DefaultHandler);\n", irq.name).unwrap();
388 &mut device_x,
389 "PROVIDE({} = DefaultHandler);\n",
390 irq.name.to_ascii_uppercase()
391 )
392 .unwrap();
393 } 399 }
394 400
395 // ============================== 401 // ==============================
@@ -397,6 +403,7 @@ pub fn gen_chip(
397 403
398 let mut data = String::new(); 404 let mut data = String::new();
399 405
406 write!(&mut data, "#[cfg(feature=\"metadata\")] pub mod metadata;").unwrap();
400 write!(&mut data, "#[cfg(feature=\"pac\")] mod pac;").unwrap(); 407 write!(&mut data, "#[cfg(feature=\"pac\")] mod pac;").unwrap();
401 write!(&mut data, "#[cfg(feature=\"pac\")] pub use pac::*; ").unwrap(); 408 write!(&mut data, "#[cfg(feature=\"pac\")] pub use pac::*; ").unwrap();
402 409
@@ -425,6 +432,38 @@ pub fn gen_chip(
425 file.write_all(data.as_bytes()).unwrap(); 432 file.write_all(data.as_bytes()).unwrap();
426 433
427 // ============================== 434 // ==============================
435 // generate metadata.rs
436
437 let metadata = Metadata {
438 name: &chip.name,
439 family: &chip.family,
440 line: &chip.line,
441 memory: &chip.memory,
442 peripherals: &core.peripherals,
443 interrupts: &core.interrupts,
444 dma_channels: &core.dma_channels,
445 };
446 let metadata = format!("{:#?}", metadata);
447 let metadata = metadata.replace("[\n", "&[\n");
448 let metadata = metadata.replace("[],\n", "&[],\n");
449
450 let mut data = String::new();
451
452 write!(
453 &mut data,
454 "
455 include!(\"../../metadata.rs\");
456 use MemoryRegionKind::*;
457 pub const METADATA: Metadata = {};
458 ",
459 metadata
460 )
461 .unwrap();
462
463 let mut file = File::create(chip_dir.join("metadata.rs")).unwrap();
464 file.write_all(data.as_bytes()).unwrap();
465
466 // ==============================
428 // generate device.x 467 // generate device.x
429 468
430 File::create(chip_dir.join("device.x")) 469 File::create(chip_dir.join("device.x"))
@@ -462,7 +501,21 @@ pub fn gen(options: Options) {
462 for chip_name in &options.chips { 501 for chip_name in &options.chips {
463 println!("Generating {}...", chip_name); 502 println!("Generating {}...", chip_name);
464 503
465 let chip = load_chip(&options, chip_name); 504 let mut chip = load_chip(&options, chip_name);
505
506 // Cleanup
507 for core in &mut chip.cores {
508 for irq in &mut core.interrupts {
509 irq.name = irq.name.to_ascii_uppercase();
510 }
511 for p in &mut core.peripherals {
512 for irq in &mut p.interrupts {
513 irq.interrupt = irq.interrupt.to_ascii_uppercase();
514 }
515 }
516 }
517
518 // Generate
466 for (core_index, core) in chip.cores.iter().enumerate() { 519 for (core_index, core) in chip.cores.iter().enumerate() {
467 let chip_core_name = match chip.cores.len() { 520 let chip_core_name = match chip.cores.len() {
468 1 => chip_name.clone(), 521 1 => chip_name.clone(),
@@ -557,6 +610,13 @@ pub fn gen(options: Options) {
557 ) 610 )
558 .unwrap(); 611 .unwrap();
559 612
613 // Generate src/metadata.rs
614 fs::write(
615 options.out_dir.join("src").join("metadata.rs"),
616 include_bytes!("assets/metadata.rs"),
617 )
618 .unwrap();
619
560 // Generate Cargo.toml 620 // Generate Cargo.toml
561 const BUILDDEP_BEGIN: &[u8] = b"# BEGIN BUILD DEPENDENCIES"; 621 const BUILDDEP_BEGIN: &[u8] = b"# BEGIN BUILD DEPENDENCIES";
562 const BUILDDEP_END: &[u8] = b"# END BUILD DEPENDENCIES"; 622 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"
19default = ["pac"] 19default = ["pac"]
20 20
21# Build the actual PAC. Set by default. 21# Build the actual PAC. Set by default.
22# If not set, only the macrotables will be generated. You may want to not set it 22# If you just want the metadata, unset it with `default-features = false`.
23# if you're using stm32-metapac from a build.rs script to use the macros.
24pac = [] 23pac = []
25 24
25# Build the chip metadata.
26# If set, a const `stm32_metapac::METADATA` will be exported, containing all the
27# metadata for the currently selected chip.
28metadata = []
29
26rt = ["cortex-m-rt/device"] 30rt = ["cortex-m-rt/device"]
27memory-x = [] 31memory-x = []
28 32