#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub struct Mcu {
pub device: Device,
pub variants: Vec<Variant>,
pub modules: Vec<Module>,
pub architecture: Architecture,
pub c_preprocessor_name: String,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Device {
pub name: String,
pub address_spaces: Vec<AddressSpace>,
pub peripherals: Vec<Peripheral>,
pub interrupts: Vec<Interrupt>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq)]
pub struct Variant {
pub name: String,
pub pinout: Option<String>,
pub package: String,
pub temperature_min: i32,
pub temperature_max: i32,
pub voltage_min: f32,
pub voltage_max: f32,
pub speed_max_hz: u64,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct AddressSpace {
pub id: String,
pub name: String,
pub start_address: u32,
pub size: u32,
pub segments: Vec<MemorySegment>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct MemorySegment {
pub name: String,
pub start_address: u32,
pub size: u32,
pub ty: String,
pub readable: bool,
pub writable: bool,
pub executable: bool,
pub page_size: Option<u32>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Peripheral {
pub name: String,
pub instances: Vec<Instance>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Interrupt {
pub name: String,
pub caption: String,
pub index: u32,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Module {
pub name: String,
pub register_groups: Vec<RegisterGroup>,
pub value_groups: Vec<ValueGroup>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Instance {
pub name: String,
pub signals: Vec<Signal>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct RegisterGroup {
pub name: String,
pub caption: String,
pub registers: Vec<Register>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct ValueGroup {
pub name: String,
pub caption: String,
pub values: Vec<Value>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Value {
pub name: String,
pub caption: String,
pub value: u32,
}
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub enum ReadWrite {
ReadAndWrite,
ReadOnly,
WriteOnly,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Register {
pub name: String,
pub caption: String,
pub offset: u32,
pub size: u32,
pub mask: Option<u32>,
pub rw: ReadWrite,
pub bitfields: Vec<Bitfield>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Bitfield {
pub name: String,
pub caption: String,
pub mask: u32,
pub size: u32,
pub values: Option<String>,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Signal {
pub pad: String,
pub group: Option<String>,
pub index: Option<u8>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Architecture {
Unknown,
Avr0,
Avr1,
Avr2,
Avr25,
Avr3,
Avr31,
Avr35,
Avr4,
Avr5,
Avr51,
Avr6,
Xmega2,
Xmega3,
Xmega4,
Xmega5,
Xmega6,
Xmega7,
Tiny,
}
#[derive(Clone, Debug, PartialOrd, PartialEq, Eq, Hash)]
pub struct Port<'a> {
instance: &'a Instance,
register_group: &'a RegisterGroup,
}
impl Mcu {
pub fn peripheral(&self, name: &str) -> Option<&Peripheral> {
self.device.peripherals.iter().find(|p| p.name == name)
}
pub fn module(&self, name: &str) -> Option<&Module> {
self.modules.iter().find(|p| p.name == name)
}
pub fn register_groups<'a>(&'a self) -> impl Iterator<Item = &'a RegisterGroup> {
self.modules.iter().flat_map(|m| m.register_groups.iter())
}
pub fn registers<'a>(&'a self) -> impl Iterator<Item = &'a Register> {
self.register_groups().flat_map(|rg| rg.registers.iter())
}
pub fn port(&self, letter: char) -> Port {
let port_name = format!("PORT{}", letter);
let instance = self
.port_peripheral()
.instance(&port_name)
.expect("no port instance with that letter found");
let register_group = self
.port_module()
.register_group(&port_name)
.expect("no port register group with that letter found");
Port { instance, register_group }
}
pub fn port_peripheral(&self) -> &Peripheral {
self.peripheral("PORT").expect("mcu does not have a port peripheral")
}
pub fn port_module(&self) -> &Module {
self.module("PORT").expect("mcu does not have a port module")
}
}
impl Peripheral {
pub fn instance(&self, name: &str) -> Option<&Instance> {
self.instances.iter().find(|i| i.name == name)
}
pub fn signals<'a>(&'a self) -> impl Iterator<Item = &'a Signal> {
self.instances.iter().flat_map(|i| i.signals.iter())
}
pub fn instance_signal_with_pad(&self, pad: &str) -> Option<(&Instance, &Signal)> {
self.instance_signals_on_pad(pad).next()
}
fn instance_signals_on_pad<'a>(
&'a self,
pad: &str,
) -> impl Iterator<Item = (&'a Instance, &'a Signal)> {
let mut instance_signals = Vec::new();
for instance in self.instances.iter() {
for signal in instance.signals.iter() {
if signal.pad == pad {
instance_signals.push((instance, signal));
}
}
}
instance_signals.into_iter()
}
}
impl Module {
pub fn register_group(&self, name: &str) -> Option<&RegisterGroup> {
self.register_groups.iter().find(|rg| rg.name == name)
}
pub fn registers<'a>(&'a self) -> impl Iterator<Item = &'a Register> {
self.register_groups.iter().flat_map(|rg| rg.registers.iter())
}
}
impl Register {
pub fn union(&self, with: &Self) -> Self {
assert_eq!(
self.name, with.name,
"can only take the union between different descriptions of the same register"
);
let mut result = self.clone();
match (result.mask, with.mask) {
(None, Some(v)) => result.mask = Some(v),
_ => (),
}
result
}
}
impl<'a> Port<'a> {
pub fn registers(&'a self) -> impl Iterator<Item = &'a Register> {
self.register_group.registers.iter()
}
pub fn signals(&'a self) -> impl Iterator<Item = &'a Signal> {
self.instance.signals.iter()
}
pub fn signal_with_pad(&'a self, pad: &str) -> Option<&'a Signal> {
self.signals().find(|s| s.pad == pad)
}
pub fn ddr_register(&self) -> &Register {
self.registers()
.find(|r| r.name.starts_with("DDR"))
.expect("port does not have ddr register")
}
pub fn port_register(&self) -> &Register {
self.registers()
.find(|r| r.name.starts_with("PORT"))
.expect("port does not have port register")
}
pub fn pin_register(&self) -> &Register {
self.registers()
.find(|r| r.name.starts_with("PIN"))
.expect("port does not have pin register")
}
}
impl Architecture {
pub fn name(&self) -> &'static str {
use Architecture::*;
match self {
Unknown => "<unknown architecture>",
Avr0 => "avr0",
Avr1 => "avr1",
Avr2 => "avr2",
Avr25 => "avr25",
Avr3 => "avr3",
Avr31 => "avr31",
Avr35 => "avr35",
Avr4 => "avr4",
Avr5 => "avr5",
Avr51 => "avr51",
Avr6 => "avr6",
Xmega2 => "xmega2",
Xmega3 => "xmega3",
Xmega4 => "xmega4",
Xmega5 => "xmega5",
Xmega6 => "xmega6",
Xmega7 => "xmega7",
Tiny => "tiny",
}
}
}