Skip to content

Commit

Permalink
feat: add iomux definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
andelf committed Jun 28, 2024
1 parent 0c1d843 commit bde2bb2
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 13 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ All PRs and Issues are handled in [andelf/hpm-data](https://github.com/andelf/hp

### Support status

- [x] HPM5300
- [x] HPM6700/HPM6400
- [x] HPM6300
- [x] HPM6800
- [x] HPM6200
- [ ] HPM6E00 - WIP
- [x] HPM5300
- [x] HPM6800
- [x] HPM6E00
- pinmux is missing

## hpm-metapac

Expand All @@ -42,6 +43,7 @@ All PRs and Issues are handled in [andelf/hpm-data](https://github.com/andelf/hp
- To best fit for HPM RISC-V's cluster register desigin, the following is added:
- All clocks, for `SYSCTL.CLOCK`, in `hpm_metapac::clocks::`
- All GPIOs and it's PADs, for `IOC`, in `hpm_metapac::pins::`
- All IOMUX settings (`FUNC_CTL`) in `hpm_metapac::iomux::`

## Data Source

Expand Down
120 changes: 120 additions & 0 deletions hpm-data-gen/src/iomux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//! parse iomux definitions from sdk_code
use std::path::{Path, PathBuf};

pub fn add_iomux_from_sdk<P: AsRef<Path>>(
data_dir: P,
chip: &mut hpm_data_serde::Chip,
) -> anyhow::Result<()> {
let sdk_path = std::env::var("HPM_SDK_BASE")
.map(PathBuf::from)
.unwrap_or_else(|_| data_dir.as_ref().parent().unwrap().join("hpm_sdk"));

let chip_name = &chip.name;

let mut all_iomux: Vec<hpm_data_serde::chip::core::IoMux> = vec![];

let chip_inc_path = match chip_name {
n if n.starts_with("HPM5301") => sdk_path.join("soc/HPM5300/HPM5301/"),
n if n.starts_with("HPM53") => sdk_path.join("soc/HPM5300/HPM5361/"),
n if n.starts_with("HPM62") => sdk_path.join("soc/HPM6200/HPM6280/"),
n if n.starts_with("HPM63") => sdk_path.join("soc/HPM6300/HPM6360/"),
n if n.starts_with("HPM67") || n.starts_with("HPM64") => {
sdk_path.join("soc/HPM6700/HPM6750/")
}
n if n.starts_with("HPM68") => sdk_path.join("soc/HPM6800/HPM6880/"),
n if n.starts_with("HPM6E") => sdk_path.join("soc/HPM6E00/HPM6E80/"),
_ => anyhow::bail!("Unknown chip: {}", chip_name),
};

let iomux_path = chip_inc_path.join("hpm_iomux.h");

let content = std::fs::read_to_string(&iomux_path)
.expect(format!("Failed to read file: {:?}", &iomux_path).as_str());

// #define IOC_PA16_FUNC_CTL_MCAN4_TXD IOC_PAD_FUNC_CTL_ALT_SELECT_SET(7)
let iomux_pattern = regex::Regex::new(
r"#define\s+(IOC_(\w+)_FUNC_CTL_(\w+))\s+IOC_PAD_FUNC_CTL_ALT_SELECT_SET\((\d+)\)",
)
.expect("Invalid regex");

for mux in iomux_pattern.captures_iter(&content).map(|cap| {
(
cap.get(1).unwrap().as_str().to_string(),
cap.get(4).unwrap().as_str().parse().unwrap(),
)
}) {
all_iomux.push(hpm_data_serde::chip::core::IoMux {
name: mux.0,
value: mux.1,
});
}

// PMIC domain

let pmic_iomux = chip_inc_path.join("hpm_pmic_iomux.h");

let content = std::fs::read_to_string(&pmic_iomux)
.expect(format!("Failed to read file: {:?}", &pmic_iomux).as_str());

// #define PIOC_PY01_FUNC_CTL_PGPIO_Y_01 IOC_PAD_FUNC_CTL_ALT_SELECT_SET(0)
let pmic_iomux_pattern = regex::Regex::new(
r"#define\s+(PIOC_(\w+)_FUNC_CTL_(\w+))\s+IOC_PAD_FUNC_CTL_ALT_SELECT_SET\((\d+)\)",
)
.expect("Invalid regex");

for mux in pmic_iomux_pattern.captures_iter(&content).map(|cap| {
(
cap.get(1).unwrap().as_str().to_string(),
cap.get(4).unwrap().as_str().parse().unwrap(),
)
}) {
all_iomux.push(hpm_data_serde::chip::core::IoMux {
name: mux.0,
value: mux.1,
});
}

// BATT domain

let batt_iomux = chip_inc_path.join("hpm_batt_iomux.h");

if batt_iomux.exists() {
let content = std::fs::read_to_string(&batt_iomux)
.expect(format!("Failed to read file: {:?}", &batt_iomux).as_str());

// #define BIOC_PZ00_FUNC_CTL_BGPIO_Z_00 IOC_PAD_FUNC_CTL_ALT_SELECT_SET(0)
let batt_iomux_pattern = regex::Regex::new(
r"#define\s+(BIOC_(\w+)_FUNC_CTL_(\w+))\s+IOC_PAD_FUNC_CTL_ALT_SELECT_SET\((\d+)\)",
)
.expect("Invalid regex");

for mux in batt_iomux_pattern
.captures_iter(&content)
.map(|cap| {
(
cap.get(1).unwrap().as_str().to_string(),
cap.get(4).unwrap().as_str().parse().unwrap(),
)
})
.filter(|(name, _)| !name.contains("_GPIO"))
{
// filter out old style GPIO

all_iomux.push(hpm_data_serde::chip::core::IoMux {
name: mux.0,
value: mux.1,
});
}
}

all_iomux.sort_by_key(|p| p.name.to_string());

all_iomux.dedup();

println!(" {} load iomux {:#?}", chip_name, all_iomux.len());

chip.cores[0].iomuxes = all_iomux;

Ok(())
}
8 changes: 7 additions & 1 deletion hpm-data-gen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{collections::HashMap, path::Path};

mod dma;
mod interrupts;
mod iomux;
mod pinmux;
mod pins;
mod registers;
Expand Down Expand Up @@ -196,6 +197,11 @@ fn main() -> anyhow::Result<()> {
sysctl::add_sysctl_from_sdk(data_dir, chip)?;
}

stopwatch.section("Handle iomux");
for chip in &mut chips {
iomux::add_iomux_from_sdk(data_dir, chip)?;
}

stopwatch.section("Handle IOC pins");
for chip in &mut chips {
pins::add_ioc_pins_from_sdk(data_dir, chip)?;
Expand All @@ -204,7 +210,7 @@ fn main() -> anyhow::Result<()> {
stopwatch.section("Writing chip data");
for chip in &chips {
println!(
"chip: {}, peripherals: {}",
" chip: {}, peripherals: {}",
chip.name,
chip.cores[0].peripherals.len()
);
Expand Down
9 changes: 9 additions & 0 deletions hpm-data-serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ pub mod chip {
pub clocks: Vec<core::Clock>,
#[serde(default)]
pub pins: Vec<core::IoPin>,
#[serde(default)]
pub iomuxes: Vec<core::IoMux>,

// include fields, for common peripherals
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -263,6 +265,13 @@ pub mod chip {
// IOC pad index
pub index: usize,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct IoMux {
pub name: String,
// alt func value
pub value: u8,
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions hpm-metapac-gen/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ pub struct Core {
pub clocks: Vec<Clock>,
#[serde(default)]
pub pins: Vec<IoPin>,
#[serde(default)]
pub iomuxes: Vec<IoMux>,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
Expand All @@ -364,6 +366,12 @@ pub struct IoPin {
pub index: u32,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
pub struct IoMux {
pub name: String,
pub value: u32,
}

#[derive(Debug, Eq, PartialEq, Clone, Deserialize)]
pub struct Interrupt {
pub name: String,
Expand Down
29 changes: 20 additions & 9 deletions hpm-metapac-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,6 @@ impl Gen {

ir.devices.insert("".to_string(), dev);

/*
let mut extra = format!(
"pub fn GPIO(n: usize) -> gpio::Gpio {{
unsafe {{ gpio::Gpio::from_ptr(({} + {}*n) as _) }}
}}",
gpio_base, gpio_stride,
);
*/
let mut extra = format!("");

for (module, version) in &peripheral_versions {
Expand Down Expand Up @@ -147,7 +139,9 @@ impl Gen {
// ==============================
// Generate Register Block indices
{
// All SYSCTL resources
writeln!(&mut extra, "pub mod resources {{").unwrap();
writeln!(&mut extra, " //! `SYSCTL.RESOURCE` definitions").unwrap();
for res in &core.resources {
writeln!(
&mut extra,
Expand All @@ -159,8 +153,9 @@ impl Gen {
}
writeln!(&mut extra, "}}").unwrap();

// All clocks
writeln!(&mut extra, "pub mod clocks {{").unwrap();

writeln!(&mut extra, " //! `SYSCTL.CLOCK` definitions").unwrap();
for clk in &core.clocks {
writeln!(
&mut extra,
Expand All @@ -172,7 +167,9 @@ impl Gen {
}
writeln!(&mut extra, "}}").unwrap();

// All pin pads
writeln!(&mut extra, "pub mod pins {{").unwrap();
writeln!(&mut extra, " //! Pin pad definitions").unwrap();
for pin in &core.pins {
writeln!(
&mut extra,
Expand All @@ -183,6 +180,20 @@ impl Gen {
.unwrap();
}
writeln!(&mut extra, "}}").unwrap();

// All iomux consts
writeln!(&mut extra, "pub mod iomux {{").unwrap();
writeln!(&mut extra, " //! `FUNC_CTL` function mux definitions").unwrap();
for mux in &core.iomuxes {
writeln!(
&mut extra,
" pub const {}: u8 = {};",
mux.name.to_ascii_uppercase(),
mux.value
)
.unwrap();
}
writeln!(&mut extra, "}}").unwrap();
}

// Cleanups!
Expand Down

0 comments on commit bde2bb2

Please sign in to comment.