use std::cmp;
use crate::Result;
pub fn parse_reg(
node: &device_tree::Node,
addr_cells: usize,
size_cells: usize,
) -> Result<(u64, u32)> {
let reg = node.prop_u32_list("reg")?;
let address = reg
.iter()
.take(addr_cells)
.enumerate()
.map(|(i, &r)| (r as u64) << (32 * (addr_cells - i).saturating_sub(1)))
.sum();
let size = reg
.iter()
.skip(addr_cells)
.take(size_cells)
.enumerate()
.map(|(i, &r)| (r as u64) << (32 * (size_cells - i).saturating_sub(1)))
.sum::<u64>() as u32;
Ok((address, size))
}
pub fn parse_ranges(node: &device_tree::Node, parent_addr_cells: usize) -> Result<(u64, u64, u64)> {
let addr_cells = node.prop_u32("#address-cells")? as usize;
let size_cells = node.prop_u32("#size-cells")? as usize;
let ranges = node.prop_u32_list("ranges")?;
let child_bus = ranges
.iter()
.take(parent_addr_cells)
.enumerate()
.map(|(i, &r)| (r as u64) << (32 * (parent_addr_cells - i).saturating_sub(1)))
.sum();
let parent_bus = ranges
.iter()
.skip(parent_addr_cells)
.take(addr_cells)
.enumerate()
.map(|(i, &r)| (r as u64) << (32 * (addr_cells - i).saturating_sub(1)))
.sum();
let length = ranges
.iter()
.skip(parent_addr_cells + addr_cells)
.take(size_cells)
.enumerate()
.map(|(i, &r)| (r as u64) << (32 * (size_cells - i).saturating_sub(1)))
.sum();
Ok((child_bus, parent_bus, length))
}
pub fn parse_interrupts(
node: &device_tree::Node,
default_name: &str,
count: Option<usize>,
) -> Result<Vec<svd::Interrupt>> {
let ints = node.prop_u32_list("interrupts")?;
let int_names: Vec<String> = match node.prop_str_list("interrupt-names") {
Ok(n) => n.into_iter().map(|n| n.to_uppercase()).collect(),
Err(_err) => {
if ints.len() > 1 {
let n = default_name.to_uppercase();
(0..ints.len()).map(|i| format!("{n}{i}")).collect()
} else {
[default_name.to_uppercase()].into()
}
}
};
let len = cmp::min(ints.len(), int_names.len());
let count_str = count.map(|c| format!("{c}")).unwrap_or_default();
Ok(ints
.into_iter()
.take(len)
.zip(int_names.into_iter().take(len))
.filter_map(|(int, name)| {
svd::Interrupt::builder()
.name(format!("{name}{count_str}"))
.value(int)
.build(svd::ValidateLevel::Strict)
.ok()
})
.collect())
}