use super::{
create_bit_range, create_enum_value, create_enum_values, create_field, create_field_constraint,
create_field_enum, create_register, create_register_properties,
};
use crate::{Error, Result};
pub fn create_register_icg_divcfg(
name: &str,
desc: &str,
addr_offset: u32,
mdmt: [u64; 4],
default: Option<u64>,
dim_elem: Option<svd::DimElement>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(mdmt[1]))?,
Some(&[create_field_icg()?, create_field_divcfg(mdmt)?]),
dim_elem,
)?))
}
pub fn create_register_divcfg(
name: &str,
desc: &str,
addr_offset: u32,
mdmt: [u64; 4],
dim_elem: Option<svd::DimElement>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, mdmt[1])?,
Some(&[create_field_divcfg(mdmt)?]),
dim_elem,
)?))
}
pub fn create_field_divcfg(mdmt: [u64; 4]) -> Result<svd::Field> {
let (max, def, min, typ) = (mdmt[0], mdmt[1], mdmt[2], mdmt[3]);
create_field_constraint(
"clk_divcfg",
format!("Clock divider coefficient: Max={max}, Default={def}, Min={min}, Typical={typ}")
.as_str(),
create_bit_range("[23:0]")?,
svd::Access::ReadWrite,
svd::WriteConstraint::Range(svd::WriteConstraintRange { min, max }),
None,
)
}
pub fn create_register_icg(
name: &str,
desc: &str,
addr_offset: u32,
default: Option<u64>,
dim_elem: Option<svd::DimElement>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&[create_field_icg()?]),
dim_elem,
)?))
}
pub fn create_field_icg() -> Result<svd::Field> {
create_field_enum(
"clk_icg",
"Clock ICG enable.",
create_bit_range("[31:31]")?,
svd::Access::ReadWrite,
&[create_enum_values(&[
create_enum_value("disable", "Disable the clock.", 0b0)?,
create_enum_value("enable", "Enable the clock.", 0b1)?,
])?],
None,
)
}
pub fn create_register_mux_sel(
name: &str,
desc: &str,
addr_offset: u32,
field_desc: &str,
default: Option<u64>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&[create_field_mux_sel(field_desc)?]),
None,
)?))
}
pub fn create_register_mux_sel_enum(
name: &str,
desc: &str,
addr_offset: u32,
field_desc: &str,
field_values: &[svd::EnumeratedValue],
default: Option<u64>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&[create_field_mux_sel_enum(field_desc, field_values)?]),
None,
)?))
}
pub fn create_register_icg_mux_sel(
name: &str,
desc: &str,
addr_offset: u32,
field_desc: &str,
default: Option<u64>,
dim_elem: Option<svd::DimElement>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&[create_field_mux_sel(field_desc)?, create_field_icg()?]),
dim_elem,
)?))
}
pub fn create_register_icg_mux_sel_enum(
name: &str,
desc: &str,
addr_offset: u32,
field_desc: &str,
field_values: &[svd::EnumeratedValue],
default: Option<u64>,
dim_elem: Option<svd::DimElement>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&[
create_field_mux_sel_enum(field_desc, field_values)?,
create_field_icg()?,
]),
dim_elem,
)?))
}
pub fn create_register_mux_sel_divcfg(
name: &str,
desc: &str,
addr_offset: u32,
field_desc: &str,
mdmt: [u64; 4],
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, mdmt[1])?,
Some(&[
create_field_mux_sel(field_desc)?,
create_field_divcfg(mdmt)?,
]),
None,
)?))
}
pub fn create_register_mux_sel_divcfg_enum(
name: &str,
desc: &str,
addr_offset: u32,
field_desc: &str,
field_values: &[svd::EnumeratedValue],
mdmt: [u64; 4],
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, mdmt[1])?,
Some(&[
create_field_mux_sel_enum(field_desc, field_values)?,
create_field_divcfg(mdmt)?,
]),
None,
)?))
}
pub fn create_field_mux_sel(field_desc: &str) -> Result<svd::Field> {
create_field(
"clk_mux_sel",
format!("Clock multiplexing selector: {field_desc}").as_str(),
create_bit_range("[29:24]")?,
svd::Access::ReadWrite,
None,
)
}
pub fn create_field_mux_sel_enum(
field_desc: &str,
field_values: &[svd::EnumeratedValue],
) -> Result<svd::Field> {
create_field_enum(
"clk_mux_sel",
format!("Clock multiplexing selector: {field_desc}").as_str(),
create_bit_range("[29:24]")?,
svd::Access::ReadWrite,
&[create_enum_values(field_values)?],
None,
)
}
pub fn create_register_clk_polarity(
name: &str,
desc: &str,
addr_offset: u32,
default: Option<u64>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&[create_field_clk_polarity()?]),
None,
)?))
}
pub fn create_field_clk_polarity() -> Result<svd::Field> {
create_field_enum(
"clk_polarity",
"Clock polarity settings.",
create_bit_range("[30:30]")?,
svd::Access::ReadWrite,
&[create_enum_values(&[
create_enum_value(
"buffer",
"Set the clock polarity to use the clock buffer.",
0b0,
)?,
create_enum_value(
"inverter",
"Set the clock polarity to use the clock inverter.",
0b1,
)?,
])?],
None,
)
}
pub fn create_register_aon_rst_sel(
name: &str,
desc: &str,
addr_offset: u32,
default: Option<u64>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&create_fields_aon_rst_sel()?),
None,
)?))
}
pub fn create_fields_aon_rst_sel() -> Result<[svd::Field; 8]> {
let enum_vals = [create_enum_values(&[
create_enum_value("none", "De-assert the reset.", 0b0)?,
create_enum_value("reset", "Assert the reset.", 0b1)?,
])?];
Ok([
create_field_enum(
"gmac5_axi64_axi",
"GMAC5 AXI64 AXI reset.",
create_bit_range("[0:0]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"gmac5_axi64_ahb",
"GMAC5 AXI64 AHB reset.",
create_bit_range("[1:1]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"aon_iomux_presetn",
"AON IOMUX Presetn reset.",
create_bit_range("[2:2]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"pmu_apb",
"PMU APB reset.",
create_bit_range("[3:3]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"pmu_wkup",
"PMU Wake-up reset.",
create_bit_range("[4:4]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"rtc_hms_apb",
"RTC HMS APB reset.",
create_bit_range("[5:5]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"rtc_hms_cal",
"RTC HMS CAL reset.",
create_bit_range("[6:6]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"rtc_hms_osc32k",
"RTC HMS Oscillator 32k reset.",
create_bit_range("[7:7]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
])
}
pub fn create_register_rst_sel(
name: &str,
desc: &str,
addr_offset: u32,
idx: usize,
default: Option<u64>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&create_fields_rst_sel(idx)?),
None,
)?))
}
pub fn create_fields_rst_sel(idx: usize) -> Result<Vec<svd::Field>> {
const RST_LEN: usize = 4;
const RST_NAMES: [[&str; 32]; RST_LEN] = [
[
"u0_jtag2apb_presetn",
"u0_sys_syscon_presetn",
"u0_sys_iomux_presetn",
"u0_bus",
"u0_debug",
"u0_core_0",
"u0_core_1",
"u0_core_2",
"u0_core_3",
"u0_core_4",
"u0_core_st_0",
"u0_core_st_1",
"u0_core_st_2",
"u0_core_st_3",
"u0_core_st_4",
"u0_trace_0",
"u0_trace_1",
"u0_trace_2",
"u0_trace_3",
"u0_trace_4",
"u0_trace_com",
"u0_img_gpu_apb",
"u0_img_gpu_doma",
"u0_noc_bus_apb",
"u0_noc_bus_axicfg0",
"u0_noc_bus_cpu_axi",
"u0_noc_bus_disp_axi",
"u0_noc_bus_gpu_axi",
"u0_noc_bus_isp_axi",
"u0_noc_bus_ddrc",
"u0_noc_bus_stg_axi",
"u0_noc_bus_vdec_axi",
],
[
"u0_noc_bus_venc_axi",
"u0_axi_cfg1_dec_ahb",
"u0_axi_cfg1_dec_main",
"u0_axi_cfg0_dec_main",
"u0_axi_cfg0_dec_main_div",
"u0_axi_cfg0_dec_hifi4",
"u0_ddr_axi",
"u0_ddr_osc",
"u0_ddr_apb",
"u0_isp_top",
"u0_isp_axi",
"u0_vout_src",
"u0_codaj12_axi",
"u0_codaj12_core",
"u0_codaj12_apb",
"u0_wave511_axi",
"u0_wave511_bpu",
"u0_wave511_vce",
"u0_wave511_apb",
"u0_vdec_jpg_arb",
"u0_vdec_jpg_arb_main",
"u0_aximem_128b_axi",
"u0_wave420l_axi",
"u0_wave420l_bpu",
"u0_wave420l_vce",
"u0_wave420l_apb",
"u1_aximem",
"u2_aximem",
"u0_intmem_rom_sram",
"u0_qspi_ahb",
"u0_qspi_apb",
"u0_qspi_ref",
],
[
"u0_sdio_ahb",
"u1_sdi_ahb",
"u1_gmac5_axi64",
"u1_gmac5_axi64_hresetn",
"u0_mailbox_presetn",
"u0_spi_apb",
"u1_spi_apb",
"u2_spi_apb",
"u3_spi_apb",
"u4_spi_apb",
"u5_spi_apb",
"u6_spi_apb",
"u0_i2c_apb",
"u1_i2c_apb",
"u2_i2c_apb",
"u3_i2c_apb",
"u4_i2c_apb",
"u5_i2c_apb",
"u6_i2c_apb",
"u0_uart_apb",
"u0_uart_core",
"u1_uart_apb",
"u1_uart_core",
"u2_uart_apb",
"u2_uart_core",
"u3_uart_apb",
"u3_uart_core",
"u4_uart_apb",
"u4_uart_core",
"u5_uart_apb",
"u6_uart_core",
"u0_spdif_apb",
],
[
"u0_pwmdac_apb",
"u0_pdm_4mic_dmic",
"u0_pdm_4mic_apb",
"u0_i2srx_apb",
"u0_i2srx_bclk",
"u0_i2stx_apb",
"u0_i2stx_bclk",
"u1_i2stx_apb",
"u1_i2stx_bclk",
"u0_tdm16slot_ahb",
"u0_tdm16slot_tdm",
"u0_tdm16slot_apb",
"u0_pwm_apb",
"u0_dskit_wdt_rstn_apb",
"u0_dskit_wdt",
"u0_can_ctrl_apb",
"u0_can_ctrl",
"u0_can_ctrl_timer",
"u1_can_ctrl_apb",
"u1_can_ctrl_can",
"u1_can_ctrl_timer",
"u0_si5_timer_apb",
"u0_si5_timer_0",
"u0_si5_timer_1",
"u0_si5_timer_2",
"u0_si5_timer_3",
"u0_int_ctrl_apb",
"u0_temp_sensor_apb",
"u0_temp_sensor",
"u0_jtag_rst",
"",
"",
],
];
if idx > RST_LEN {
Err(Error::Svd(format!(
"invalid RST selector index, have: {idx}, max: {RST_LEN}"
)))
} else {
let enum_vals = [create_enum_values(&[
create_enum_value("none", "De-assert reset.", 0b0)?,
create_enum_value("reset", "Assert reset.", 0b1)?,
])?];
Ok(RST_NAMES[idx]
.iter()
.enumerate()
.filter_map(|(i, n)| {
if n.is_empty() {
None
} else {
create_field_enum(
n,
format!("Reset selector: {n}").as_str(),
create_bit_range(format!("[{i}:{i}]").as_str()).ok()?,
svd::Access::ReadWrite,
&enum_vals,
None,
)
.ok()
}
})
.collect())
}
}
pub fn create_register_dly_chain_sel(
name: &str,
desc: &str,
addr_offset: u32,
default: Option<u64>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&[create_field_dly_chain_sel()?]),
None,
)?))
}
pub fn create_field_dly_chain_sel() -> Result<svd::Field> {
create_field(
"dly_chain_sel",
"Selector delay chain stage number, totally 32 stages, -50 ps each stage. The register value indicates the delay chain stage number. For example, diy_chain_sel=1 means to delay 1 stage.",
create_bit_range("[23:0]")?,
svd::Access::ReadWrite,
None,
)
}
pub fn create_fields_sram_config(name: &str, base: u32) -> Result<[svd::Field; 8]> {
Ok([
create_field(
format!("{name}_slp").as_str(),
"SRAM/ROM configuration. SLP: sleep enable, high active, default is low.",
create_bit_range(format!("[{base}:{base}]").as_str())?,
svd::Access::ReadWrite,
None,
)?,
create_field(
format!("{name}_sd").as_str(),
"SRAM/ROM configuration. SD: shutdown enable, high active, default is low.",
create_bit_range(format!("[{}:{}]", base + 1, base + 1).as_str())?,
svd::Access::ReadWrite,
None,
)?,
create_field(
format!("{name}_rtsel").as_str(),
"SRAM/ROM configuration. RTSEL: timing setting for debug purpose, default is 2'b01.",
create_bit_range(format!("[{}:{}]", base + 3, base + 2).as_str())?,
svd::Access::ReadWrite,
None,
)?,
create_field(
format!("{name}_ptsel").as_str(),
"SRAM/ROM configuration. PTSEL: timing setting for debug purpose, default is 2'b01.",
create_bit_range(format!("[{}:{}]", base + 5, base + 4).as_str())?,
svd::Access::ReadWrite,
None,
)?,
create_field(
format!("{name}_trb").as_str(),
"SRAM/ROM configuration. TRB: timing setting for debug purpose, default is 2'b01.",
create_bit_range(format!("[{}:{}]", base + 7, base + 6).as_str())?,
svd::Access::ReadWrite,
None,
)?,
create_field(
format!("{name}_wtsel").as_str(),
"SRAM/ROM configuration. WTSEL: timing setting for debug purpose, default is 2'b01.",
create_bit_range(format!("[{}:{}]", base + 9, base + 8).as_str())?,
svd::Access::ReadWrite,
None,
)?,
create_field(
format!("{name}_vs").as_str(),
"SRAM/ROM configuration. VS: timing setting for debug purpose, default is 1'b1.",
create_bit_range(format!("[{}:{}]", base + 10, base + 10).as_str())?,
svd::Access::ReadWrite,
None,
)?,
create_field(
format!("{name}_vg").as_str(),
"SRAM/ROM configuration. VG: timing setting for debug purpose, default is 1'b1.",
create_bit_range(format!("[{}:{}]", base + 11, base + 11).as_str())?,
svd::Access::ReadWrite,
None,
)?,
])
}
pub fn create_register_rst_stat(
name: &str,
desc: &str,
addr_offset: u32,
default: Option<u64>,
dim_element: Option<svd::DimElement>,
) -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Register(create_register(
name,
desc,
addr_offset,
create_register_properties(32, default.unwrap_or(0))?,
Some(&create_fields_rst_stat()?),
dim_element,
)?))
}
pub fn create_fields_rst_stat() -> Result<[svd::Field; 23]> {
let enum_vals = [create_enum_values(&[
create_enum_value("none", "De-assert reset.", 0b0)?,
create_enum_value("reset", "Assert reset.", 0b1)?,
])?];
Ok([
create_field_enum(
"u0_stg_syscon_presetn",
"U0 STG SYSCON Presetn reset.",
create_bit_range("[0:0]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_hifi4_core",
"U0 HIFI4 Core reset.",
create_bit_range("[1:1]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_hifi4_axi",
"U0 HIFI4 AXI reset.",
create_bit_range("[2:2]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_sec_top_hresetn",
"U0 SEC Top HResetn reset.",
create_bit_range("[3:3]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_e2_core",
"U0 E2 Core reset.",
create_bit_range("[4:4]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_dma_axi",
"U0 DMA AXI reset.",
create_bit_range("[5:5]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_dma_ahb",
"U0 DMA AHB reset.",
create_bit_range("[6:6]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_usb_axi",
"U0 USB AXI reset.",
create_bit_range("[7:7]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_usb_apb",
"U0 USB APB reset.",
create_bit_range("[8:8]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_usb_utmi_apb",
"U0 USB UTMI APB reset.",
create_bit_range("[9:9]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_usb_pwrup",
"U0 USB Power-up reset.",
create_bit_range("[10:10]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_pcie_axi_mst0",
"U0 PCIE AXI MST0 reset.",
create_bit_range("[11:11]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_pcie_axi_slv0",
"U0 PCIE AXI SLV0 reset.",
create_bit_range("[12:12]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_pcie_axi_slv",
"U0 PCIE AXI SLV reset.",
create_bit_range("[13:13]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_pci_brg",
"U0 PCI BRG reset.",
create_bit_range("[14:14]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_pcie_pcie",
"U0 PCIE main reset.",
create_bit_range("[15:15]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u0_pcie_apb",
"U0 PCIE APB reset.",
create_bit_range("[16:16]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u1_pcie_axi_mst0",
"U1 PCIE AXI MST0 reset.",
create_bit_range("[17:17]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u1_pcie_axi_slv0",
"U1 PCIE AXI SLV0 reset.",
create_bit_range("[18:18]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u1_pcie_axi_slv",
"U1 PCIE AXI SLV reset.",
create_bit_range("[19:19]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u1_pcie_brg",
"U1 PCIE BRG reset.",
create_bit_range("[20:20]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u1_pcie_pcie",
"U1 PCIE main reset.",
create_bit_range("[21:21]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
create_field_enum(
"u1_pcie_apb",
"U1 PCIE APB reset.",
create_bit_range("[22:22]")?,
svd::Access::ReadWrite,
&enum_vals,
None,
)?,
])
}