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 Suspend register.
pub fn create(dma_channels: u64) -> Result<svd::RegisterCluster> {
    Ok(svd::RegisterCluster::Register(create_register(
        "chsusp",
        "DMAC Channel Suspend register contains the DMAC channel suspend settings. Only exists when DMAX_NUM_CHANNELS > 8",
        0x20,
        create_register_properties(64, 0)?,
        create_fields(dma_channels)?.as_deref(),
        None,
    )?))
}

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

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

fn create_susp0_fields(dma_channels: u64) -> Result<Vec<svd::Field>> {
    let (ch_name, ch_we_name, susp0_field_len) = match dma_channels {
        ch if ch > 16 => ("susp0_ch", "susp_we0_ch", 16),
        ch if ch > 8 => ("susp_ch", "susp_we_ch", ch as usize),
        _ => ("", "", 0),
    };

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