use serde::Deserialize; use stm32_data_macros::EnumDebug; pub mod ir { use super::*; #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct IR { pub blocks: Vec, pub fieldsets: Vec
, pub enums: Vec, } impl IR { pub fn from_chiptool(ir: chiptool::ir::IR) -> Self { let mut blocks: Vec = 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(); #[allow(clippy::redundant_field_names)] Block { name: name.to_string(), items: items, extends: block.extends.clone(), description: block.description.clone(), } }) .collect(); blocks.sort_by_key(|b| b.name.clone()); let mut fieldsets: Vec
= ir .fieldsets .iter() .map(|(name, fieldset)| { let fields = fieldset .fields .iter() .map(|field| Field { name: field.name.clone(), description: field.description.clone(), bit_offset: match &field.bit_offset { chiptool::ir::BitOffset::Regular(offset) => { BitOffset::Regular(RegularBitOffset { offset: *offset }) } chiptool::ir::BitOffset::Cursed(ranges) => { BitOffset::Cursed(CursedBitOffset { ranges: ranges.clone() }) } }, 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(); #[allow(clippy::redundant_field_names)] 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(); fieldsets.sort_by_key(|f| f.name.clone()); let mut enums: Vec = 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(); #[allow(clippy::redundant_field_names)] Enum { name: name.strip_prefix("vals::").unwrap().to_owned(), description: enumm.description.clone(), bit_size: enumm.bit_size, variants: variants, } }) .collect(); enums.sort_by_key(|e| e.name.clone()); Self { blocks, fieldsets, enums, } } } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Block { pub name: String, pub extends: Option, pub description: Option, pub items: Vec, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct BlockItem { pub name: String, pub description: Option, pub array: Option, pub byte_offset: u32, pub inner: BlockItemInner, } #[derive(EnumDebug, 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, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct BlockItemBlock { pub block: String, } #[derive(EnumDebug, 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, pub description: Option, pub bit_size: u32, pub fields: Vec, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Field { pub name: String, pub description: Option, pub bit_offset: BitOffset, pub bit_size: u32, pub array: Option, pub enumm: Option, } #[derive(EnumDebug, 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, } #[derive(EnumDebug, Eq, PartialEq, Clone, Deserialize)] pub enum BitOffset { Regular(RegularBitOffset), Cursed(CursedBitOffset), } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct RegularBitOffset { pub offset: u32, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct CursedBitOffset { pub ranges: Vec>, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Enum { pub name: String, pub description: Option, pub bit_size: u32, pub variants: Vec, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct EnumVariant { pub name: String, pub description: Option, pub value: u64, } } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Chip { pub name: String, pub family: String, pub line: String, pub cores: Vec, pub memory: Vec, pub packages: Vec, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct MemoryRegion { pub name: String, pub kind: MemoryRegionKind, pub address: u32, pub size: u32, pub settings: Option, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct FlashSettings { pub erase_size: u32, pub write_size: u32, pub erase_value: u8, } #[derive(EnumDebug, Eq, PartialEq, Clone, Deserialize)] pub enum MemoryRegionKind { #[serde(rename = "flash")] Flash, #[serde(rename = "ram")] Ram, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Core { pub name: String, pub peripherals: Vec, #[serde(default)] pub nvic_priority_bits: Option, pub interrupts: Vec, pub dma_channels: Vec, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Interrupt { pub name: String, pub number: u32, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Package { pub name: String, pub package: String, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct Peripheral { pub name: String, pub address: u64, #[serde(default)] pub registers: Option, #[serde(default)] pub rcc: Option, #[serde(default)] pub pins: Vec, #[serde(default)] pub dma_channels: Vec, #[serde(default)] pub interrupts: Vec, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct PeripheralInterrupt { pub signal: String, pub interrupt: String, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct PeripheralRcc { pub clock: String, #[serde(default)] pub enable: Option, #[serde(default)] pub reset: Option, #[serde(default)] pub mux: Option, #[serde(default)] pub stop_mode: StopMode, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct PeripheralRccRegister { pub register: String, pub field: String, } #[derive(EnumDebug, Eq, PartialEq, Clone, Deserialize, Default)] pub enum StopMode { #[default] Stop1, // Peripheral prevents chip from entering Stop1 Stop2, // Peripheral prevents chip from entering Stop2 Standby, // Peripheral does not prevent chip from entering Stop } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct PeripheralPin { pub pin: String, pub signal: String, pub af: Option, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize)] pub struct DmaChannel { pub name: String, pub dma: String, pub channel: u32, pub dmamux: Option, pub dmamux_channel: Option, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Hash)] pub struct PeripheralDmaChannel { pub signal: String, pub channel: Option, pub dmamux: Option, pub dma: Option, pub request: Option, } #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Hash)] pub struct PeripheralRegisters { pub kind: String, pub version: String, pub block: String, #[serde(default)] pub ir: String, }