svd-generator 0.7.0

Converts device information from flattened device tree into an SVD description
Documentation
use crate::svd::register::{
    create_bit_range, create_field, create_register, create_register_properties,
};
use crate::Result;

/// Creates Synopsys DesignWare AXI DMAC Channel Enable 2 register.
pub fn create(dma_channels: u64) -> Result<svd::RegisterCluster> {
    Ok(svd::RegisterCluster::Register(create_register(
        "chen2",
        "DMAC Channel Enable register contains the DMAC channel enable settings. Only exists when DMAX_NUM_CHANNELS > 8",
        0x18,
        create_register_properties(64, 0)?,
        create_fields(dma_channels)?.as_deref(),
        None,
    )?))
}

fn create_fields(dma_channels: u64) -> Result<Option<Vec<svd::Field>>> {
    let en1_field_len = dma_channels.saturating_sub(16) as usize;

    match dma_channels {
        ch if ch > 16 => Ok(Some(create_en0_fields(dma_channels)?.into_iter().chain([
                create_field(
                    "en1_ch",
                    "DMAC Channel Enable - 0: disable DMAC channel, 1: enable DMAC channel",
                    create_bit_range("[32:32]")?,
                    svd::Access::ReadWrite,
                    Some(svd::DimElement::builder()
                        .dim(en1_field_len as u32)
                        .dim_increment(1)
                        .dim_index(Some((17..=32).map(|s| format!("{s}")).take(en1_field_len).collect::<Vec<String>>()))
                        .build(svd::ValidateLevel::Strict)?),
                )?,
                create_field(
                    "en_we1_ch",
                    "DMAC Channel Enable Write-enable - 0: disable write to DMAC channel enable bit, 1: enable write to DMAC channel enable bit",
                    create_bit_range("[48:48]")?,
                    svd::Access::WriteOnly,
                    Some(svd::DimElement::builder()
                        .dim(en1_field_len as u32)
                        .dim_increment(1)
                        .dim_index(Some((17..=32).map(|s| format!("{s}")).take(en1_field_len).collect::<Vec<String>>()))
                        .build(svd::ValidateLevel::Strict)?),
                )?,
        ]).collect::<Vec<_>>())),
        ch if ch > 8 => Ok(Some(create_en0_fields(dma_channels)?)),
        _ => Ok(None),
    }
}

fn create_en0_fields(dma_channels: u64) -> Result<Vec<svd::Field>> {
    let (ch_name, ch_we_name, en0_field_len) = match dma_channels {
        ch if ch > 16 => ("en0_ch", "en_we0_ch", 16),
        ch => ("en_ch", "en_we_ch", ch as usize),
    };

    Ok(vec![
        create_field(
            ch_name,
            "DMAC Channel Enable - 0: disable DMAC channel, 1: enable DMAC channel",
            create_bit_range("[0:0]")?,
            svd::Access::ReadWrite,
            Some(svd::DimElement::builder()
                .dim(en0_field_len as u32)
                .dim_increment(1)
                .dim_index(Some((1..=16).map(|s| format!("{s}")).take(en0_field_len).collect::<Vec<String>>()))
                .build(svd::ValidateLevel::Strict)?),
        )?,
        create_field(
            ch_we_name,
            "DMAC Channel Enable Write-enable - 0: disable write to DMAC channel enable bit, 1: enable write to DMAC channel enable bit",
            create_bit_range("[16:16]")?,
            svd::Access::WriteOnly,
            Some(svd::DimElement::builder()
                .dim(en0_field_len as u32)
                .dim_increment(1)
                .dim_index(Some((1..=16).map(|s| format!("{s}")).take(en0_field_len).collect::<Vec<String>>()))
                .build(svd::ValidateLevel::Strict)?),
        )?,
    ])
}