use svd_parser as svd;
use svd_parser::svd::registercluster::RegisterCluster;
use log::*;
use serde::Deserialize;
use std::fs::File;
use std::io::Read;
use crate::info::*;
#[derive(Deserialize, Debug)]
pub struct Config {}
fn parse_field(config: &Config, field: &svd_parser::svd::fieldinfo::FieldInfo) -> Field {
log::trace!(
"Field {} from {}:{}",
field.name,
field.bit_range.msb(),
field.bit_range.lsb()
);
if field.enumerated_values.len() > 1 {
unimplemented!("SVD fields with multiple enumerated values is unimplemented!");
}
let enumerations = if field.enumerated_values.len() == 1 {
let values: Vec<_> = field.enumerated_values[0]
.values
.iter()
.map(|value| {
if value.value.is_none() {
unimplemented!("Enumeration values have to have a value!");
}
Enumeration {
name: value.name.clone(),
value: value.value.unwrap() as u64,
}
})
.collect();
values
} else {
vec![]
};
Field {
name: field.name.clone(),
lsb: field.bit_range.lsb(),
msb: field.bit_range.msb(),
enumerations: enumerations,
}
}
fn parse_reg(config: &Config, reg: &svd_parser::svd::registerinfo::RegisterInfo) -> Register {
log::debug!(
"Found register {} with {} fields at offset {}",
reg.name,
reg.fields.as_deref().unwrap().len(),
reg.address_offset
);
let fields = reg
.fields
.as_deref()
.unwrap()
.iter()
.map(|field| match field {
svd_parser::svd::field::Field::Single(info) => parse_field(config, info),
svd_parser::svd::field::Field::Array(info, dims) => {
unimplemented!("Field arrays are unimplemented!");
}
})
.collect();
Register {
name: reg.name.clone(),
offset: reg.address_offset as u64,
is_raw: false,
fields: fields,
}
}
fn parse_periph(config: &Config, regs: &[RegisterCluster]) -> Vec<Register> {
log::debug!("Parsing {} RegisterClusters", regs.len());
let regs = regs
.iter()
.map(|reg| {
match reg {
RegisterCluster::Register(svd_parser::svd::register::Register::Single(reg)) => {
parse_reg(config, reg)
}
RegisterCluster::Register(svd_parser::svd::register::Register::Array(
reg,
dims,
)) => {
unimplemented!("Register arrays are unimplemented!");
println!("- reg array dims={:?}", dims);
parse_reg(config, reg);
println!("");
}
RegisterCluster::Cluster(svd_parser::svd::cluster::Cluster::Single(cluster)) => {
unimplemented!("Clusters are unimplemented!");
println!("- cluster");
}
RegisterCluster::Cluster(svd_parser::svd::cluster::Cluster::Array(
cluster,
dims,
)) => {
unimplemented!("Cluster arrays are unimplemented!");
println!("- cluster array: {} dims={:?}", cluster.name, dims);
parse_periph(config, &cluster.children);
println!("");
}
}
})
.collect();
regs
}
pub fn parse_svd(filename: &str, periph: &str, config: &Config) -> Peripheral {
let periph_name = periph;
let xml = &mut String::new();
File::open(filename).unwrap().read_to_string(xml).unwrap();
let res = svd::parse(xml).unwrap();
let periph: Vec<_> = res
.peripherals
.iter()
.filter(|p| p.name == periph)
.collect();
if periph.len() != 1 {
panic!("Unknown periph length {}!", periph.len());
}
let periph = periph[0];
println!("{}", periph.name);
if let Some(parent) = &periph.derived_from {
println!("- Derived from {}", parent);
}
let mut regs_out = vec![];
if let Some(regs) = &periph.registers {
regs_out = parse_periph(config, regs);
}
Peripheral {
name: periph_name.to_string(),
word_size: 32,
regs: regs_out,
}
}