diff --git a/artiq/firmware/libboard_artiq/hmc830_7043.rs b/artiq/firmware/libboard_artiq/hmc830_7043.rs index 880a1d085..18cbb8794 100644 --- a/artiq/firmware/libboard_artiq/hmc830_7043.rs +++ b/artiq/firmware/libboard_artiq/hmc830_7043.rs @@ -155,8 +155,8 @@ pub mod hmc7043 { (true, SYSREF_DIV, 0x08, true), // 1: DAC1_SYSREF (true, DAC_CLK_DIV, 0x08, false), // 2: DAC0_CLK (true, SYSREF_DIV, 0x08, true), // 3: DAC0_SYSREF - (false, 0, 0x10, true), // 4: AMC_FPGA_SYSREF0 - (true, SYSREF_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1 + (true, SYSREF_DIV, 0x10, true), // 4: AMC_FPGA_SYSREF0 + (true, FPGA_CLK_DIV, 0x10, true), // 5: AMC_FPGA_SYSREF1 (false, 0, 0x10, false), // 6: unused (true, SYSREF_DIV, 0x10, true), // 7: RTM_FPGA_SYSREF0 (true, FPGA_CLK_DIV, 0x08, false), // 8: GTP_CLK0_IN diff --git a/artiq/firmware/satman/jdcg.rs b/artiq/firmware/satman/jdcg.rs index f7bdd8f90..a4ae234db 100644 --- a/artiq/firmware/satman/jdcg.rs +++ b/artiq/firmware/satman/jdcg.rs @@ -1,100 +1,123 @@ -use board_misoc::{csr, clock}; -use board_artiq::drtioaux; +pub mod jesd { + use board_misoc::{csr, clock}; -use super::jdac_requests; - -pub fn jesd_reset(reset: bool) { - unsafe { - csr::jesd_crg::jreset_write(if reset {1} else {0}); + pub fn reset(reset: bool) { + unsafe { + csr::jesd_crg::jreset_write(if reset {1} else {0}); + } } -} -fn jesd_enable(dacno: u8, en: bool) { - unsafe { - (csr::JDCG[dacno as usize].jesd_control_enable_write)(if en {1} else {0}) - } - clock::spin_us(5000); -} - -fn jesd_ready(dacno: u8) -> bool { - unsafe { - (csr::JDCG[dacno as usize].jesd_control_ready_read)() != 0 - } -} - -fn jesd_prbs(dacno: u8, en: bool) { - unsafe { - (csr::JDCG[dacno as usize].jesd_control_prbs_config_write)(if en {0b01} else {0b00}) - } - clock::spin_us(5000); -} - -fn jesd_stpl(dacno: u8, en: bool) { - unsafe { - (csr::JDCG[dacno as usize].jesd_control_stpl_enable_write)(if en {1} else {0}) - } - clock::spin_us(5000); -} - -fn jesd_jsync(dacno: u8) -> bool { - unsafe { - (csr::JDCG[dacno as usize].jesd_control_jsync_read)() != 0 - } -} - -fn jdac_basic_request(dacno: u8, reqno: u8) { - if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacBasicRequest { - destination: 0, - dacno: dacno, - reqno: reqno - }) { - error!("aux packet error ({})", e); - } - match drtioaux::recv_timeout(1, Some(1000)) { - Ok(drtioaux::Packet::JdacBasicReply { succeeded }) => - if !succeeded { - error!("JESD DAC basic request failed (dacno={}, reqno={})", dacno, reqno); - }, - Ok(packet) => error!("received unexpected aux packet: {:?}", packet), - Err(e) => error!("aux packet error ({})", e), - } -} - -pub fn init() { - for dacno in 0..csr::JDCG.len() { - let dacno = dacno as u8; - info!("DAC-{} initializing...", dacno); - - jesd_enable(dacno, true); - jesd_prbs(dacno, false); - jesd_stpl(dacno, false); - - jdac_basic_request(dacno, jdac_requests::INIT); - - jesd_prbs(dacno, true); - jdac_basic_request(dacno, jdac_requests::PRBS); - jesd_prbs(dacno, false); - - jesd_stpl(dacno, true); - jdac_basic_request(dacno, jdac_requests::STPL); - jesd_stpl(dacno, false); - - jdac_basic_request(dacno, jdac_requests::INIT); - - let t = clock::get_ms(); - while !jesd_ready(dacno) { - if clock::get_ms() > t + 200 { - error!("JESD ready timeout"); - break; - } + pub fn enable(dacno: u8, en: bool) { + unsafe { + (csr::JDCG[dacno as usize].jesd_control_enable_write)(if en {1} else {0}) } clock::spin_us(5000); - jdac_basic_request(dacno, jdac_requests::PRINT_STATUS); + } - if !jesd_jsync(dacno) { - error!("bad SYNC"); + pub fn ready(dacno: u8) -> bool { + unsafe { + (csr::JDCG[dacno as usize].jesd_control_ready_read)() != 0 } + } - info!(" ...done"); + pub fn prbs(dacno: u8, en: bool) { + unsafe { + (csr::JDCG[dacno as usize].jesd_control_prbs_config_write)(if en {0b01} else {0b00}) + } + clock::spin_us(5000); + } + + pub fn stpl(dacno: u8, en: bool) { + unsafe { + (csr::JDCG[dacno as usize].jesd_control_stpl_enable_write)(if en {1} else {0}) + } + clock::spin_us(5000); + } + + pub fn jsync(dacno: u8) -> bool { + unsafe { + (csr::JDCG[dacno as usize].jesd_control_jsync_read)() != 0 + } + } +} + +pub mod jdac { + use board_misoc::{csr, clock}; + use board_artiq::drtioaux; + + use super::jesd; + use super::super::jdac_requests; + + pub fn basic_request(dacno: u8, reqno: u8) { + if let Err(e) = drtioaux::send(1, &drtioaux::Packet::JdacBasicRequest { + destination: 0, + dacno: dacno, + reqno: reqno + }) { + error!("aux packet error ({})", e); + } + match drtioaux::recv_timeout(1, Some(1000)) { + Ok(drtioaux::Packet::JdacBasicReply { succeeded }) => + if !succeeded { + error!("JESD DAC basic request failed (dacno={}, reqno={})", dacno, reqno); + }, + Ok(packet) => error!("received unexpected aux packet: {:?}", packet), + Err(e) => error!("aux packet error ({})", e), + } + } + + pub fn init() { + for dacno in 0..csr::JDCG.len() { + let dacno = dacno as u8; + info!("DAC-{} initializing...", dacno); + + jesd::enable(dacno, true); + clock::spin_us(10); + if !jesd::ready(dacno) { + error!("JESD core reported not ready"); + } + + basic_request(dacno, jdac_requests::INIT); + + jesd::prbs(dacno, true); + basic_request(dacno, jdac_requests::PRBS); + jesd::prbs(dacno, false); + + jesd::stpl(dacno, true); + basic_request(dacno, jdac_requests::STPL); + jesd::stpl(dacno, false); + + basic_request(dacno, jdac_requests::INIT); + clock::spin_us(5000); + + basic_request(dacno, jdac_requests::PRINT_STATUS); + + if !jesd::jsync(dacno) { + error!("JESD core reported bad SYNC"); + } + + info!(" ...done"); + } + } +} + +pub mod jesd204sync { + fn sysref_auto_rtio_align() -> Result<(), &'static str> { + info!("TODO: sysref_auto_rtio_align"); + Ok(()) + } + + fn sysref_auto_dac_align() -> Result<(), &'static str> { + info!("TODO: sysref_auto_dac_align"); + Ok(()) + } + + pub fn sysref_auto_align() { + if let Err(e) = sysref_auto_rtio_align() { + error!("failed to align SYSREF at FPGA: {}", e); + } + if let Err(e) = sysref_auto_dac_align() { + error!("failed to align SYSREF at DAC: {}", e); + } } } diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index c08e1b605..9d09d6859 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -498,9 +498,9 @@ pub extern fn main() -> i32 { * To handle those cases, we simply keep the JESD204 core in reset unless the * Si5324 is locked to the recovered clock. */ - jdcg::jesd_reset(false); + jdcg::jesd::reset(false); if repeaters[0].is_up() { - jdcg::init(); + jdcg::jdac::init(); } } @@ -516,26 +516,15 @@ pub extern fn main() -> i32 { for mut rep in repeaters.iter_mut() { rep.service(&routing_table, rank); } - #[cfg(has_jdcg)] - { - let rep0_is_up = repeaters[0].is_up(); - if rep0_is_up && !rep0_was_up { - jdcg::init(); - } - rep0_was_up = rep0_is_up; - } hardware_tick(&mut hardware_tick_ts); if drtiosat_tsc_loaded() { info!("TSC loaded from uplink"); - /* TODO: #[cfg(has_jdcg)] + #[cfg(has_jdcg)] { - if let Err(e) = board_artiq::jesd204sync::sysref_auto_rtio_align() { - error!("failed to align SYSREF at FPGA: {}", e); + if rep0_was_up { + jdcg::jesd204sync::sysref_auto_align(); } - if let Err(e) = board_artiq::jesd204sync::sysref_auto_dac_align() { - error!("failed to align SYSREF at DAC: {}", e); - } - } */ + } for rep in repeaters.iter() { if let Err(e) = rep.sync_tsc() { error!("failed to sync TSC ({})", e); @@ -545,10 +534,19 @@ pub extern fn main() -> i32 { error!("aux packet error: {}", e); } } + #[cfg(has_jdcg)] + { + let rep0_is_up = repeaters[0].is_up(); + if rep0_is_up && !rep0_was_up { + jdcg::jdac::init(); + jdcg::jesd204sync::sysref_auto_align(); + } + rep0_was_up = rep0_is_up; + } } #[cfg(has_jdcg)] - jdcg::jesd_reset(true); + jdcg::jesd::reset(true); drtiosat_reset_phy(true); drtiosat_reset(true); diff --git a/artiq/gateware/targets/sayma_amc.py b/artiq/gateware/targets/sayma_amc.py index adc305e5e..82b53c817 100755 --- a/artiq/gateware/targets/sayma_amc.py +++ b/artiq/gateware/targets/sayma_amc.py @@ -58,6 +58,7 @@ class SatelliteBase(BaseSoC): l2_size=128*1024, **kwargs) add_identifier(self, suffix=identifier_suffix) + self.rtio_clk_freq = rtio_clk_freq platform = self.platform @@ -279,11 +280,17 @@ class Satellite(SatelliteBase): self.add_rtio(rtio_channels) self.submodules.sysref_sampler = jesd204_tools.SysrefSampler( - platform.request("dac_sysref"), self.rtio_tsc.coarse_ts) + platform.request("amc_fpga_sysref", 0), self.rtio_tsc.coarse_ts) self.csr_devices.append("sysref_sampler") self.jdcg_0.jesd.core.register_jref(self.sysref_sampler.jref) self.jdcg_1.jesd.core.register_jref(self.sysref_sampler.jref) + # DDMTD + # https://github.com/sinara-hw/Sayma_RTM/issues/68 + sysref_pads = platform.request("amc_fpga_sysref", 1) + self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(sysref_pads, self.rtio_clk_freq) + self.csr_devices.append("sysref_ddmtd") + class SimpleSatellite(SatelliteBase): def __init__(self, **kwargs): diff --git a/artiq/gateware/targets/sayma_rtm.py b/artiq/gateware/targets/sayma_rtm.py index 350a4b74d..02a3afe42 100755 --- a/artiq/gateware/targets/sayma_rtm.py +++ b/artiq/gateware/targets/sayma_rtm.py @@ -21,7 +21,6 @@ from artiq.gateware.drtio.transceiver import gtp_7series from artiq.gateware.drtio.siphaser import SiPhaser7Series from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer from artiq.gateware.drtio import * -from artiq.gateware import jesd204_tools from artiq.build_soc import add_identifier from artiq import __artiq_dir__ as artiq_dir @@ -216,12 +215,6 @@ class Satellite(_SatelliteBase): platform.request("hmc7043_out_en")) self.csr_devices.append("hmc7043_out_en") - # DDMTD - # https://github.com/sinara-hw/Sayma_RTM/issues/68 - sysref_pads = platform.request("rtm_fpga_sysref", 1) # use odd-numbered 7043 output - self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(sysref_pads, self.rtio_clk_freq) - self.csr_devices.append("sysref_ddmtd") - class SatmanSoCBuilder(Builder): def __init__(self, *args, **kwargs):