Merge pull request #265 from xoviat/sel
rcc: pipe through sel mux and generate ir
This commit is contained in:
commit
4baa9a0079
@ -14,6 +14,24 @@ impl PeripheralToClock {
|
||||
|
||||
for (rcc_name, ir) in ®isters.registers {
|
||||
if let Some(rcc_name) = rcc_name.strip_prefix("rcc_") {
|
||||
let mut family_muxes = HashMap::new();
|
||||
for (reg, body) in &ir.fieldsets {
|
||||
let key = format!("fieldset/{reg}");
|
||||
if let Some(_) = regex!(r"^fieldset/CCIPR\d?$").captures(&key) {
|
||||
for field in &body.fields {
|
||||
if let Some(peri) = field.name.strip_suffix("SEL") {
|
||||
family_muxes.insert(
|
||||
peri.to_string(),
|
||||
stm32_data_serde::chip::core::peripheral::rcc::Mux {
|
||||
register: reg.clone(),
|
||||
field: field.name.clone(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut family_clocks = HashMap::new();
|
||||
for (reg, body) in &ir.fieldsets {
|
||||
let key = format!("fieldset/{reg}");
|
||||
@ -49,6 +67,8 @@ impl PeripheralToClock {
|
||||
}
|
||||
}
|
||||
|
||||
let mux = family_muxes.get(peri).map(|peri| peri.clone());
|
||||
|
||||
let res = stm32_data_serde::chip::core::peripheral::Rcc {
|
||||
clock: peri_clock,
|
||||
enable: stm32_data_serde::chip::core::peripheral::rcc::Enable {
|
||||
@ -56,6 +76,7 @@ impl PeripheralToClock {
|
||||
field: field.name.clone(),
|
||||
},
|
||||
reset,
|
||||
mux,
|
||||
};
|
||||
|
||||
family_clocks.insert(peri.to_string(), res);
|
||||
|
@ -114,6 +114,8 @@ pub mod chip {
|
||||
pub enable: rcc::Enable,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub reset: Option<rcc::Reset>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub mux: Option<rcc::Mux>,
|
||||
}
|
||||
|
||||
pub mod rcc {
|
||||
@ -130,6 +132,12 @@ pub mod chip {
|
||||
pub register: String,
|
||||
pub field: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct Mux {
|
||||
pub register: String,
|
||||
pub field: String,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
|
@ -1,3 +1,110 @@
|
||||
pub mod ir {
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct IR {
|
||||
pub blocks: &'static [Block],
|
||||
pub fieldsets: &'static [FieldSet],
|
||||
pub enums: &'static [Enum],
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Block {
|
||||
pub name: &'static str,
|
||||
pub extends: Option<&'static str>,
|
||||
|
||||
pub description: Option<&'static str>,
|
||||
pub items: &'static [BlockItem],
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct BlockItem {
|
||||
pub name: &'static str,
|
||||
pub description: Option<&'static str>,
|
||||
|
||||
pub array: Option<Array>,
|
||||
pub byte_offset: u32,
|
||||
|
||||
pub inner: BlockItemInner,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub enum BlockItemInner {
|
||||
Block(BlockItemBlock),
|
||||
Register(Register),
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Register {
|
||||
pub access: Access,
|
||||
pub bit_size: u32,
|
||||
pub fieldset: Option<&'static str>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct BlockItemBlock {
|
||||
pub block: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub enum Access {
|
||||
ReadWrite,
|
||||
Read,
|
||||
Write,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
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],
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
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>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub enum Array {
|
||||
Regular(RegularArray),
|
||||
Cursed(CursedArray),
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct RegularArray {
|
||||
pub len: u32,
|
||||
pub stride: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct CursedArray {
|
||||
pub offsets: &'static [u32],
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Enum {
|
||||
pub name: &'static str,
|
||||
pub description: Option<&'static str>,
|
||||
pub bit_size: u32,
|
||||
pub variants: &'static [EnumVariant],
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct EnumVariant {
|
||||
pub name: &'static str,
|
||||
pub description: Option<&'static str>,
|
||||
pub value: u64,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub struct Metadata {
|
||||
pub name: &'static str,
|
||||
@ -60,6 +167,7 @@ pub struct PeripheralRegisters {
|
||||
pub kind: &'static str,
|
||||
pub version: &'static str,
|
||||
pub block: &'static str,
|
||||
pub ir: &'static ir::IR,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
@ -73,6 +181,7 @@ pub struct PeripheralRcc {
|
||||
pub clock: &'static str,
|
||||
pub enable: Option<PeripheralRccRegister>,
|
||||
pub reset: Option<PeripheralRccRegister>,
|
||||
pub mux: Option<PeripheralRccRegister>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
|
@ -1,5 +1,234 @@
|
||||
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: item.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(),
|
||||
}),
|
||||
}),
|
||||
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)]
|
||||
pub struct Chip {
|
||||
pub name: String,
|
||||
@ -85,6 +314,8 @@ pub struct PeripheralRcc {
|
||||
pub enable: Option<PeripheralRccRegister>,
|
||||
#[serde(default)]
|
||||
pub reset: Option<PeripheralRccRegister>,
|
||||
#[serde(default)]
|
||||
pub mux: Option<PeripheralRccRegister>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
|
||||
@ -123,4 +354,6 @@ pub struct PeripheralRegisters {
|
||||
pub kind: String,
|
||||
pub version: String,
|
||||
pub block: String,
|
||||
#[serde(default)]
|
||||
pub ir: String,
|
||||
}
|
||||
|
@ -186,9 +186,9 @@ impl Gen {
|
||||
write!(
|
||||
&mut data,
|
||||
"
|
||||
const PERIPHERALS: &'static [Peripheral] = {};
|
||||
const INTERRUPTS: &'static [Interrupt] = {};
|
||||
const DMA_CHANNELS: &'static [DmaChannel] = {};
|
||||
pub(crate) static PERIPHERALS: &'static [Peripheral] = {};
|
||||
pub(crate) static INTERRUPTS: &'static [Interrupt] = {};
|
||||
pub(crate) static DMA_CHANNELS: &'static [DmaChannel] = {};
|
||||
",
|
||||
stringify(&core.peripherals),
|
||||
stringify(&core.interrupts),
|
||||
@ -199,6 +199,18 @@ impl Gen {
|
||||
let out_dir = self.opts.out_dir.clone();
|
||||
let n = self.metadata_dedup.len();
|
||||
let deduped_file = self.metadata_dedup.entry(data.clone()).or_insert_with(|| {
|
||||
let ir_regex = Regex::new("\":ir_for:([a-z0-9]+):\"").unwrap();
|
||||
let mut data = ir_regex.replace_all(&data, "&$1::REGISTERS").to_string();
|
||||
|
||||
for (module, version) in &peripheral_versions {
|
||||
writeln!(
|
||||
&mut data,
|
||||
"#[path=\"../registers/{}_{}.rs\"] pub mod {};",
|
||||
module, version, module
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let file = format!("metadata_{:04}.rs", n);
|
||||
let path = out_dir.join("src/chips").join(&file);
|
||||
fs::write(path, data).unwrap();
|
||||
@ -208,7 +220,7 @@ impl Gen {
|
||||
|
||||
let data = format!(
|
||||
"include!(\"../{}\");
|
||||
pub const METADATA: Metadata = Metadata {{
|
||||
pub static METADATA: Metadata = Metadata {{
|
||||
name: {:?},
|
||||
family: {:?},
|
||||
line: {:?},
|
||||
@ -250,6 +262,7 @@ impl Gen {
|
||||
|
||||
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/registers")).unwrap();
|
||||
fs::create_dir_all(self.opts.out_dir.join("src/chips")).unwrap();
|
||||
|
||||
let mut chip_core_names: Vec<String> = Vec::new();
|
||||
@ -268,6 +281,10 @@ impl Gen {
|
||||
for irq in &mut p.interrupts {
|
||||
irq.interrupt = irq.interrupt.to_ascii_uppercase();
|
||||
}
|
||||
|
||||
if let Some(registers) = &mut p.registers {
|
||||
registers.ir = format!(":ir_for:{}:", registers.kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,6 +335,35 @@ impl Gen {
|
||||
let re = Regex::new("# *! *\\[.*\\]").unwrap();
|
||||
let data = re.replace_all(&data, "");
|
||||
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::*;
|
||||
pub(crate) 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user