finish auto-generation effort
Some checks failed
ci / Check build (push) Has been cancelled
ci / Check formatting (push) Has been cancelled
ci / Check Documentation Build (push) Has been cancelled
ci / Clippy (push) Has been cancelled
ci / Check build (pull_request) Has been cancelled
ci / Check formatting (pull_request) Has been cancelled
ci / Check Documentation Build (pull_request) Has been cancelled
ci / Clippy (pull_request) Has been cancelled

This commit is contained in:
Robin Mueller
2025-10-08 19:01:15 +02:00
parent 209fc9532e
commit bd143ba51d
17 changed files with 759 additions and 575 deletions

304
tools/Cargo.lock generated
View File

@@ -47,7 +47,7 @@ version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
dependencies = [
"windows-sys",
"windows-sys 0.60.2",
]
[[package]]
@@ -58,7 +58,7 @@ checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys",
"windows-sys 0.60.2",
]
[[package]]
@@ -145,6 +145,16 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "colored"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
dependencies = [
"lazy_static",
"windows-sys 0.59.0",
]
[[package]]
name = "cortex-ar"
version = "0.3.0"
@@ -164,6 +174,15 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "deranged"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071"
dependencies = [
"powerfmt",
]
[[package]]
name = "derive-mmio"
version = "0.6.1"
@@ -198,6 +217,30 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.176"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
[[package]]
name = "log"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "memchr"
version = "2.7.6"
@@ -212,6 +255,12 @@ dependencies = [
"zynq7000-rt",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num_enum"
version = "0.7.4"
@@ -233,6 +282,15 @@ dependencies = [
"syn",
]
[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
"libc",
]
[[package]]
name = "once_cell"
version = "1.21.3"
@@ -255,6 +313,12 @@ version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
@@ -330,6 +394,47 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "simple_logger"
version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8c5dfa5e08767553704aa0ffd9d9794d527103c736aba9854773851fd7497eb"
dependencies = [
"colored",
"log",
"time",
"windows-sys 0.48.0",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
@@ -373,6 +478,39 @@ dependencies = [
"syn",
]
[[package]]
name = "time"
version = "0.3.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
dependencies = [
"deranged",
"itoa",
"libc",
"num-conv",
"num_threads",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
[[package]]
name = "time-macros"
version = "0.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "unicode-ident"
version = "1.0.19"
@@ -391,13 +529,62 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets",
"windows-targets 0.53.5",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
@@ -407,58 +594,148 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
@@ -500,7 +777,12 @@ name = "zynq7000-ps7init-extract"
version = "0.1.0"
dependencies = [
"clap",
"log",
"proc-macro2",
"quote",
"regex",
"simple_logger",
"syn",
"zynq7000",
]

View File

@@ -0,0 +1,2 @@
/ddrc_config_autogen.rs
/ddriob_config_autogen.rs

View File

@@ -6,4 +6,9 @@ edition = "2024"
[dependencies]
clap = { version = "4", features = ["derive"] }
zynq7000 = { path = "../../zynq/zynq7000" }
log = "0.4"
simple_logger = "5"
regex = "1"
quote = "1"
syn = "2"
proc-macro2 = "1"

View File

@@ -0,0 +1,26 @@
Zynq7000 PS7 Init Extractor
=========
AMD provides tooling to auto-generate some of the hardware initialization for the external DDR
as native Rust code.
The AMD tooling generates these files as `ps7init.tcl`, `ps7init.c`, `ps7init.h` files but not as
Rust files. The specific parameters required for different DDR chips are proprietary, so that
portion is required for Rust programs as well. Do avoid the need of compiling the PS7 initialization
scripts with a C compiler, this tool extracts all required configuration parameters for DDR and
DDRIOB initialization and configuration and exports them as native Rust constants.
The generates files can be placed in individual projects or board support packages to initialize
the DDR in conjunction with the [Zynq7000 HAL library](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/fsbl-rs/zynq/zynq7000-hal).
Right now, the script expects the `ps7init.tcl` file to be passed as a command line argument
for `-p` or `--path`. It then generates the configuration as a `ddrc_config_autogen.rs` and
`ddrc_config_autogen.rs` file.
For example, assuming that there is a `ps7init.tcl` script in the current directory, you can use
```sh
cargo run -- --path ./ps7init.tcl
```
to generate the configuration files.

View File

@@ -1,12 +1,13 @@
use std::{
fs::File,
io::{BufRead, BufWriter},
path::Path,
};
use std::{collections::HashMap, ops::RangeInclusive, path::Path};
use clap::Parser as _;
use std::io::Write as _;
use zynq7000::ddrc::regs;
use simple_logger::SimpleLogger;
const DDRC_ADDR_RANGE: RangeInclusive<u32> = 0xf800_6000..=0xf800_62b4;
const DDRIOB_ADDR_RANGE: RangeInclusive<u32> = 0xf800_0b40..=0xf800_0b68;
const DDRC_FILE_NAME: &str = "ddrc_config_autogen.rs";
const DDRIOB_FILE_NAME: &str = "ddriob_config_autogen.rs";
#[derive(clap::Parser, Debug)]
#[command(version, about)]
@@ -31,63 +32,310 @@ fn extract_hex_values(line: &str) -> Option<(u32, u32, u32)> {
}
}
#[derive(Default)]
pub struct RegisterToValueMap(pub HashMap<u32, u32>);
impl RegisterToValueMap {
fn val_as_token(&self, reg_name: &str, addr: u32) -> proc_macro2::TokenStream {
let val = self.0.get(&addr).unwrap_or_else(|| {
panic!(
"failed to retrieve register value for register {}",
reg_name
)
});
format!("{:#010x}", val)
.parse::<proc_macro2::TokenStream>()
.unwrap()
}
}
enum ParsingMode {
DdrRev3,
MioRev3,
}
fn main() -> std::io::Result<()> {
SimpleLogger::new().init().unwrap();
let cli = Cli::parse();
let ps7init_tcl = Path::new(&cli.path);
if !ps7init_tcl.exists() {
eprintln!("File not found: {}", ps7init_tcl.display());
log::error!("File not found: {}", ps7init_tcl.display());
std::process::exit(1);
}
let mut ddrc_config = None;
let mut two_rank_config = None;
let mut hpr_config = None;
for maybe_line in std::fs::read(ps7init_tcl).unwrap().lines() {
if let Ok(line) = maybe_line
&& let Some((addr, _mask, value)) = extract_hex_values(&line)
let mut parsing_mode = None;
let mut reg_to_values = RegisterToValueMap::default();
for line in std::fs::read_to_string(ps7init_tcl)?.lines() {
match parsing_mode {
None => {
if line.contains("ps7_ddr_init_data_3_0") {
parsing_mode = Some(ParsingMode::DdrRev3);
} else if line.contains("ps7_mio_init_data_3_0") {
parsing_mode = Some(ParsingMode::MioRev3);
}
continue;
}
Some(ParsingMode::MioRev3) => {
if line.contains("}") {
parsing_mode = None;
continue;
}
}
Some(ParsingMode::DdrRev3) => {
if line.contains("}") {
parsing_mode = None;
continue;
}
}
}
if let Some((addr, _mask, value)) = extract_hex_values(line)
&& (DDRC_ADDR_RANGE.contains(&addr) || DDRIOB_ADDR_RANGE.contains(&addr))
&& addr % 4 == 0
{
match addr {
0xf800_6000 => ddrc_config = Some(regs::DdrcControl::new_with_raw_value(value)),
0xf800_6004 => {
two_rank_config = Some(regs::TwoRankConfig::new_with_raw_value(value))
// Only use first value.
if reg_to_values.0.contains_key(&addr) {
if addr != 0xF800_6000 {
log::warn!("detected duplicate register value for address {}", addr);
}
0xf800_6008 => {
hpr_config = Some(regs::LprHprQueueControl::new_with_raw_value(value))
}
_ => (),
continue;
}
reg_to_values.0.insert(addr, value);
}
}
let file_path = "ddr_config.rs";
let file = File::create(file_path).expect("Failed to create file");
let mut writer = BufWriter::new(file);
writeln!(
writer,
"//! This file was auto-generated by the zynq7000-ps7init-extract program"
)?;
writeln!(writer, "//!")?;
writeln!(
writer,
"//! This configuration file contains static DDR configuration parameters extracted from the AMD ps7init.tcl file"
)?;
writeln!(writer, "use zynq7000::ddrc::regs;")?;
log::info!("generating DDRC config files: {}", DDRC_FILE_NAME);
generate_ddrc_config(&reg_to_values, DDRC_FILE_NAME)?;
log::info!("generating DDRIOB config files: {}", DDRIOB_FILE_NAME);
generate_ddriob_config(&reg_to_values, DDRIOB_FILE_NAME)?;
writeln!(
writer,
"pub const DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS: DdrcConfigSet = DdrcConfigSet {{"
)?;
writeln!(
writer,
" ctrl: regs::DdrcControl::new_with_raw_value({:#08x})",
ddrc_config.expect("DDR control unknown").raw_value()
)?;
writeln!(
writer,
" ctrl: regs::TwoRankConfig::new_with_raw_value({:#08x})",
two_rank_config
.expect("two rank config unknown")
.raw_value()
)?;
writeln!(writer, "}}")?;
Ok(())
}
fn generate_ddrc_config(
reg_to_values: &RegisterToValueMap,
file_name: &str,
) -> std::io::Result<()> {
// Format as hex strings
let ddrc = reg_to_values.val_as_token("DDRC Control", 0xF800_6000);
let two_rank = reg_to_values.val_as_token("Two Rank", 0xF800_6004);
let hpr = reg_to_values.val_as_token("HPR", 0xF800_6008);
let lpr = reg_to_values.val_as_token("LPR", 0xF800_600C);
let wr = reg_to_values.val_as_token("WR", 0xF800_6010);
let dram_param_0 = reg_to_values.val_as_token("DRAM Reg0", 0xF800_6014);
let dram_param_1 = reg_to_values.val_as_token("DRAM Reg1", 0xF800_6018);
let dram_param_2 = reg_to_values.val_as_token("DRAM Reg2", 0xF800_601C);
let dram_param_3 = reg_to_values.val_as_token("DRAM Reg3", 0xF800_6020);
let dram_param_4 = reg_to_values.val_as_token("DRAM Reg4", 0xF800_6024);
let dram_init_param = reg_to_values.val_as_token("DRAM Init Param", 0xF800_6028);
let dram_emr = reg_to_values.val_as_token("DRAM EMR", 0xF800_602C);
let dram_emr_mr = reg_to_values.val_as_token("DRAM EMR MR", 0xF800_6030);
let dram_burst8_rdwr = reg_to_values.val_as_token("DRAM Burst8 RDWR", 0xF800_6034);
let dram_disable_dq = reg_to_values.val_as_token("DRAM Disable DQ", 0xF800_6038);
let dram_addr_map_bank = reg_to_values.val_as_token("DRAM Addr Map Bank", 0xF800_603C);
let dram_addr_map_col = reg_to_values.val_as_token("DRAM Addr Map Col", 0xF800_6040);
let dram_addr_map_row = reg_to_values.val_as_token("DRAM Addr Map Row", 0xF800_6044);
let dram_odt = reg_to_values.val_as_token("DRAM ODT", 0xF800_6048);
let phy_cmd_timeout_rddata_cpt = reg_to_values.val_as_token("PHY CMD Timeout", 0xF800_6050);
let dll_calib = reg_to_values.val_as_token("DLL Calib", 0xF800_6058);
let odt_delay_hold = reg_to_values.val_as_token("ODT Delay Hold", 0xF800_605C);
let ctrl_reg1 = reg_to_values.val_as_token("CTRL Reg 1", 0xF800_6060);
let ctrl_reg2 = reg_to_values.val_as_token("CTRL Reg 2", 0xF800_6064);
let ctrl_reg3 = reg_to_values.val_as_token("CTRL Reg 3", 0xF800_6068);
let ctrl_reg4 = reg_to_values.val_as_token("CTRL Reg 4", 0xF800_606C);
let ctrl_reg5 = reg_to_values.val_as_token("CTRL Reg 5", 0xF800_6078);
let ctrl_reg6 = reg_to_values.val_as_token("CTRL Reg 6", 0xF800_607C);
let che_t_zq = reg_to_values.val_as_token("CHE T ZQ", 0xF800_60A4);
let che_t_zq_short_interval_reg =
reg_to_values.val_as_token("CHE T ZQ Short Interval", 0xF800_60A4);
let deep_powerdown = reg_to_values.val_as_token("Deep Powerdown", 0xF800_60AC);
let reg_2c = reg_to_values.val_as_token("Reg 2C", 0xF800_60B0);
let reg_2d = reg_to_values.val_as_token("Reg 2D", 0xF800_60B4);
let dfi_timing = reg_to_values.val_as_token("DFI Timing", 0xF800_60B8);
let che_ecc_ctrl = reg_to_values.val_as_token("CHE ECC CTRL", 0xF800_60C4);
let ecc_scrub = reg_to_values.val_as_token("ECC Scrub", 0xF800_60F4);
let phy_receiver_enable = reg_to_values.val_as_token("PHY Receiver Enable", 0xF800_6114);
let phy_config_0 = reg_to_values.val_as_token("PHY Config 0", 0xF800_6118);
let phy_config_1 = reg_to_values.val_as_token("PHY Config 1", 0xF800_611C);
let phy_config_2 = reg_to_values.val_as_token("PHY Config 2", 0xF800_6120);
let phy_config_3 = reg_to_values.val_as_token("PHY Config 3", 0xF800_6124);
let phy_init_ratio_0 = reg_to_values.val_as_token("PHY Init Ratio 0", 0xF800_612C);
let phy_init_ratio_1 = reg_to_values.val_as_token("PHY Init Ratio 1", 0xF800_6130);
let phy_init_ratio_2 = reg_to_values.val_as_token("PHY Init Ratio 2", 0xF800_6134);
let phy_init_ratio_3 = reg_to_values.val_as_token("PHY Init Ratio 3", 0xF800_6138);
let phy_rd_dqs_config_0 = reg_to_values.val_as_token("PHY RD DQS Config 0", 0xF800_6140);
let phy_rd_dqs_config_1 = reg_to_values.val_as_token("PHY RD DQS Config 1", 0xF800_6144);
let phy_rd_dqs_config_2 = reg_to_values.val_as_token("PHY RD DQS Config 2", 0xF800_6148);
let phy_rd_dqs_config_3 = reg_to_values.val_as_token("PHY RD DQS Config 3", 0xF800_614C);
let phy_wr_dqs_config_0 = reg_to_values.val_as_token("PHY WR DQS Config 0", 0xF800_6154);
let phy_wr_dqs_config_1 = reg_to_values.val_as_token("PHY WR DQS Config 1", 0xF800_6158);
let phy_wr_dqs_config_2 = reg_to_values.val_as_token("PHY WR DQS Config 2", 0xF800_615C);
let phy_wr_dqs_config_3 = reg_to_values.val_as_token("PHY WR DQS Config 3", 0xF800_6160);
let phy_we_cfg_0 = reg_to_values.val_as_token("PHY WE Config 0", 0xF800_6168);
let phy_we_cfg_1 = reg_to_values.val_as_token("PHY WE Config 1", 0xF800_616C);
let phy_we_cfg_2 = reg_to_values.val_as_token("PHY WE Config 2", 0xF800_6170);
let phy_we_cfg_3 = reg_to_values.val_as_token("PHY WE Config 3", 0xF800_6174);
let phy_wr_data_slv_0 = reg_to_values.val_as_token("PHY WR Data Slv 0", 0xF800_617C);
let phy_wr_data_slv_1 = reg_to_values.val_as_token("PHY WR Data Slv 1", 0xF800_6180);
let phy_wr_data_slv_2 = reg_to_values.val_as_token("PHY WR Data Slv 2", 0xF800_6184);
let phy_wr_data_slv_3 = reg_to_values.val_as_token("PHY WR Data Slv 3", 0xF800_6188);
let reg64 = reg_to_values.val_as_token("Reg64", 0xF800_6190);
let reg65 = reg_to_values.val_as_token("Reg65", 0xF800_6194);
let page_mask = reg_to_values.val_as_token("Page Mask", 0xF800_6204);
let axi_priority_wr_port_0 = reg_to_values.val_as_token("AXI Priority WR Port 0", 0xF800_6208);
let axi_priority_wr_port_1 = reg_to_values.val_as_token("AXI Priority WR Port 1", 0xF800_620C);
let axi_priority_wr_port_2 = reg_to_values.val_as_token("AXI Priority WR Port 2", 0xF800_6210);
let axi_priority_wr_port_3 = reg_to_values.val_as_token("AXI Priority WR Port 3", 0xF800_6214);
let axi_priority_rd_port_0 = reg_to_values.val_as_token("AXI Priority RD Port 0", 0xF800_6218);
let axi_priority_rd_port_1 = reg_to_values.val_as_token("AXI Priority RD Port 1", 0xF800_621C);
let axi_priority_rd_port_2 = reg_to_values.val_as_token("AXI Priority RD Port 2", 0xF800_6220);
let axi_priority_rd_port_3 = reg_to_values.val_as_token("AXI Priority RD Port 3", 0xF800_6224);
let lpddr_ctrl_0 = reg_to_values.val_as_token("LPDDR CTRL 0", 0xF800_62A8);
let lpddr_ctrl_1 = reg_to_values.val_as_token("LPDDR CTRL 1", 0xF800_62AC);
let lpddr_ctrl_2 = reg_to_values.val_as_token("LPDDR CTRL 2", 0xF800_62B0);
let lpddr_ctrl_3 = reg_to_values.val_as_token("LPDDR CTRL 3", 0xF800_62B4);
let generated = quote::quote! {
//!This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program.
//!
//!This configuration file contains static DDR configuration parameters extracted from the
//!AMD ps7init.tcl file
use zynq7000::ddrc::regs;
use zynq7000_hal::ddr::DdrcConfigSet;
pub const DDRC_CONFIG_ZEDBOARD: DdrcConfigSet = DdrcConfigSet {
ctrl: regs::DdrcControl::new_with_raw_value(#ddrc),
two_rank: regs::TwoRankConfig::new_with_raw_value(#two_rank),
hpr: regs::LprHprQueueControl::new_with_raw_value(#hpr),
lpr: regs::LprHprQueueControl::new_with_raw_value(#lpr),
wr: regs::WriteQueueControl::new_with_raw_value(#wr),
dram_param_0: regs::DramParamReg0::new_with_raw_value(#dram_param_0),
dram_param_1: regs::DramParamReg1::new_with_raw_value(#dram_param_1),
dram_param_2: regs::DramParamReg2::new_with_raw_value(#dram_param_2),
dram_param_3: regs::DramParamReg3::new_with_raw_value(#dram_param_3),
dram_param_4: regs::DramParamReg4::new_with_raw_value(#dram_param_4),
dram_init_param: regs::DramInitParam::new_with_raw_value(#dram_init_param),
dram_emr: regs::DramEmr::new_with_raw_value(#dram_emr),
dram_emr_mr: regs::DramEmrMr::new_with_raw_value(#dram_emr_mr),
dram_burst8_rdwr: regs::DramBurst8ReadWrite::new_with_raw_value(#dram_burst8_rdwr),
disable_dq: regs::DisableDq::new_with_raw_value(#dram_disable_dq),
dram_addr_map_bank: regs::DramAddrMapBank::new_with_raw_value(#dram_addr_map_bank),
dram_addr_map_col: regs::DramAddrMapColumn::new_with_raw_value(#dram_addr_map_col),
dram_addr_map_row: regs::DramAddrMapRow::new_with_raw_value(#dram_addr_map_row),
dram_odt: regs::DramOdt::new_with_raw_value(#dram_odt),
phy_cmd_timeout_rddata_cpt: regs::PhyCmdTimeoutRdDataCpt::new_with_raw_value(#phy_cmd_timeout_rddata_cpt),
dll_calib: regs::DllCalib::new_with_raw_value(#dll_calib),
odt_delay_hold: regs::OdtDelayHold::new_with_raw_value(#odt_delay_hold),
ctrl_reg1: regs::CtrlReg1::new_with_raw_value(#ctrl_reg1),
ctrl_reg2: regs::CtrlReg2::new_with_raw_value(#ctrl_reg2),
ctrl_reg3: regs::CtrlReg3::new_with_raw_value(#ctrl_reg3),
ctrl_reg4: regs::CtrlReg4::new_with_raw_value(#ctrl_reg4),
ctrl_reg5: regs::CtrlReg5::new_with_raw_value(#ctrl_reg5),
ctrl_reg6: regs::CtrlReg6::new_with_raw_value(#ctrl_reg6),
che_t_zq: regs::CheTZq::new_with_raw_value(#che_t_zq),
che_t_zq_short_interval_reg: regs::CheTZqShortInterval::new_with_raw_value(#che_t_zq_short_interval_reg),
deep_powerdown: regs::DeepPowerdown::new_with_raw_value(#deep_powerdown),
reg_2c: regs::Reg2c::new_with_raw_value(#reg_2c),
reg_2d: regs::Reg2d::new_with_raw_value(#reg_2d),
dfi_timing: regs::DfiTiming::new_with_raw_value(#dfi_timing),
che_ecc_ctrl: regs::CheEccControl::new_with_raw_value(#che_ecc_ctrl),
ecc_scrub: regs::EccScrub::new_with_raw_value(#ecc_scrub),
phy_receiver_enable: regs::PhyReceiverEnable::new_with_raw_value(#phy_receiver_enable),
phy_config: [
regs::PhyConfig::new_with_raw_value(#phy_config_0),
regs::PhyConfig::new_with_raw_value(#phy_config_1),
regs::PhyConfig::new_with_raw_value(#phy_config_2),
regs::PhyConfig::new_with_raw_value(#phy_config_3),
],
phy_init_ratio: [
regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_0),
regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_1),
regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_2),
regs::PhyInitRatio::new_with_raw_value(#phy_init_ratio_3),
],
phy_rd_dqs_config: [
regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_0),
regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_1),
regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_2),
regs::PhyDqsConfig::new_with_raw_value(#phy_rd_dqs_config_3),
],
phy_wr_dqs_config: [
regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_0),
regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_1),
regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_2),
regs::PhyDqsConfig::new_with_raw_value(#phy_wr_dqs_config_3),
],
phy_we_cfg: [
regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_0),
regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_1),
regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_2),
regs::PhyWriteEnableConfig::new_with_raw_value(#phy_we_cfg_3),
],
phy_wr_data_slv: [
regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_0),
regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_1),
regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_2),
regs::PhyWriteDataSlaveConfig::new_with_raw_value(#phy_wr_data_slv_3),
],
reg64: regs::Reg64::new_with_raw_value(#reg64),
reg65: regs::Reg65::new_with_raw_value(#reg65),
page_mask: #page_mask,
axi_priority_wr_port: [
regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_0),
regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_1),
regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_2),
regs::AxiPriorityWritePort::new_with_raw_value(#axi_priority_wr_port_3),
],
axi_priority_rd_port: [
regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_0),
regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_1),
regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_2),
regs::AxiPriorityReadPort::new_with_raw_value(#axi_priority_rd_port_3),
],
lpddr_ctrl_0: regs::LpddrControl0::new_with_raw_value(#lpddr_ctrl_0),
lpddr_ctrl_1: regs::LpddrControl1::new_with_raw_value(#lpddr_ctrl_1),
lpddr_ctrl_2: regs::LpddrControl2::new_with_raw_value(#lpddr_ctrl_2),
lpddr_ctrl_3: regs::LpddrControl3::new_with_raw_value(#lpddr_ctrl_3),
};
};
std::fs::write(file_name, generated.to_string())?;
Ok(())
}
fn generate_ddriob_config(
reg_to_values: &RegisterToValueMap,
file_name: &str,
) -> std::io::Result<()> {
// Format as hex strings
let addr0 = reg_to_values.val_as_token("DDRIOB Addr 0", 0xF800_0B40);
let addr1 = reg_to_values.val_as_token("DDRIOB Addr 1", 0xF800_0B44);
let data0 = reg_to_values.val_as_token("DDRIOB Data 0", 0xF800_0B48);
let data1 = reg_to_values.val_as_token("DDRIOB Data 1", 0xF800_0B4C);
let diff0 = reg_to_values.val_as_token("DDRIOB Diff 0", 0xF800_0B50);
let diff1 = reg_to_values.val_as_token("DDRIOB Diff 1", 0xF800_0B54);
let clock = reg_to_values.val_as_token("DDRIOB Clock", 0xF800_0B58);
let generated = quote::quote! {
//!This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program.
//!
//!This configuration file contains static DDRIOB configuration parameters extracted from the
//!AMD ps7init.tcl file
use zynq7000::ddrc::regs;
use zynq7000_hal::ddr::DdriobConfigSet;
pub const DDRIOB_CONFIG_SET_ZEDBOARD: DdriobConfigSet = DdriobConfigSet {
addr0: regs::DdriobConfig::new_with_raw_value(#addr0),
addr1: regs::DdriobConfig::new_with_raw_value(#addr1),
data0: regs::DdriobConfig::new_with_raw_value(#data0),
data1: regs::DdriobConfig::new_with_raw_value(#data1),
diff0: regs::DdriobConfig::new_with_raw_value(#diff0),
diff1: regs::DdriobConfig::new_with_raw_value(#diff1),
clock: regs::DdriobConfig::new_with_raw_value(#clock),
};
};
std::fs::write(file_name, generated.to_string())?;
Ok(())
}

View File

@@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
zynq7000 = { path = "../zynq7000" }
zynq7000-hal = { path = "../zynq7000-hal" }
bitbybit = "1.4"
arbitrary-int = "2"

View File

@@ -0,0 +1,101 @@
#![doc = r"This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program."]
#![doc = r""]
#![doc = r"This configuration file contains static DDR configuration parameters extracted from the"]
#![doc = r"AMD ps7init.tcl file"]
use zynq7000::ddrc::regs;
use zynq7000_hal::ddr::DdrcConfigSet;
pub const DDRC_CONFIG_ZEDBOARD: DdrcConfigSet = DdrcConfigSet {
ctrl: regs::DdrcControl::new_with_raw_value(0x00000080),
two_rank: regs::TwoRankConfig::new_with_raw_value(0x00001082),
hpr: regs::LprHprQueueControl::new_with_raw_value(0x03c0780f),
lpr: regs::LprHprQueueControl::new_with_raw_value(0x02001001),
wr: regs::WriteQueueControl::new_with_raw_value(0x00014001),
dram_param_0: regs::DramParamReg0::new_with_raw_value(0x0004159b),
dram_param_1: regs::DramParamReg1::new_with_raw_value(0x44e458d3),
dram_param_2: regs::DramParamReg2::new_with_raw_value(0x7282bce5),
dram_param_3: regs::DramParamReg3::new_with_raw_value(0x270872d0),
dram_param_4: regs::DramParamReg4::new_with_raw_value(0x00000000),
dram_init_param: regs::DramInitParam::new_with_raw_value(0x00002007),
dram_emr: regs::DramEmr::new_with_raw_value(0x00000008),
dram_emr_mr: regs::DramEmrMr::new_with_raw_value(0x00040b30),
dram_burst8_rdwr: regs::DramBurst8ReadWrite::new_with_raw_value(0x000116d4),
disable_dq: regs::DisableDq::new_with_raw_value(0x00000000),
dram_addr_map_bank: regs::DramAddrMapBank::new_with_raw_value(0x00000777),
dram_addr_map_col: regs::DramAddrMapColumn::new_with_raw_value(0xfff00000),
dram_addr_map_row: regs::DramAddrMapRow::new_with_raw_value(0x0ff66666),
dram_odt: regs::DramOdt::new_with_raw_value(0x0003c008),
phy_cmd_timeout_rddata_cpt: regs::PhyCmdTimeoutRdDataCpt::new_with_raw_value(0x77010800),
dll_calib: regs::DllCalib::new_with_raw_value(0x00000000),
odt_delay_hold: regs::OdtDelayHold::new_with_raw_value(0x00005003),
ctrl_reg1: regs::CtrlReg1::new_with_raw_value(0x0000003e),
ctrl_reg2: regs::CtrlReg2::new_with_raw_value(0x00020000),
ctrl_reg3: regs::CtrlReg3::new_with_raw_value(0x00284141),
ctrl_reg4: regs::CtrlReg4::new_with_raw_value(0x00001610),
ctrl_reg5: regs::CtrlReg5::new_with_raw_value(0x00466111),
ctrl_reg6: regs::CtrlReg6::new_with_raw_value(0x00032222),
che_t_zq: regs::CheTZq::new_with_raw_value(0x10200802),
che_t_zq_short_interval_reg: regs::CheTZqShortInterval::new_with_raw_value(0x10200802),
deep_powerdown: regs::DeepPowerdown::new_with_raw_value(0x000001fe),
reg_2c: regs::Reg2c::new_with_raw_value(0x1cffffff),
reg_2d: regs::Reg2d::new_with_raw_value(0x00000200),
dfi_timing: regs::DfiTiming::new_with_raw_value(0x00200066),
che_ecc_ctrl: regs::CheEccControl::new_with_raw_value(0x00000000),
ecc_scrub: regs::EccScrub::new_with_raw_value(0x00000008),
phy_receiver_enable: regs::PhyReceiverEnable::new_with_raw_value(0x00000000),
phy_config: [
regs::PhyConfig::new_with_raw_value(0x40000001),
regs::PhyConfig::new_with_raw_value(0x40000001),
regs::PhyConfig::new_with_raw_value(0x40000001),
regs::PhyConfig::new_with_raw_value(0x40000001),
],
phy_init_ratio: [
regs::PhyInitRatio::new_with_raw_value(0x00033c03),
regs::PhyInitRatio::new_with_raw_value(0x00034003),
regs::PhyInitRatio::new_with_raw_value(0x0002f400),
regs::PhyInitRatio::new_with_raw_value(0x00030400),
],
phy_rd_dqs_config: [
regs::PhyDqsConfig::new_with_raw_value(0x00000035),
regs::PhyDqsConfig::new_with_raw_value(0x00000035),
regs::PhyDqsConfig::new_with_raw_value(0x00000035),
regs::PhyDqsConfig::new_with_raw_value(0x00000035),
],
phy_wr_dqs_config: [
regs::PhyDqsConfig::new_with_raw_value(0x00000083),
regs::PhyDqsConfig::new_with_raw_value(0x00000083),
regs::PhyDqsConfig::new_with_raw_value(0x0000007f),
regs::PhyDqsConfig::new_with_raw_value(0x00000078),
],
phy_we_cfg: [
regs::PhyWriteEnableConfig::new_with_raw_value(0x00000124),
regs::PhyWriteEnableConfig::new_with_raw_value(0x00000125),
regs::PhyWriteEnableConfig::new_with_raw_value(0x00000112),
regs::PhyWriteEnableConfig::new_with_raw_value(0x00000116),
],
phy_wr_data_slv: [
regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000c3),
regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000c3),
regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000bf),
regs::PhyWriteDataSlaveConfig::new_with_raw_value(0x000000b8),
],
reg64: regs::Reg64::new_with_raw_value(0x00040080),
reg65: regs::Reg65::new_with_raw_value(0x0001fc82),
page_mask: 0x00000000,
axi_priority_wr_port: [
regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff),
regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff),
regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff),
regs::AxiPriorityWritePort::new_with_raw_value(0x000003ff),
],
axi_priority_rd_port: [
regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff),
regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff),
regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff),
regs::AxiPriorityReadPort::new_with_raw_value(0x000003ff),
],
lpddr_ctrl_0: regs::LpddrControl0::new_with_raw_value(0x00000000),
lpddr_ctrl_1: regs::LpddrControl1::new_with_raw_value(0x00000000),
lpddr_ctrl_2: regs::LpddrControl2::new_with_raw_value(0x00005125),
lpddr_ctrl_3: regs::LpddrControl3::new_with_raw_value(0x000012a8),
};

View File

@@ -0,0 +1,16 @@
#![doc = r"This file was auto-generated by the [zynq7000-ps7init-extract](https://egit.irs.uni-stuttgart.de/rust/zynq7000-rs/src/branch/main/tools/zynq7000-ps7init-extract) program."]
#![doc = r""]
#![doc = r"This configuration file contains static DDRIOB configuration parameters extracted from the"]
#![doc = r"AMD ps7init.tcl file"]
use zynq7000::ddrc::regs;
use zynq7000_hal::ddr::DdriobConfigSet;
pub const DDRIOB_CONFIG_SET_ZEDBOARD: DdriobConfigSet = DdriobConfigSet {
addr0: regs::DdriobConfig::new_with_raw_value(0x00000600),
addr1: regs::DdriobConfig::new_with_raw_value(0x00000600),
data0: regs::DdriobConfig::new_with_raw_value(0x00000672),
data1: regs::DdriobConfig::new_with_raw_value(0x00000672),
diff0: regs::DdriobConfig::new_with_raw_value(0x00000674),
diff1: regs::DdriobConfig::new_with_raw_value(0x00000674),
clock: regs::DdriobConfig::new_with_raw_value(0x00000600),
};

View File

@@ -1,4 +1,6 @@
#![no_std]
pub mod ddrc_config_autogen;
pub mod ddriob_config_autogen;
pub mod phy_marvell;
pub mod qspi_spansion;

View File

@@ -1,503 +0,0 @@
use arbitrary_int::{u2, u3, u4, u5, u6, u7, u9, u10, u11, u12, u20};
use zynq7000::{
ddrc::regs::{
AxiPriorityReadPort, AxiPriorityWritePort, CheEccControl, CheTZq, CheTZqShortInterval,
CtrlReg1, CtrlReg2, CtrlReg3, CtrlReg4, CtrlReg5, CtrlReg6, DataBusWidth, DdrcControl,
DeepPowerdown, DfiTiming, DisableDq, DllCalib, DllCalibSel, DramAddrMapBank,
DramAddrMapColumn, DramAddrMapRow, DramBurst8ReadWrite, DramEmr, DramEmrMr, DramInitParam,
DramOdt, DramParamReg0, DramParamReg1, DramParamReg2, DramParamReg3, DramParamReg4,
EccMode, EccScrub, LpddrBit, LpddrControl0, LpddrControl1, LpddrControl2, LpddrControl3,
LprHprQueueControl, MobileSetting, ModeRegisterType, OdtDelayHold, PhyCmdTimeoutRdDataCpt,
PhyConfig, PhyDqsConfig, PhyInitRatio, PhyReceiverEnable, PhyWriteDataSlaveConfig,
PhyWriteEnableConfig, Reg2c, Reg2d, Reg64, Reg65, SoftReset, TwoRankConfig,
WriteQueueControl,
},
slcr::ddriob::{DciType, DdriobConfig, InputType, OutputEnable},
};
use zynq7000_hal::ddr::{DdrcConfigSet, DdriobConfigSet};
const DDRIOB_ADDR_CFG: DdriobConfig = DdriobConfig::builder()
.with_pullup_enable(false)
.with_output_enable(OutputEnable::OBuf)
.with_term_disable_mode(false)
.with_ibuf_disable_mode(false)
.with_dci_type(DciType::Disabled)
.with_termination_enable(false)
.with_dci_update_enable(false)
.with_inp_type(InputType::Off)
.build();
const DDRIOB_DATA_CFG: DdriobConfig = DdriobConfig::builder()
.with_pullup_enable(false)
.with_output_enable(OutputEnable::OBuf)
.with_term_disable_mode(false)
.with_ibuf_disable_mode(false)
.with_dci_type(DciType::DciTermination)
.with_termination_enable(true)
.with_dci_update_enable(false)
.with_inp_type(InputType::VRefBasedDifferentialReceiverForSstlHstl)
.build();
const DDRIOB_DIFF_CFG: DdriobConfig = DdriobConfig::builder()
.with_pullup_enable(false)
.with_output_enable(OutputEnable::OBuf)
.with_term_disable_mode(false)
.with_ibuf_disable_mode(false)
.with_dci_type(DciType::DciTermination)
.with_termination_enable(true)
.with_dci_update_enable(false)
.with_inp_type(InputType::DifferentialInputReceiver)
.build();
const DDRIOB_CLOCK_CFG: DdriobConfig = DdriobConfig::builder()
.with_pullup_enable(false)
.with_output_enable(OutputEnable::OBuf)
.with_term_disable_mode(false)
.with_ibuf_disable_mode(false)
.with_dci_type(DciType::Disabled)
.with_termination_enable(false)
.with_dci_update_enable(false)
.with_inp_type(InputType::Off)
.build();
// TODO: Auto-generate from ps7init.tcl
pub const DDRIOB_CONFIG_SET_ZEDBOARD: DdriobConfigSet = DdriobConfigSet {
addr0: DDRIOB_ADDR_CFG,
addr1: DDRIOB_ADDR_CFG,
data0: DDRIOB_DATA_CFG,
data1: DDRIOB_DATA_CFG,
diff0: DDRIOB_DIFF_CFG,
diff1: DDRIOB_DIFF_CFG,
clock: DDRIOB_CLOCK_CFG,
};
// TODO: Auto-generate from ps7init.tcl
pub const DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS: DdrcConfigSet = DdrcConfigSet {
ctrl: DdrcControl::builder()
.with_disable_auto_refresh(false)
.with_disable_active_bypass(false)
.with_disable_read_bypass(false)
.with_read_write_idle_gap(u7::new(1))
.with_burst8_refresh(u3::new(0))
.with_data_bus_width(DataBusWidth::_32Bit)
.with_power_down_enable(false)
.with_soft_reset(SoftReset::Reset)
.build(),
two_rank: TwoRankConfig::builder()
.with_addrmap_cs_bit0(u5::new(0))
.with_ddrc_active_ranks(u2::new(1))
.with_rfc_nom_x32(u12::new(0x82))
.build(),
hpr: LprHprQueueControl::builder()
.with_xact_run_length(u4::new(0xf))
.with_max_starve_x32(u11::new(0xf))
.with_min_non_critical_x32(u11::new(0xf))
.build(),
lpr: LprHprQueueControl::builder()
.with_xact_run_length(u4::new(0x8))
.with_max_starve_x32(u11::new(0x2))
.with_min_non_critical_x32(u11::new(0x1))
.build(),
wr: WriteQueueControl::builder()
.with_max_starve_x32(u11::new(0x2))
.with_xact_run_length(u4::new(0x8))
.with_min_non_critical_x32(u11::new(0x1))
.build(),
dram_param_0: DramParamReg0::builder()
.with_post_selfref_gap_x32(u7::new(0x10))
.with_t_rfc_min(0x56)
.with_t_rc(u6::new(0x1b))
.build(),
dram_param_1: DramParamReg1::builder()
.with_t_cke(u4::new(0x4))
.with_t_ras_min(u5::new(0x13))
.with_t_ras_max(u6::new(0x24))
.with_t_faw(u6::new(0x16))
.with_powerdown_to_x32(u5::new(0x6))
.with_wr2pre(u5::new(0x13))
.build(),
dram_param_2: DramParamReg2::builder()
.with_t_rcd(u4::new(0x7))
.with_rd2pre(u5::new(0x5))
.with_pad_pd(u3::new(0x0))
.with_t_xp(u5::new(0x5))
.with_wr2rd(u5::new(0xf))
.with_rd2wr(u5::new(0x7))
.with_write_latency(u5::new(0x5))
.build(),
dram_param_3: DramParamReg3::builder()
.with_disable_pad_pd_feature(false)
.with_read_latency(u5::new(0x7))
.with_enable_dfi_dram_clk_disable(false)
.with_mobile(MobileSetting::Ddr2Ddr3)
.with_sdram(false)
.with_refresh_to_x32(u5::new(0x8))
.with_t_rp(u4::new(0x7))
.with_refresh_margin(u4::new(0x2))
.with_t_rrd(u3::new(0x6))
.with_t_ccd(u3::new(0x4))
.build(),
dram_param_4: DramParamReg4::builder()
.with_mr_rdata_valid(false)
.with_mr_type(ModeRegisterType::Write)
.with_mr_wr_busy(false)
.with_mr_data(0x0)
.with_mr_addr(u2::new(0x0))
.with_mr_wr(false)
.with_prefer_write(false)
.with_enable_2t_timing_mode(false)
.build(),
dram_init_param: DramInitParam::builder()
.with_t_mrd(u3::new(0x4))
.with_pre_ocd_x32(u4::new(0x0))
.with_final_wait_x32(u7::new(0x7))
.build(),
dram_emr: DramEmr::builder().with_emr3(0x0).with_emr2(0x8).build(),
dram_emr_mr: DramEmrMr::builder().with_emr(0x4).with_mr(0xb30).build(),
dram_burst8_rdwr: DramBurst8ReadWrite::builder()
.with_burst_rdwr(u4::new(0x4))
.with_pre_cke_x1024(u10::new(0x16d))
.with_post_cke_x1024(u10::new(0x1))
.with_burstchop(false)
.build(),
disable_dq: DisableDq::builder()
.with_dis_dq(false)
.with_force_low_pri_n(false)
.build(),
dram_addr_map_bank: DramAddrMapBank::builder()
.with_addrmap_bank_b6(u4::new(0))
.with_addrmap_bank_b5(u4::new(0))
.with_addrmap_bank_b2(u4::new(0x7))
.with_addrmap_bank_b1(u4::new(0x7))
.with_addrmap_bank_b0(u4::new(0x7))
.build(),
dram_addr_map_col: DramAddrMapColumn::builder()
.with_addrmap_col_b11(u4::new(0xf))
.with_addrmap_col_b10(u4::new(0xf))
.with_addrmap_col_b9(u4::new(0xf))
.with_addrmap_col_b8(u4::new(0x0))
.with_addrmap_col_b7(u4::new(0x0))
.with_addrmap_col_b4(u4::new(0x0))
.with_addrmap_col_b3(u4::new(0x0))
.with_addrmap_col_b2(u4::new(0x0))
.build(),
dram_addr_map_row: DramAddrMapRow::builder()
.with_addrmap_row_b15(u4::new(0xf))
.with_addrmap_row_b14(u4::new(0xf))
.with_addrmap_row_b13(u4::new(0x6))
.with_addrmap_row_b12(u4::new(0x6))
.with_addrmap_row_b2_11(u4::new(0x6))
.with_addrmap_row_b1(u4::new(0x6))
.with_addrmap_row_b0(u4::new(0x4))
.build(),
dram_odt: DramOdt::builder()
.with_phy_idle_local_odt(u2::new(0x0))
.with_phy_write_local_odt(u2::new(0x3))
.with_phy_read_local_odt(u2::new(0x0))
.with_rank0_wr_odt(u3::new(0x1))
.with_rank0_rd_odt(u3::new(0x0))
.build(),
phy_cmd_timeout_rddata_cpt: PhyCmdTimeoutRdDataCpt::builder()
.with_wrlvl_num_of_dq0(u4::new(0x7))
.with_gatelvl_num_of_dq0(u4::new(0x7))
.with_clk_stall_level(false)
.with_dis_phy_ctrl_rstn(false)
.with_rdc_fifo_rst_err_cnt_clr(false)
.with_use_fixed_re(true)
.with_rdc_we_to_re_delay(u4::new(0x8))
.with_wr_cmd_to_data(u4::new(0x0))
.with_rd_cmd_to_data(u4::new(0x0))
.build(),
dll_calib: DllCalib::builder().with_sel(DllCalibSel::Periodic).build(),
odt_delay_hold: OdtDelayHold::builder()
.with_wr_odt_hold(u4::new(0x5))
.with_rd_odt_hold(u4::new(0x0))
.with_wr_odt_delay(u4::new(0x0))
.with_rd_odt_delay(u4::new(0x3))
.build(),
ctrl_reg1: CtrlReg1::builder()
.with_selfref_enable(false)
.with_dis_collision_page_opt(false)
.with_dis_wc(false)
.with_refresh_update_level(false)
.with_auto_pre_en(false)
.with_lpr_num_entries(u6::new(0x1f))
.with_pageclose(false)
.build(),
ctrl_reg2: CtrlReg2::builder()
.with_go_2_critcal_enable(true)
.with_go_2_critical_hysteresis(0x0)
.build(),
ctrl_reg3: CtrlReg3::builder()
.with_dfi_t_wlmrd(u10::new(0x28))
.with_rdlvl_rr(0x41)
.with_wrlvl_ww(0x41)
.build(),
ctrl_reg4: CtrlReg4::builder()
.with_dfi_t_ctrlupd_interval_max_x1024(0x16)
.with_dfi_t_ctrlupd_interval_min_x1024(0x10)
.build(),
ctrl_reg5: CtrlReg5::builder()
.with_t_ckesr(u6::new(0x4))
.with_t_cksrx(u4::new(0x6))
.with_t_ckrse(u4::new(0x6))
.with_dfi_t_dram_clk_enable(u4::new(0x1))
.with_dfi_t_dram_clk_disable(u4::new(0x1))
.with_dfi_t_ctrl_delay(u4::new(0x1))
.build(),
ctrl_reg6: CtrlReg6::builder()
.with_t_cksx(u4::new(0x3))
.with_t_ckdpdx(u4::new(0x2))
.with_t_ckdpde(u4::new(0x2))
.with_t_ckpdx(u4::new(0x2))
.with_t_ckpde(u4::new(0x2))
.build(),
che_t_zq: CheTZq::builder()
.with_t_zq_short_nop(u10::new(0x40))
.with_t_zq_long_nop(u10::new(0x200))
.with_t_mode(u10::new(0x200))
.with_ddr3(true)
.with_dis_auto_zq(false)
.build(),
che_t_zq_short_interval_reg: CheTZqShortInterval::builder()
.with_dram_rstn_x1024(0x69)
.with_t_zq_short_interval(u20::new(0xcb73))
.build(),
deep_powerdown: DeepPowerdown::builder()
.with_deep_powerdown_to_x1024(0xff)
.with_enable(false)
.build(),
reg_2c: Reg2c::builder()
.with_dfi_rd_data_eye_train(true)
.with_dfi_rd_dqs_gate_level(true)
.with_dfi_wr_level_enable(true)
.with_trdlvl_max_error(false)
.with_twrlvl_max_error(false)
.with_dfi_rdlvl_max_x1024(u12::new(0xfff))
.with_dfi_wrlvl_max_x1024(u12::new(0xfff))
.build(),
reg_2d: Reg2d::builder().with_skip_ocd(true).build(),
dfi_timing: DfiTiming::builder()
.with_dfi_t_ctrlup_max(u10::new(0x40))
.with_dfi_t_ctrlup_min(u10::new(0x3))
.with_dfi_t_rddata_enable(u5::new(0x6))
.build(),
che_ecc_ctrl: CheEccControl::builder()
.with_clear_correctable_errors(false)
.with_clear_uncorrectable_errors(false)
.build(),
ecc_scrub: EccScrub::builder()
.with_disable_scrub(true)
.with_ecc_mode(EccMode::NoEcc)
.build(),
phy_receiver_enable: PhyReceiverEnable::builder()
.with_phy_dif_off(u4::new(0))
.with_phy_dif_on(u4::new(0))
.build(),
phy_config: [PhyConfig::builder()
.with_dq_offset(u7::new(0x40))
.with_wrlvl_inc_mode(false)
.with_gatelvl_inc_mode(false)
.with_rdlvl_inc_mode(false)
.with_data_slice_in_use(true)
.build(); 4],
phy_init_ratio: [
PhyInitRatio::builder()
.with_gatelvl_init_ratio(u10::new(0xcf))
.with_wrlvl_init_ratio(u10::new(0x3))
.build(),
PhyInitRatio::builder()
.with_gatelvl_init_ratio(u10::new(0xd0))
.with_wrlvl_init_ratio(u10::new(0x3))
.build(),
PhyInitRatio::builder()
.with_gatelvl_init_ratio(u10::new(0xbd))
.with_wrlvl_init_ratio(u10::new(0x0))
.build(),
PhyInitRatio::builder()
.with_gatelvl_init_ratio(u10::new(0xc1))
.with_wrlvl_init_ratio(u10::new(0x0))
.build(),
],
phy_rd_dqs_config: [
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x35))
.build(),
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x35))
.build(),
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x35))
.build(),
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x35))
.build(),
],
phy_wr_dqs_config: [
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x83))
.build(),
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x83))
.build(),
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x7f))
.build(),
PhyDqsConfig::builder()
.with_dqs_slave_delay(u9::new(0x0))
.with_dqs_slave_force(false)
.with_dqs_slave_ratio(u10::new(0x78))
.build(),
],
phy_we_cfg: [
PhyWriteEnableConfig::builder()
.with_fifo_we_in_delay(u9::new(0x0))
.with_fifo_we_in_force(false)
.with_fifo_we_slave_ratio(u11::new(0x124))
.build(),
PhyWriteEnableConfig::builder()
.with_fifo_we_in_delay(u9::new(0x0))
.with_fifo_we_in_force(false)
.with_fifo_we_slave_ratio(u11::new(0x125))
.build(),
PhyWriteEnableConfig::builder()
.with_fifo_we_in_delay(u9::new(0x0))
.with_fifo_we_in_force(false)
.with_fifo_we_slave_ratio(u11::new(0x112))
.build(),
PhyWriteEnableConfig::builder()
.with_fifo_we_in_delay(u9::new(0x0))
.with_fifo_we_in_force(false)
.with_fifo_we_slave_ratio(u11::new(0x116))
.build(),
],
phy_wr_data_slv: [
PhyWriteDataSlaveConfig::builder()
.with_wr_data_slave_delay(u9::new(0x0))
.with_wr_data_slave_force(false)
.with_wr_data_slave_ratio(u10::new(0xc3))
.build(),
PhyWriteDataSlaveConfig::builder()
.with_wr_data_slave_delay(u9::new(0x0))
.with_wr_data_slave_force(false)
.with_wr_data_slave_ratio(u10::new(0xc3))
.build(),
PhyWriteDataSlaveConfig::builder()
.with_wr_data_slave_delay(u9::new(0x0))
.with_wr_data_slave_force(false)
.with_wr_data_slave_ratio(u10::new(0xbf))
.build(),
PhyWriteDataSlaveConfig::builder()
.with_wr_data_slave_delay(u9::new(0x0))
.with_wr_data_slave_force(false)
.with_wr_data_slave_ratio(u10::new(0xb8))
.build(),
],
reg64: Reg64::builder()
.with_cmd_latency(false)
.with_lpddr(false)
.with_ctrl_slave_delay(u7::new(0x0))
.with_ctrl_slave_force(false)
.with_ctrl_slave_ratio(u10::new(0x100))
.with_sel_logic(false)
.with_invert_clkout(true)
.with_bl2(false)
.build(),
reg65: Reg65::builder()
.with_ctrl_slave_delay(u2::new(0x0))
.with_dis_calib_rst(false)
.with_use_rd_data_eye_level(true)
.with_use_rd_dqs_gate_level(true)
.with_use_wr_level(true)
.with_dll_lock_diff(u4::new(0xf))
.with_rd_rl_delay(u5::new(0x4))
.with_wr_rl_delay(u5::new(0x2))
.build(),
page_mask: 0x0,
axi_priority_wr_port: [
AxiPriorityWritePort::builder()
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_wr_port(u10::new(0x3ff))
.build(),
AxiPriorityWritePort::builder()
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_wr_port(u10::new(0x3ff))
.build(),
AxiPriorityWritePort::builder()
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_wr_port(u10::new(0x3ff))
.build(),
AxiPriorityWritePort::builder()
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_wr_port(u10::new(0x3ff))
.build(),
],
axi_priority_rd_port: [
AxiPriorityReadPort::builder()
.with_enable_hpr(false)
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_rd_port_n(u10::new(0x3ff))
.build(),
AxiPriorityReadPort::builder()
.with_enable_hpr(false)
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_rd_port_n(u10::new(0x3ff))
.build(),
AxiPriorityReadPort::builder()
.with_enable_hpr(false)
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_rd_port_n(u10::new(0x3ff))
.build(),
AxiPriorityReadPort::builder()
.with_enable_hpr(false)
.with_disable_page_match(false)
.with_disable_urgent(false)
.with_disable_aging(false)
.with_pri_rd_port_n(u10::new(0x3ff))
.build(),
],
lpddr_ctrl_0: LpddrControl0::builder()
.with_mr4_margin(0x0)
.with_derate_enable(false)
.with_per_bank_refresh(false)
.with_lpddr2(LpddrBit::Ddr2Ddr3)
.build(),
lpddr_ctrl_1: LpddrControl1::builder().with_mr4_read_interval(0x0).build(),
lpddr_ctrl_2: LpddrControl2::builder()
.with_t_mrw(u10::new(0x5))
.with_idle_after_reset_x32(0x12)
.with_min_stable_clock_x1(u4::new(0x5))
.build(),
lpddr_ctrl_3: LpddrControl3::builder()
.with_dev_zqinit_x32(u10::new(0x12))
.with_max_auto_init_x1024(0xa8)
.build(),
};

View File

@@ -25,7 +25,7 @@ use zynq7000_hal::{
};
use zynq7000_rt as _;
use crate::ddr_cfg::{DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS, DDRIOB_CONFIG_SET_ZEDBOARD};
use crate::ddr_cfg::DDRIOB_CONFIG_SET_ZEDBOARD;
pub mod ddr_cfg;
@@ -128,8 +128,8 @@ pub fn main() -> ! {
ddr_3x_div: u6::new(2),
ddr_2x_div: u6::new(3),
},
&DDRIOB_CONFIG_SET_ZEDBOARD,
&DDRC_CONFIG_ZEDBOARD_FULL_BUILDERS,
&zedboard_bsp::ddriob_config_autogen::DDRIOB_CONFIG_SET_ZEDBOARD,
&zedboard_bsp::ddrc_config_autogen::DDRC_CONFIG_ZEDBOARD,
);
info!("DDR init done.");

View File

@@ -2,6 +2,7 @@ pub const DDRC_BASE_ADDR: usize = 0xF800_6000;
pub mod regs {
use arbitrary_int::{u2, u3, u4, u5, u6, u7, u9, u10, u11, u12, u20};
pub use crate::slcr::ddriob::DdriobConfig;
#[bitbybit::bitenum(u2)]
#[derive(Debug, PartialEq, Eq)]

View File

@@ -381,6 +381,7 @@ impl InterruptControl {
}
#[bitbybit::bitenum(u2, exhaustive = false)]
#[derive(Debug)]
pub enum PhyOperation {
Read = 0b10,
Write = 0b01,

View File

@@ -1,10 +1,11 @@
//! # GPIO register module.
#[bitbybit::bitfield(u32, default = 0x0, debug)]
#[bitbybit::bitfield(u32, default = 0x0)]
#[derive(Debug)]
pub struct MaskedOutput {
#[bits(16..=31, w)]
pub mask: u16,
mask: u16,
#[bits(0..=15, rw)]
pub output: u16,
output: u16,
}
#[derive(derive_mmio::Mmio)]

View File

@@ -56,6 +56,7 @@ impl Control {
}
#[bitbybit::bitenum(u1, exhaustive = true)]
#[derive(Debug)]
pub enum ReplacementPolicy {
PseudoRandomWithLfsr = 0,
RoundRobin = 1,
@@ -123,7 +124,7 @@ pub struct AuxControl {
}
#[bitbybit::bitfield(u32, default = 0x0, debug)]
#[derive(Debug, PartialEq, Eq)]
#[derive(PartialEq, Eq)]
pub struct LatencyConfig {
/// Latency is the numerical value + 1 cycles.
#[bits(8..=10, rw)]

View File

@@ -69,7 +69,6 @@ pub struct Config {
}
#[bitbybit::bitfield(u32, default = 0x0, debug)]
#[derive(Debug)]
pub struct InterruptStatus {
#[bit(6, rw)]
tx_underflow: bool,

View File

@@ -5,6 +5,7 @@ pub const UART_0_BASE: usize = 0xE000_0000;
pub const UART_1_BASE: usize = 0xE000_1000;
#[bitbybit::bitenum(u3, exhaustive = true)]
#[derive(Debug)]
pub enum Parity {
Even = 0b000,
Odd = 0b001,