metapac: generate ir
This commit is contained in:
parent
1595920962
commit
38619f8b99
@ -1,3 +1,96 @@
|
|||||||
|
pub mod ir {
|
||||||
|
pub struct IR {
|
||||||
|
pub blocks: &'static [Block],
|
||||||
|
pub fieldsets: &'static [FieldSet],
|
||||||
|
pub enums: &'static [Enum],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Block {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub extends: Option<&'static str>,
|
||||||
|
|
||||||
|
pub description: Option<&'static str>,
|
||||||
|
pub items: &'static [BlockItem],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BlockItem {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub description: Option<&'static str>,
|
||||||
|
|
||||||
|
pub array: Option<Array>,
|
||||||
|
pub byte_offset: u32,
|
||||||
|
|
||||||
|
pub inner: BlockItemInner,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum BlockItemInner {
|
||||||
|
Block(BlockItemBlock),
|
||||||
|
Register(Register),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Register {
|
||||||
|
pub access: Access,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub fieldset: Option<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BlockItemBlock {
|
||||||
|
pub block: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Access {
|
||||||
|
ReadWrite,
|
||||||
|
Read,
|
||||||
|
Write,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FieldSet {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub extends: Option<&'static str>,
|
||||||
|
|
||||||
|
pub description: Option<&'static str>,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub fields: &'static [Field],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Field {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub description: Option<&'static str>,
|
||||||
|
|
||||||
|
pub bit_offset: u32,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub array: Option<Array>,
|
||||||
|
pub enumm: Option<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Array {
|
||||||
|
Regular(RegularArray),
|
||||||
|
Cursed(CursedArray),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RegularArray {
|
||||||
|
pub len: u32,
|
||||||
|
pub stride: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CursedArray {
|
||||||
|
pub offsets: &'static [u32],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Enum {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub description: Option<&'static str>,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub variants: &'static [EnumVariant],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct EnumVariant {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub description: Option<&'static str>,
|
||||||
|
pub value: u64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
pub struct Metadata {
|
pub struct Metadata {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
@ -73,6 +166,7 @@ pub struct PeripheralRcc {
|
|||||||
pub clock: &'static str,
|
pub clock: &'static str,
|
||||||
pub enable: Option<PeripheralRccRegister>,
|
pub enable: Option<PeripheralRccRegister>,
|
||||||
pub reset: Option<PeripheralRccRegister>,
|
pub reset: Option<PeripheralRccRegister>,
|
||||||
|
pub mux: Option<PeripheralRccRegister>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
@ -1,5 +1,226 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
pub mod ir {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct IR {
|
||||||
|
pub blocks: Vec<Block>,
|
||||||
|
pub fieldsets: Vec<FieldSet>,
|
||||||
|
pub enums: Vec<Enum>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IR {
|
||||||
|
pub fn from_chiptool(ir: chiptool::ir::IR) -> Self {
|
||||||
|
let blocks: Vec<Block> = ir
|
||||||
|
.blocks
|
||||||
|
.iter()
|
||||||
|
.map(|(name, block)| {
|
||||||
|
let items = block
|
||||||
|
.items
|
||||||
|
.iter()
|
||||||
|
.map(|item| BlockItem {
|
||||||
|
name: item.name.clone(),
|
||||||
|
description: item.description.clone(),
|
||||||
|
array: None,
|
||||||
|
byte_offset: item.byte_offset,
|
||||||
|
inner: match &item.inner {
|
||||||
|
chiptool::ir::BlockItemInner::Block(block) => BlockItemInner::Block(BlockItemBlock {
|
||||||
|
block: block.block.clone(),
|
||||||
|
}),
|
||||||
|
chiptool::ir::BlockItemInner::Register(register) => {
|
||||||
|
BlockItemInner::Register(Register {
|
||||||
|
access: match register.access {
|
||||||
|
chiptool::ir::Access::Read => Access::Read,
|
||||||
|
chiptool::ir::Access::ReadWrite => Access::ReadWrite,
|
||||||
|
chiptool::ir::Access::Write => Access::Write,
|
||||||
|
},
|
||||||
|
bit_size: register.bit_size,
|
||||||
|
fieldset: register
|
||||||
|
.fieldset
|
||||||
|
.as_ref()
|
||||||
|
.map(|fieldset| fieldset.strip_prefix("regs::").unwrap().to_string()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Block {
|
||||||
|
name: name.to_string(),
|
||||||
|
items: items,
|
||||||
|
extends: block.extends.clone(),
|
||||||
|
description: block.description.clone(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let fieldsets: Vec<FieldSet> = ir
|
||||||
|
.fieldsets
|
||||||
|
.iter()
|
||||||
|
.map(|(name, fieldset)| {
|
||||||
|
let fields = fieldset
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| Field {
|
||||||
|
name: field.name.clone(),
|
||||||
|
description: field.description.clone(),
|
||||||
|
bit_offset: field.bit_offset,
|
||||||
|
bit_size: field.bit_size,
|
||||||
|
array: field.array.as_ref().map(|array| match &array {
|
||||||
|
chiptool::ir::Array::Regular(regular_array) => Array::Regular(RegularArray {
|
||||||
|
len: regular_array.len,
|
||||||
|
stride: regular_array.stride,
|
||||||
|
}),
|
||||||
|
chiptool::ir::Array::Cursed(cursed_array) => Array::Cursed(CursedArray {
|
||||||
|
offsets: cursed_array.offsets.clone(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
enumm: field
|
||||||
|
.enumm
|
||||||
|
.as_ref()
|
||||||
|
.map(|fieldset| fieldset.strip_prefix("vals::").unwrap().to_string()),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
FieldSet {
|
||||||
|
name: name.strip_prefix("regs::").unwrap().to_owned(),
|
||||||
|
fields: fields,
|
||||||
|
extends: fieldset.extends.clone(),
|
||||||
|
description: fieldset.description.clone(),
|
||||||
|
bit_size: fieldset.bit_size,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let enums: Vec<Enum> = ir
|
||||||
|
.enums
|
||||||
|
.iter()
|
||||||
|
.map(|(name, enumm)| {
|
||||||
|
let variants = enumm
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.map(|variant| EnumVariant {
|
||||||
|
name: variant.name.clone(),
|
||||||
|
description: variant.description.clone(),
|
||||||
|
value: variant.value,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Enum {
|
||||||
|
name: name.strip_prefix("vals::").unwrap().to_owned(),
|
||||||
|
description: enumm.description.clone(),
|
||||||
|
bit_size: enumm.bit_size,
|
||||||
|
variants: variants,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
blocks,
|
||||||
|
fieldsets,
|
||||||
|
enums,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct Block {
|
||||||
|
pub name: String,
|
||||||
|
pub extends: Option<String>,
|
||||||
|
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub items: Vec<BlockItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct BlockItem {
|
||||||
|
pub name: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
|
||||||
|
pub array: Option<Array>,
|
||||||
|
pub byte_offset: u32,
|
||||||
|
|
||||||
|
pub inner: BlockItemInner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub enum BlockItemInner {
|
||||||
|
Block(BlockItemBlock),
|
||||||
|
Register(Register),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct Register {
|
||||||
|
pub access: Access,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub fieldset: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct BlockItemBlock {
|
||||||
|
pub block: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub enum Access {
|
||||||
|
ReadWrite,
|
||||||
|
Read,
|
||||||
|
Write,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct FieldSet {
|
||||||
|
pub name: String,
|
||||||
|
pub extends: Option<String>,
|
||||||
|
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub fields: Vec<Field>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct Field {
|
||||||
|
pub name: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
|
||||||
|
pub bit_offset: u32,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub array: Option<Array>,
|
||||||
|
pub enumm: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub enum Array {
|
||||||
|
Regular(RegularArray),
|
||||||
|
Cursed(CursedArray),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct RegularArray {
|
||||||
|
pub len: u32,
|
||||||
|
pub stride: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct CursedArray {
|
||||||
|
pub offsets: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct Enum {
|
||||||
|
pub name: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub bit_size: u32,
|
||||||
|
pub variants: Vec<EnumVariant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
|
pub struct EnumVariant {
|
||||||
|
pub name: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub value: u64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||||
pub struct Chip {
|
pub struct Chip {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -206,7 +206,7 @@ impl Gen {
|
|||||||
file
|
file
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = format!(
|
let mut data = format!(
|
||||||
"include!(\"../{}\");
|
"include!(\"../{}\");
|
||||||
pub const METADATA: Metadata = Metadata {{
|
pub const METADATA: Metadata = Metadata {{
|
||||||
name: {:?},
|
name: {:?},
|
||||||
@ -226,6 +226,15 @@ impl Gen {
|
|||||||
&core.nvic_priority_bits,
|
&core.nvic_priority_bits,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for (module, version) in &peripheral_versions {
|
||||||
|
writeln!(
|
||||||
|
&mut data,
|
||||||
|
"#[path=\"../../registers/{}_{}.rs\"] pub mod {};",
|
||||||
|
module, version, module
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let mut file = File::create(chip_dir.join("metadata.rs")).unwrap();
|
let mut file = File::create(chip_dir.join("metadata.rs")).unwrap();
|
||||||
file.write_all(data.as_bytes()).unwrap();
|
file.write_all(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
@ -250,6 +259,7 @@ impl Gen {
|
|||||||
|
|
||||||
pub fn gen(&mut self) {
|
pub fn gen(&mut self) {
|
||||||
fs::create_dir_all(self.opts.out_dir.join("src/peripherals")).unwrap();
|
fs::create_dir_all(self.opts.out_dir.join("src/peripherals")).unwrap();
|
||||||
|
fs::create_dir_all(self.opts.out_dir.join("src/registers")).unwrap();
|
||||||
fs::create_dir_all(self.opts.out_dir.join("src/chips")).unwrap();
|
fs::create_dir_all(self.opts.out_dir.join("src/chips")).unwrap();
|
||||||
|
|
||||||
let mut chip_core_names: Vec<String> = Vec::new();
|
let mut chip_core_names: Vec<String> = Vec::new();
|
||||||
@ -318,6 +328,35 @@ impl Gen {
|
|||||||
let re = Regex::new("# *! *\\[.*\\]").unwrap();
|
let re = Regex::new("# *! *\\[.*\\]").unwrap();
|
||||||
let data = re.replace_all(&data, "");
|
let data = re.replace_all(&data, "");
|
||||||
file.write_all(data.as_bytes()).unwrap();
|
file.write_all(data.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
let ir = crate::data::ir::IR::from_chiptool(ir);
|
||||||
|
let mut data = String::new();
|
||||||
|
|
||||||
|
write!(
|
||||||
|
&mut data,
|
||||||
|
"
|
||||||
|
use crate::metadata::ir::*;
|
||||||
|
static REGISTERS: IR = {};
|
||||||
|
",
|
||||||
|
stringify(&ir)
|
||||||
|
.replace("Register(", "BlockItemInner::Register(")
|
||||||
|
.replace("Block(", "BlockItemInner::Block(")
|
||||||
|
.replace("Regular(", "Array::Regular(")
|
||||||
|
.replace("Cursed(", "Array::Cursed(")
|
||||||
|
.replace("Read,", "Access::Read,")
|
||||||
|
.replace("Write,", "Access::Write,")
|
||||||
|
.replace("ReadAccess::Write,", "Access::ReadWrite,"),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut file = File::create(
|
||||||
|
self.opts
|
||||||
|
.out_dir
|
||||||
|
.join("src/registers")
|
||||||
|
.join(format!("{}_{}.rs", module, version)),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
file.write_all(data.as_bytes()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate Cargo.toml
|
// Generate Cargo.toml
|
||||||
|
Loading…
x
Reference in New Issue
Block a user