|
|
@ -357,7 +357,7 @@ pub mod wrpll {
|
|
|
|
mod tag_collector {
|
|
|
|
mod tag_collector {
|
|
|
|
use super::*;
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(wrpll_ref_clk = "GTX_CDR")]
|
|
|
|
#[cfg(wrpll_ref_clk = "GT_CDR")]
|
|
|
|
static TAG_OFFSET: Mutex<u32> = Mutex::new(19050);
|
|
|
|
static TAG_OFFSET: Mutex<u32> = Mutex::new(19050);
|
|
|
|
#[cfg(wrpll_ref_clk = "SMA_CLKIN")]
|
|
|
|
#[cfg(wrpll_ref_clk = "SMA_CLKIN")]
|
|
|
|
static TAG_OFFSET: Mutex<u32> = Mutex::new(0);
|
|
|
|
static TAG_OFFSET: Mutex<u32> = Mutex::new(0);
|
|
|
@ -457,7 +457,7 @@ pub mod wrpll {
|
|
|
|
csr::wrpll::frequency_counter_update_en_write(1);
|
|
|
|
csr::wrpll::frequency_counter_update_en_write(1);
|
|
|
|
timer.delay_us(150_000); // 8ns << TIMER_WIDTH
|
|
|
|
timer.delay_us(150_000); // 8ns << TIMER_WIDTH
|
|
|
|
csr::wrpll::frequency_counter_update_en_write(0);
|
|
|
|
csr::wrpll::frequency_counter_update_en_write(0);
|
|
|
|
#[cfg(wrpll_ref_clk = "GTX_CDR")]
|
|
|
|
#[cfg(wrpll_ref_clk = "GT_CDR")]
|
|
|
|
let ref_count = csr::wrpll::frequency_counter_counter_rtio_rx0_read();
|
|
|
|
let ref_count = csr::wrpll::frequency_counter_counter_rtio_rx0_read();
|
|
|
|
#[cfg(wrpll_ref_clk = "SMA_CLKIN")]
|
|
|
|
#[cfg(wrpll_ref_clk = "SMA_CLKIN")]
|
|
|
|
let ref_count = csr::wrpll::frequency_counter_counter_ref_read();
|
|
|
|
let ref_count = csr::wrpll::frequency_counter_counter_ref_read();
|
|
|
@ -534,7 +534,7 @@ pub mod wrpll {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(wrpll_ref_clk = "GTX_CDR")]
|
|
|
|
#[cfg(wrpll_ref_clk = "GT_CDR")]
|
|
|
|
fn test_skew(timer: &mut GlobalTimer) -> Result<(), &'static str> {
|
|
|
|
fn test_skew(timer: &mut GlobalTimer) -> Result<(), &'static str> {
|
|
|
|
// wait for PLL to stabilize
|
|
|
|
// wait for PLL to stabilize
|
|
|
|
timer.delay_us(20_000);
|
|
|
|
timer.delay_us(20_000);
|
|
|
@ -547,7 +547,7 @@ pub mod wrpll {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(wrpll_ref_clk = "GTX_CDR")]
|
|
|
|
#[cfg(wrpll_ref_clk = "GT_CDR")]
|
|
|
|
fn has_timing_error(timer: &mut GlobalTimer) -> bool {
|
|
|
|
fn has_timing_error(timer: &mut GlobalTimer) -> bool {
|
|
|
|
unsafe {
|
|
|
|
unsafe {
|
|
|
|
csr::wrpll_skewtester::error_write(1);
|
|
|
|
csr::wrpll_skewtester::error_write(1);
|
|
|
@ -664,7 +664,7 @@ pub mod wrpll {
|
|
|
|
#[cfg(feature = "calibrate_wrpll_skew")]
|
|
|
|
#[cfg(feature = "calibrate_wrpll_skew")]
|
|
|
|
calibrate_skew(timer).expect("failed to set the correct skew");
|
|
|
|
calibrate_skew(timer).expect("failed to set the correct skew");
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(wrpll_ref_clk = "GTX_CDR")]
|
|
|
|
#[cfg(wrpll_ref_clk = "GT_CDR")]
|
|
|
|
test_skew(timer).expect("skew test failed");
|
|
|
|
test_skew(timer).expect("skew test failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -688,12 +688,10 @@ pub mod wrpll_refclk {
|
|
|
|
pub filt_reg2: u16, //0x4F
|
|
|
|
pub filt_reg2: u16, //0x4F
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn one_clock_cycle(timer: &mut GlobalTimer) {
|
|
|
|
fn one_clock_cycle() {
|
|
|
|
unsafe {
|
|
|
|
unsafe {
|
|
|
|
csr::wrpll_refclk::mmcm_dclk_write(1);
|
|
|
|
csr::wrpll_refclk::mmcm_dclk_write(1);
|
|
|
|
timer.delay_us(1);
|
|
|
|
|
|
|
|
csr::wrpll_refclk::mmcm_dclk_write(0);
|
|
|
|
csr::wrpll_refclk::mmcm_dclk_write(0);
|
|
|
|
timer.delay_us(1);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -732,33 +730,33 @@ pub mod wrpll_refclk {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
#[allow(dead_code)]
|
|
|
|
fn read(timer: &mut GlobalTimer, address: u8) -> u16 {
|
|
|
|
fn read(address: u8) -> u16 {
|
|
|
|
set_addr(address);
|
|
|
|
set_addr(address);
|
|
|
|
set_enable(true);
|
|
|
|
set_enable(true);
|
|
|
|
// Set DADDR on the MMCM and assert DEN for one clock cycle
|
|
|
|
// Set DADDR on the MMCM and assert DEN for one clock cycle
|
|
|
|
one_clock_cycle(timer);
|
|
|
|
one_clock_cycle();
|
|
|
|
|
|
|
|
|
|
|
|
set_enable(false);
|
|
|
|
set_enable(false);
|
|
|
|
while !drp_ready() {
|
|
|
|
while !drp_ready() {
|
|
|
|
// keep the clock signal until data is ready
|
|
|
|
// keep the clock signal until data is ready
|
|
|
|
one_clock_cycle(timer);
|
|
|
|
one_clock_cycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
get_data()
|
|
|
|
get_data()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn write(timer: &mut GlobalTimer, address: u8, value: u16) {
|
|
|
|
fn write(address: u8, value: u16) {
|
|
|
|
set_addr(address);
|
|
|
|
set_addr(address);
|
|
|
|
set_data(value);
|
|
|
|
set_data(value);
|
|
|
|
set_write_enable(true);
|
|
|
|
set_write_enable(true);
|
|
|
|
set_enable(true);
|
|
|
|
set_enable(true);
|
|
|
|
// Set DADDR, DI on the MMCM and assert DWE, DEN for one clock cycle
|
|
|
|
// Set DADDR, DI on the MMCM and assert DWE, DEN for one clock cycle
|
|
|
|
one_clock_cycle(timer);
|
|
|
|
one_clock_cycle();
|
|
|
|
|
|
|
|
|
|
|
|
set_write_enable(false);
|
|
|
|
set_write_enable(false);
|
|
|
|
set_enable(false);
|
|
|
|
set_enable(false);
|
|
|
|
while !drp_ready() {
|
|
|
|
while !drp_ready() {
|
|
|
|
// keep the clock signal until write is finished
|
|
|
|
// keep the clock signal until write is finished
|
|
|
|
one_clock_cycle(timer);
|
|
|
|
one_clock_cycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -783,17 +781,17 @@ pub mod wrpll_refclk {
|
|
|
|
// Based on "DRP State Machine" from XAPP888
|
|
|
|
// Based on "DRP State Machine" from XAPP888
|
|
|
|
// hold reset HIGH during mmcm config
|
|
|
|
// hold reset HIGH during mmcm config
|
|
|
|
reset(true);
|
|
|
|
reset(true);
|
|
|
|
write(timer, 0x08, settings.clkout0_reg1);
|
|
|
|
write(0x08, settings.clkout0_reg1);
|
|
|
|
write(timer, 0x09, settings.clkout0_reg2);
|
|
|
|
write(0x09, settings.clkout0_reg2);
|
|
|
|
write(timer, 0x14, settings.clkfbout_reg1);
|
|
|
|
write(0x14, settings.clkfbout_reg1);
|
|
|
|
write(timer, 0x15, settings.clkfbout_reg2);
|
|
|
|
write(0x15, settings.clkfbout_reg2);
|
|
|
|
write(timer, 0x16, settings.div_reg);
|
|
|
|
write(0x16, settings.div_reg);
|
|
|
|
write(timer, 0x18, settings.lock_reg1);
|
|
|
|
write(0x18, settings.lock_reg1);
|
|
|
|
write(timer, 0x19, settings.lock_reg2);
|
|
|
|
write(0x19, settings.lock_reg2);
|
|
|
|
write(timer, 0x1A, settings.lock_reg3);
|
|
|
|
write(0x1A, settings.lock_reg3);
|
|
|
|
write(timer, 0x28, settings.power_reg);
|
|
|
|
write(0x28, settings.power_reg);
|
|
|
|
write(timer, 0x4E, settings.filt_reg1);
|
|
|
|
write(0x4E, settings.filt_reg1);
|
|
|
|
write(timer, 0x4F, settings.filt_reg2);
|
|
|
|
write(0x4F, settings.filt_reg2);
|
|
|
|
reset(false);
|
|
|
|
reset(false);
|
|
|
|
|
|
|
|
|
|
|
|
// wait for the mmcm to lock
|
|
|
|
// wait for the mmcm to lock
|
|
|
|