use crate::svd::register::{
create_bit_range, create_cluster, create_field, create_register, create_register_properties,
};
use crate::Result;
pub fn create() -> Result<svd::RegisterCluster> {
Ok(svd::RegisterCluster::Cluster(create_cluster(
"func_sel",
"Registers used to configure the function selector of the system signal indicated by the register name.",
0x29c,
&[
create_register_func_sel0()?,
create_register_func_sel1()?,
create_register_func_sel2()?,
create_register_func_sel3()?,
create_register_func_sel4()?,
create_register_func_sel5()?,
create_register_func_sel6()?,
],
None,
)?))
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
enum FuncSel {
#[default]
Gmac = 0,
Gpio = 1,
DvpData = 2,
DvpHsync = 3,
DvpVsync = 4,
DvpClock = 5,
}
impl From<&FuncSel> for &'static str {
fn from(val: &FuncSel) -> Self {
match val {
FuncSel::Gmac => "Function selector of GMAC1_RXC: * Function 0: u0_sys_crg.clk_gmac1_rgmii_rx, * Function 1: u0_sys_crg.clk_gmac1_rmii_ref, * Function 2: None, * Function 3: None",
FuncSel::Gpio => "GPIO function selector: * Function 0: See Function Description no page 84 for more information, * Function 1: See Full Multiplexing for more information, * Function 2: See Function 2 for more information, * Function 3: See Function 3 for more information",
FuncSel::DvpData => "Function Selector of DVP_DATA[idx], see Function 2 for more information",
FuncSel::DvpHsync => "Function Selector of DVP_HSYNC, see Function 2 for more information",
FuncSel::DvpVsync => "Function Selector of DVP_VSYNC, see Function 2 for more information",
FuncSel::DvpClock => "Function Selector of DVP_CLK, see Function 2 for more information",
}
}
}
type NameFuncRange = (String, FuncSel, svd::BitRange);
fn create_register_func_sel(idx: u32, nfra: &[NameFuncRange]) -> Result<svd::RegisterCluster> {
let addr = idx * 4;
Ok(svd::RegisterCluster::Register(create_register(
format!("func_sel{idx}").as_str(),
format!("SYS IOMUX CFG SAIF SYSCFG Function Selector {addr}").as_str(),
addr,
create_register_properties(32, 0)?,
Some(
nfra.iter()
.filter_map(|(fname, func, range)| {
create_field(
fname.as_str(),
func.into(),
*range,
svd::Access::ReadWrite,
None,
)
.ok()
})
.collect::<Vec<svd::Field>>()
.as_ref(),
),
None,
)?))
}
fn create_register_func_sel0() -> Result<svd::RegisterCluster> {
let nfras = (0..11)
.filter_map(|idx| {
if idx == 0 {
Some((
"pad_gmac1_rxc".into(),
FuncSel::Gmac,
create_bit_range("[1:0]").ok()?,
))
} else {
let pad = idx - 1;
let bit = 2 + (pad * 3);
let bit_end = bit + 2;
Some((
format!("pad_gpio1{pad}"),
FuncSel::Gpio,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
}
})
.collect::<Vec<NameFuncRange>>();
create_register_func_sel(0, nfras.as_ref())
}
fn create_register_func_sel1() -> Result<svd::RegisterCluster> {
let nfras = (0..10)
.filter_map(|idx| {
let pad = 20 + idx;
let bit = idx * 3;
let bit_end = bit + 2;
Some((
format!("pad_gpio{pad}"),
FuncSel::Gpio,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
})
.collect::<Vec<NameFuncRange>>();
create_register_func_sel(1, nfras.as_ref())
}
fn create_register_func_sel2() -> Result<svd::RegisterCluster> {
let nfras = (0..11)
.filter_map(|idx| {
let pad = 30 + idx;
let bit = idx * 3;
let bit_end = bit + 2;
Some((
format!("pad_gpio{pad}"),
FuncSel::Gpio,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
})
.collect::<Vec<NameFuncRange>>();
create_register_func_sel(2, nfras.as_ref())
}
fn create_register_func_sel3() -> Result<svd::RegisterCluster> {
let nfras = (0..11)
.filter_map(|idx| {
let pad = 41 + idx;
let bit = idx * 3;
let bit_end = bit + 2;
Some((
format!("pad_gpio{pad}"),
FuncSel::Gpio,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
})
.collect::<Vec<NameFuncRange>>();
create_register_func_sel(3, nfras.as_ref())
}
fn create_register_func_sel4() -> Result<svd::RegisterCluster> {
let nfras = (0..12)
.filter_map(|idx| {
if idx < 11 {
let pad = 52 + idx;
let (bit, bit_end) = if idx < 4 {
(idx * 2, (idx * 2) + 1)
} else {
(idx * 3, (idx * 3) + 2)
};
Some((
format!("pad_gpio{pad}"),
FuncSel::Gpio,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
} else {
Some((
"pad_gpio63".into(),
FuncSel::Gpio,
create_bit_range("[31:30]").ok()?,
))
}
})
.collect::<Vec<NameFuncRange>>();
create_register_func_sel(4, nfras.as_ref())
}
fn create_register_func_sel5() -> Result<svd::RegisterCluster> {
let nfras = [6, 7, 8, 9, 0, 10, 11, 1, 2, 3, 4]
.iter()
.enumerate()
.filter_map(|(idx, &pad)| {
if idx == 0 {
Some((
"pad_gpio6".into(),
FuncSel::Gpio,
create_bit_range("[1:0]").ok()?,
))
} else if idx < 5 {
let bit = idx * 2;
let bit_end = bit + 2;
Some((
format!("pad_gpio{pad}"),
FuncSel::Gpio,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
} else {
let bit = 11 + ((idx - 5) * 3);
let bit_end = bit + 2;
Some((
format!("vin_dvp_data{pad}"),
FuncSel::DvpData,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
}
})
.collect::<Vec<NameFuncRange>>();
create_register_func_sel(5, nfras.as_ref())
}
fn create_register_func_sel6() -> Result<svd::RegisterCluster> {
let nfras = (0..8)
.filter_map(|idx| {
if idx < 6 {
let data = 5 + idx;
let bit = idx * 3;
let bit_end = bit + 2;
Some((
format!("vin_dvp_data{data}"),
FuncSel::DvpData,
create_bit_range(format!("[{bit_end}:{bit}]").as_str()).ok()?,
))
} else if idx == 6 {
Some((
"vin_dvp_hvalid".into(),
FuncSel::DvpHsync,
create_bit_range("[17:15]").ok()?,
))
} else if idx == 7 {
Some((
"vin_dvp_vvalid".into(),
FuncSel::DvpVsync,
create_bit_range("[20:18]").ok()?,
))
} else {
Some((
"dvp_clk".into(),
FuncSel::DvpClock,
create_bit_range("[23:21]").ok()?,
))
}
})
.collect::<Vec<NameFuncRange>>();
create_register_func_sel(6, nfras.as_ref())
}