From 5a2a857a2ff7d9b563a04c034101f4921034ddb2 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 21 Jun 2018 16:23:41 +0800 Subject: [PATCH] firmware: clean up SYSREF phase management --- artiq/firmware/libboard_artiq/ad9154.rs | 26 +++++++++----------- artiq/firmware/libboard_artiq/hmc830_7043.rs | 23 ++++++++--------- artiq/firmware/runtime/main.rs | 2 +- artiq/firmware/satman/main.rs | 2 +- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/artiq/firmware/libboard_artiq/ad9154.rs b/artiq/firmware/libboard_artiq/ad9154.rs index e637a4550..c4086ca02 100644 --- a/artiq/firmware/libboard_artiq/ad9154.rs +++ b/artiq/firmware/libboard_artiq/ad9154.rs @@ -703,11 +703,11 @@ fn dac_sysref_scan(dacno: u8, center_phase: u16) { info!("AD9154-{} SYSREF scan...", dacno); - hmc7043::cfg_dac_sysref(dacno, center_phase); + hmc7043::sysref_offset_dac(dacno, center_phase); clock::spin_us(10000); let mut sync_error_last = dac_get_sync_error(dacno); for d in 0..128 { - hmc7043::cfg_dac_sysref(dacno, center_phase - d); + hmc7043::sysref_offset_dac(dacno, center_phase - d); clock::spin_us(10000); let sync_error = dac_get_sync_error(dacno); if sync_error != sync_error_last { @@ -717,11 +717,11 @@ fn dac_sysref_scan(dacno: u8, center_phase: u16) { } } - hmc7043::cfg_dac_sysref(dacno, center_phase); + hmc7043::sysref_offset_dac(dacno, center_phase); clock::spin_us(10000); sync_error_last = dac_get_sync_error(dacno); for d in 0..128 { - hmc7043::cfg_dac_sysref(dacno, center_phase + d); + hmc7043::sysref_offset_dac(dacno, center_phase + d); clock::spin_us(10000); let sync_error = dac_get_sync_error(dacno); if sync_error != sync_error_last { @@ -743,12 +743,7 @@ fn dac_sysref_scan(dacno: u8, center_phase: u16) { } } -fn dac_sysref_cfg(dacno: u8, phase: u16) { - info!("AD9154-{} setting SYSREF phase to {}", dacno, phase); - hmc7043::cfg_dac_sysref(dacno, phase); -} - -fn init_dac(dacno: u8) -> Result<(), &'static str> { +fn init_dac(dacno: u8, sysref_phase: u16) -> Result<(), &'static str> { let dacno = dacno as u8; // Reset the DAC, detect and configure it dac_reset(dacno); @@ -757,15 +752,14 @@ fn init_dac(dacno: u8) -> Result<(), &'static str> { // Run the PRBS, STPL and SYSREF scan tests dac_prbs(dacno)?; dac_stpl(dacno, 4, 2)?; - let sysref_phase = 61; dac_sysref_scan(dacno, sysref_phase); // Set SYSREF phase and reconfigure the DAC - dac_sysref_cfg(dacno, sysref_phase); + hmc7043::sysref_offset_dac(dacno, sysref_phase); dac_cfg_retry(dacno)?; Ok(()) } -pub fn init() { +pub fn init(sysref_phase_fpga: u16, sysref_phase_dac: u16) { // Release the JESD clock domain reset late, as we need to // set up clock chips before. jesd_unreset(); @@ -774,10 +768,12 @@ pub fn init() { // the HMC7043 input clock (which defines slip resolution) // is 2x the DAC clock, so there are two possible phases from // the divider states. This deterministically selects one. - hmc7043::sysref_rtio_align(); + hmc7043::sysref_rtio_align(sysref_phase_fpga); for dacno in 0..csr::AD9154.len() { - match init_dac(dacno as u8) { + // We assume DCLK and SYSREF traces are matched on the PCB + // (they are on Sayma) so only one phase is needed. + match init_dac(dacno as u8, sysref_phase_dac) { Ok(_) => (), Err(e) => error!("failed to initialize AD9154-{}: {}", dacno, e) } diff --git a/artiq/firmware/libboard_artiq/hmc830_7043.rs b/artiq/firmware/libboard_artiq/hmc830_7043.rs index 9015bd917..b3b5ece69 100644 --- a/artiq/firmware/libboard_artiq/hmc830_7043.rs +++ b/artiq/firmware/libboard_artiq/hmc830_7043.rs @@ -318,13 +318,13 @@ pub mod hmc7043 { info!(" ...done"); } - pub fn cfg_dac_sysref(dacno: u8, phase: u16) { + pub fn sysref_offset_dac(dacno: u8, phase_offset: u16) { /* Analog delay resolution: 25ps * Digital delay resolution: 1/2 input clock cycle = 416ps for 1.2GHz * 16*25ps = 400ps: limit analog delay to 16 steps instead of 32. */ - let analog_delay = (phase % 17) as u8; - let digital_delay = (phase / 17) as u8; + let analog_delay = (phase_offset % 17) as u8; + let digital_delay = (phase_offset / 17) as u8; spi_setup(); if dacno == 0 { write(0x00d5, analog_delay); @@ -337,9 +337,9 @@ pub mod hmc7043 { } } - fn cfg_fpga_sysref(phase: u16) { - let analog_delay = (phase % 17) as u8; - let digital_delay = (phase / 17) as u8; + fn sysref_offset_fpga(phase_offset: u16) { + let analog_delay = (phase_offset % 17) as u8; + let digital_delay = (phase_offset / 17) as u8; spi_setup(); write(0x0111, analog_delay); write(0x0112, digital_delay); @@ -355,15 +355,13 @@ pub mod hmc7043 { unsafe { csr::sysref_sampler::sample_result_read() == 1 } } - pub fn sysref_rtio_align() { + pub fn sysref_rtio_align(phase_offset: u16) { info!("aligning SYSREF with RTIO..."); - let phase_offset = 44; let mut slips0 = 0; let mut slips1 = 0; - // meet setup/hold (assuming FPGA timing margins are OK) - cfg_fpga_sysref(phase_offset); + sysref_offset_fpga(phase_offset); // if we are already in the 1 zone, get out of it while sysref_sample() { sysref_slip(); @@ -374,12 +372,11 @@ pub mod hmc7043 { sysref_slip(); slips1 += 1; } - info!(" ...done ({}/{} slips), verifying timing margin", slips0, slips1); let mut margin = None; for d in 0..phase_offset { - cfg_fpga_sysref(phase_offset - d); + sysref_offset_fpga(phase_offset - d); if !sysref_sample() { margin = Some(d); break; @@ -387,7 +384,7 @@ pub mod hmc7043 { } // meet setup/hold - cfg_fpga_sysref(phase_offset); + sysref_offset_fpga(phase_offset); if margin.is_some() { let margin = margin.unwrap(); diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 900bd435f..8e407d4c5 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -109,7 +109,7 @@ fn startup() { /* must be the first SPI init because of HMC830 SPI mode selection */ board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043"); #[cfg(has_ad9154)] - board_artiq::ad9154::init(); + board_artiq::ad9154::init(44, 61); #[cfg(has_allaki_atts)] board_artiq::hmc542::program_all(8/*=4dB*/); diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 3f47537a4..302a0ef95 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -262,7 +262,7 @@ pub extern fn main() -> i32 { /* must be the first SPI init because of HMC830 SPI mode selection */ hmc830_7043::init().expect("cannot initialize HMC830/7043"); #[cfg(has_ad9154)] - board_artiq::ad9154::init(); + board_artiq::ad9154::init(32, 61); #[cfg(has_allaki_atts)] board_artiq::hmc542::program_all(8/*=4dB*/);