svd-generator 0.4.1

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

/// Creates ARM PL080 DMA Controller Channel registers.
pub fn create() -> Result<svd::RegisterCluster> {
    Ok(svd::RegisterCluster::Cluster(create_cluster(
        "channel",
        "DMAC Channel registers",
        0x100,
        &[
            svd::RegisterCluster::Register(create_register(
                "src_addr",
                "DMAC Source Address register - contain the current source address, byte-aligned, of the data to be transferred. Software programs each register directly before the appropriate channel is enabled.",
                0x0,
                create_register_properties(32, 0)?,
                Some(&[
                    create_field(
                        "src_addr",
                        "DMA source address.",
                        create_bit_range("[31:0]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                ]),
                None,
            )?),
            svd::RegisterCluster::Register(create_register(
                "dst_addr",
                "DMA Destination Address register - contain the current destination address, byte-aligned, of the data to be transferred. Software programs each register directly before the channel is enabled. When the DMA channel is enabled, the register is updated as the destination address is incremented and by following the linked list when a complete packet of data has been transferred. Reading the register when the channel is active does not provide useful information. This is because by the time the software has processed the value read, the channel might have progressed. It is intended to be read-only when a channel has stopped. In this case, it shows the destination address of the last item read.",
                0x4,
                create_register_properties(32, 0)?,
                Some(&[
                    create_field(
                        "dst_addr",
                        "DMA destination address.",
                        create_bit_range("[31:0]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                ]),
                None,
            )?),
            svd::RegisterCluster::Register(create_register(
                "lli",
                "DMA Linked List Item register",
                0x8,
                create_register_properties(32, 0)?,
                Some(&[
                    create_field(
                        "lm",
                        "AHB master select for loading the next LLI. 0: AHB Master 1, 1: AHB Master 2.",
                        create_bit_range("[0:0]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "lli",
                        "Linked list item. Bits [31:2] of the address for the next LLI. Address bits [1:0] are 0.",
                        create_bit_range("[31:2]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                ]),
                None,
            )?),
            svd::RegisterCluster::Register(create_register(
                "control",
                "DMA Channel Control register",
                0xc,
                create_register_properties(32, 0)?,
                Some(&[
                    create_field(
                        "transfer_size",
                        "Transfer size. A write to this field sets the size of the transfer when the DMAC is the flow controller. This value counts down from the original value to zero, and so its value indicates the number of transfers left to complete. A read from this field provides the number of transfers still to be completed on the destination bus. Reading the register when the channel is active does not give useful information because by the time the software has processed the value read, the channel might have progressed. Only use it when a channel is enabled, and then disabled. The ARM PrimeCell DMA Controller (PL080) Design Manual provides more information about the use of this field. Program the transfer size value to zero if the DMAC is not the flow controller. If you program the TransferSize to a non-zero value, the DMAC might attempt to use this value instead of ignoring the TransferSize.",
                        create_bit_range("[11:0]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "sb_size",
                        "Source burst size - 0: 1, 1: 4, 2: 8, 3: 16, 4: 32, 5: 64, 6: 128, 7: 256. Indicates the number of transfers that make up a source burst. You must set this value to the burst size of the source peripheral, or if the source is memory, to the memory boundary size. The burst size is the amount of data that is transferred when the DMACxBREQ signal goes active in the source peripheral. The burst size is not related to the AHB HBURST signal.",
                        create_bit_range("[14:12]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "db_size",
                        "Destination burst size - 0: 1, 1: 4, 2: 8, 3: 16, 4: 32, 5: 64, 6: 128, 7: 256. Indicates the number of transfers that make up a destination burst transfer request. You must set this value to the burst size of the destination peripheral, or if the destination is memory, to the memory boundary size. The burst size is the amount of data that is transferred when the DMACxBREQ signal goes active in the destination peripheral. The burst size is not related to the AHB HBURST signal.",
                        create_bit_range("[17:15]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "src_width",
                        "Source transfer width - 0: 8-bit, 1: 16-bit, 2: 32-bit. Transfers wider than the AHB master bus width are illegal. The source and destination widths can be different from each other. The hardware automatically packs and unpacks the data when required.",
                        create_bit_range("[20:18]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "dst_width",
                        "Destination transfer width - 0: 8-bit, 1: 16-bit, 2: 32-bit. Transfers wider than the AHB master bus width are illegal. The source and destination widths can be different from each other. The hardware automatically packs and unpacks the data when required.",
                        create_bit_range("[23:21]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "src",
                        "Source AHB master select - 0: AHB master 1 selected, 1: AHB master 2 selected.",
                        create_bit_range("[24:24]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "dst",
                        "Destination AHB master select - 0: AHB master 1 selected, 1: AHB master 2 selected.",
                        create_bit_range("[25:25]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "src_inc",
                        "Source increment. When set, the source address is incremented after each transfer.",
                        create_bit_range("[26:26]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "dst_inc",
                        "Destination increment. When set, the destination address is incremented after each transfer.",
                        create_bit_range("[27:27]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "prot_user",
                        "Protection - 0: user mode, 1: privileged mode. Indicates whether the access is in User or Privileged mode. This bit controls the AHB HPROT[1] signal.",
                        create_bit_range("[28:28]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "prot_buf",
                        "Protection - 0: non-bufferable, 1: bufferable. Indicates whether or not the access can be buffered. This bit indicates whether or not the access is bufferable. For example, you can use this bit to indicate to an AMBA bridge that the read can complete in zero wait states on the source bus without waiting for it to arbitrate for the destination bus and for the slave to accept the data. This bit controls the AHB HPROT[2] signal.",
                        create_bit_range("[29:29]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "prot_cache",
                        "Protection - 0: non-cacheable, 1: cacheable. This bit indicates whether or not the access is cacheable. For example, you can use this bit to indicate to an AMBA bridge that when it saw the first read of a burst of eight it can transfer the whole burst of eight reads on the destination bus, rather than pass the transactions through one at a time. This bit controls the AHB HPROT[3] signal.",
                        create_bit_range("[30:30]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "ie",
                        "Terminal count interrupt enable bit. It controls whether the current LLI is expected to trigger the terminal count interrupt.",
                        create_bit_range("[31:31]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                ]),
                None,
            )?),
            svd::RegisterCluster::Register(create_register(
                "configuration",
                "DMA Channel Configuration register",
                0x10,
                create_register_properties(32, 0)?,
                Some(&[
                    create_field(
                        "enable",
                        "Channel enable - 0: channel disabled, 1: channel enabled.",
                        create_bit_range("[0:0]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "src_peripheral",
                        "Source peripheral. This value selects the DMA source request peripheral. This field is ignored if the source of the transfer is from memory.",
                        create_bit_range("[4:1]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "dst_peripheral",
                        "Destination peripheral. This value selects the DMA destination request peripheral. This field is ignored if the destination of the transfer is to memory.",
                        create_bit_range("[9:6]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "flow_cntrl",
                        "Flow control and transfer type. This value indicates the flow controller and transfer type. The flow controller can be the DMAC, the source peripheral, or the destination peripheral. The transfer type can be memory-to-memory, memory-to-peripheral, peripheral-to-memory, or peripheral-to-peripheral.",
                        create_bit_range("[13:11]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "iem",
                        "Interrupt error mask. When cleared, this bit masks out the error interrupt of the relevant channel.",
                        create_bit_range("[14:14]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "itc",
                        "Terminal count interrupt mask. When cleared, this bit masks out the terminal count interrupt of the relevant channel.",
                        create_bit_range("[15:15]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "lock",
                        "Lock. When set, this bit enables locked transfers. For details of how lock control works.",
                        create_bit_range("[16:16]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                    create_field(
                        "active",
                        "Active - 0: there channel FIFO has no data, 1: the channel FIFO has data.",
                        create_bit_range("[17:17]")?,
                        svd::Access::ReadOnly,
                        None,
                    )?,
                    create_field(
                        "halt",
                        "Halt - 0: enable DMA requests, 1: ignore extra source DMA requests. The contents of the channels FIFO are drained. You can use this value with the Active and Channel Enable bits to cleanly disable a DMA channel.",
                        create_bit_range("[18:18]")?,
                        svd::Access::ReadWrite,
                        None,
                    )?,
                ]),
                None,
            )?),
            svd::RegisterCluster::Register(create_register(
                "_Reserved",
                "Reserved",
                0x14,
                create_register_properties(32, 0)?,
                Some(&[
                    create_field(
                        "_reserved",
                        "Reserved",
                        create_bit_range("[31:0]")?,
                        svd::Access::ReadOnly,
                        None,
                    )?,
                ]),
                Some(svd::DimElement::builder()
                    .dim(3)
                    .dim_increment(0x4)
                    .build(svd::ValidateLevel::Strict)?),
            )?),
        ],
        Some(svd::DimElement::builder()
            .dim(8)
            .dim_increment(0x20)
            .build(svd::ValidateLevel::Strict)?),
    )?))
}