Compare commits

..

5 Commits

Author SHA1 Message Date
morgan 005f96a924 Firmware: Runtime WRPLL
runtime: drive CLK_SEL to true when si549 is used
runtime & libboard_artiq: allow standalone to use io_expander
si549: add bit bang mmcm dynamic configuration
si549: add frequency counter for refclk
rtio_clocking & si549: add 125Mhz wrpll refclk setup
2024-03-19 12:12:24 +08:00
morgan 682e92b17e Firmware: Satman skew calibration & tester
cargo template: add calibrate_wrpll_skew feature
tag collector: add TAG_OFFSET for Satman WRPLL
tag collector: add TAG_OFFSET getter & setter for calibration
wrpll: add skew tester and calibration
wrpll: gate calibration behind calibrate_wrpll_skew feature
2024-03-19 12:12:19 +08:00
morgan fbf973efd0 Firmware: Satman WRPLL
satman: drive CLK_SEL to true when si549 is used
satman : add main & helper si549 setup
satman : add WRPLL select_recovered_clock
si549: add tag collector to process gtx & main tags
si549: add frequency counter to set BASE_ADPLL
si549: add set_adpll for main & helper PLL
si549: add main & helper PLL
FIQ & si549: replace dummy with a custom handler for gtx & main tags ISR
2024-03-19 12:11:35 +08:00
morgan a163d29ec0 Firmware: Si549 and io_expander
io_expander: set CLK_SEL pin to output when si549 is used
io_expander: gate virtual leds for standalone
si549: add bit bang i2c
si549: add si549 programming
si549: add main & helper setup
2024-03-19 12:11:18 +08:00
morgan 9d27741de8 Gateware: kasli_soc WRPLL setup
kasli_soc: use enable_wrpll from json to switch from si5324 to si549
kasli_soc: add wrpll for all variants
kasli_soc: add gtx & main tag nFIQ for all variants
kasli_soc: add wrpll_refclk for runtime
kasli_soc: add skewtester for satman
kasli_soc: add WRPLL_REF_CLK config for firmware
2024-03-19 12:11:13 +08:00
2 changed files with 24 additions and 26 deletions

View File

@ -594,7 +594,7 @@ class GenericSatellite(SoCCore):
self.csr_devices.append("wrpll")
self.comb += self.ps7.core.core0.nfiq.eq(self.wrpll.ev.irq)
self.config["HAS_SI549"] = None
self.config["WRPLL_REF_CLK"] = "GTX_CDR"
self.config["WRPLL_REF_CLK"] = "GT_CDR"
else:
self.submodules.siphaser = SiPhaser7Series(
si5324_clkin=platform.request("cdr_clk"),

View File

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