svd-generator 0.6.0

Converts device information from flattened device tree into an SVD description
Documentation
use crate::{Error, Result};

pub mod dwmac_dma;
pub mod jh7110;

/// Convenience function to create a SVD register [`Cluster`](svd::Cluster).
pub fn create_cluster(
    name: &str,
    desc: &str,
    address_offset: u32,
    children: &[svd::RegisterCluster],
    dim_element: Option<svd::DimElement>,
) -> Result<svd::Cluster> {
    let name = if dim_element.is_some() {
        format!("{name}[%s]")
    } else {
        name.into()
    };
    let info = svd::ClusterInfo::builder()
        .name(name)
        .description(Some(desc.into()))
        .address_offset(address_offset)
        .children(children.into())
        .build(svd::ValidateLevel::Strict)?;

    match dim_element {
        Some(dim) => Ok(svd::Cluster::Array(info, dim)),
        None => Ok(svd::Cluster::Single(info)),
    }
}

/// Convenience function to create a SVD [`Register`](svd::Register).
pub fn create_register(
    name: &str,
    desc: &str,
    addr_offset: u32,
    properties: svd::RegisterProperties,
    fields: Option<&[svd::Field]>,
    dim_element: Option<svd::DimElement>,
) -> Result<svd::Register> {
    let name = if dim_element.is_some() {
        format!("{name}[%s]")
    } else {
        name.into()
    };
    let info = svd::RegisterInfo::builder()
        .name(name)
        .description(Some(desc.into()))
        .address_offset(addr_offset)
        .properties(properties)
        .fields(fields.map(|f| f.into()))
        .build(svd::ValidateLevel::Weak)?;

    match dim_element {
        Some(dim) => Ok(svd::Register::Array(info, dim)),
        None => Ok(svd::Register::Single(info)),
    }
}

/// Convenience function to create a SVD [`RegisterProperties`](svd::RegisterProperties).
pub fn create_register_properties(size: u32, reset_value: u64) -> Result<svd::RegisterProperties> {
    Ok(svd::RegisterProperties::new()
        .size(Some(size))
        .reset_value(Some(reset_value))
        .build(svd::ValidateLevel::Strict)?)
}

/// Convenience function to create a SVD register [`Field`](svd::Field).
pub fn create_field(
    name: &str,
    desc: &str,
    bit_range: svd::BitRange,
    access: svd::Access,
    dim_element: Option<svd::DimElement>,
) -> Result<svd::Field> {
    let name = if dim_element.is_some() {
        format!("{name}[%s]")
    } else {
        name.into()
    };
    let info = svd::FieldInfo::builder()
        .name(name)
        .description(Some(desc.into()))
        .bit_range(bit_range)
        .access(Some(access))
        .build(svd::ValidateLevel::Strict)?;

    match dim_element {
        Some(dim) => Ok(svd::Field::Array(info, dim)),
        None => Ok(svd::Field::Single(info)),
    }
}

/// Convenience function to create a SVD register [`Field`](svd::Field) with a
/// [`WriteConstraint`](svd::WriteConstraint).
pub fn create_field_constraint(
    name: &str,
    desc: &str,
    bit_range: svd::BitRange,
    access: svd::Access,
    constraint: svd::WriteConstraint,
    dim_element: Option<svd::DimElement>,
) -> Result<svd::Field> {
    let info = svd::FieldInfo::builder()
        .name(name.into())
        .description(Some(desc.into()))
        .bit_range(bit_range)
        .access(Some(access))
        .write_constraint(Some(constraint))
        .build(svd::ValidateLevel::Strict)?;

    match dim_element {
        Some(dim) => Ok(svd::Field::Array(info, dim)),
        None => Ok(svd::Field::Single(info)),
    }
}

/// Convenience function to create a SVD register [`Field`](svd::Field) with a list of
/// [`EnumeratedValues`](svd::EnumeratedValues).
pub fn create_field_enum(
    name: &str,
    desc: &str,
    bit_range: svd::BitRange,
    access: svd::Access,
    enum_values: &[svd::EnumeratedValues],
    dim_element: Option<svd::DimElement>,
) -> Result<svd::Field> {
    let name = if dim_element.is_some() {
        format!("{name}[%s]")
    } else {
        name.into()
    };
    let info = svd::FieldInfo::builder()
        .name(name)
        .description(Some(desc.into()))
        .bit_range(bit_range)
        .access(Some(access))
        .write_constraint(Some(svd::WriteConstraint::UseEnumeratedValues(true)))
        .enumerated_values(enum_values.into())
        .build(svd::ValidateLevel::Strict)?;

    match dim_element {
        Some(dim) => Ok(svd::Field::Array(info, dim)),
        None => Ok(svd::Field::Single(info)),
    }
}

/// Convenience function to create a SVD [`EnumeratedValues`](svd::EnumeratedValues).
pub fn create_enum_values(values: &[svd::EnumeratedValue]) -> Result<svd::EnumeratedValues> {
    Ok(svd::EnumeratedValues::builder()
        .values(values.into())
        .build(svd::ValidateLevel::Strict)?)
}

/// Convenience function to create a SVD [`EnumeratedValue`](svd::EnumeratedValue).
pub fn create_enum_value(name: &str, desc: &str, value: u64) -> Result<svd::EnumeratedValue> {
    Ok(svd::EnumeratedValue::builder()
        .name(name.into())
        .description(Some(desc.into()))
        .value(Some(value))
        .build(svd::ValidateLevel::Strict)?)
}

/// Convenience function to create a SVD register [`BitRange`](svd::BitRange).
pub fn create_bit_range(range: &str) -> Result<svd::BitRange> {
    svd::BitRange::from_bit_range(range).ok_or(Error::InvalidBitRange)
}