mirror of https://github.com/m-labs/artiq.git
drtio: resync SYSREF when TSC is loaded
This commit is contained in:
parent
5a2a857a2f
commit
e29536351d
|
@ -56,6 +56,11 @@ mod moninj;
|
||||||
#[cfg(has_rtio_analyzer)]
|
#[cfg(has_rtio_analyzer)]
|
||||||
mod analyzer;
|
mod analyzer;
|
||||||
|
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
const SYSREF_PHASE_FPGA: u16 = 32;
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
const SYSREF_PHASE_DAC: u16 = 61;
|
||||||
|
|
||||||
fn startup() {
|
fn startup() {
|
||||||
irq::set_mask(0);
|
irq::set_mask(0);
|
||||||
irq::set_ie(true);
|
irq::set_ie(true);
|
||||||
|
@ -109,7 +114,7 @@ fn startup() {
|
||||||
/* must be the first SPI init because of HMC830 SPI mode selection */
|
/* must be the first SPI init because of HMC830 SPI mode selection */
|
||||||
board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
||||||
#[cfg(has_ad9154)]
|
#[cfg(has_ad9154)]
|
||||||
board_artiq::ad9154::init(44, 61);
|
board_artiq::ad9154::init(SYSREF_PHASE_FPGA, SYSREF_PHASE_DAC);
|
||||||
#[cfg(has_allaki_atts)]
|
#[cfg(has_allaki_atts)]
|
||||||
board_artiq::hmc542::program_all(8/*=4dB*/);
|
board_artiq::hmc542::program_all(8/*=4dB*/);
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,16 @@ fn drtio_reset_phy(reset: bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn drtio_tsc_loaded() -> bool {
|
||||||
|
unsafe {
|
||||||
|
let tsc_loaded = (csr::DRTIO[0].tsc_loaded_read)() == 1;
|
||||||
|
if tsc_loaded {
|
||||||
|
(csr::DRTIO[0].tsc_loaded_write)(1);
|
||||||
|
}
|
||||||
|
tsc_loaded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn process_aux_packet(packet: drtioaux::Packet) -> Result<(), drtioaux::Error<!>> {
|
fn process_aux_packet(packet: drtioaux::Packet) -> Result<(), drtioaux::Error<!>> {
|
||||||
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
// In the code below, *_chan_sel_write takes an u8 if there are fewer than 256 channels,
|
||||||
// and u16 otherwise; hence the `as _` conversion.
|
// and u16 otherwise; hence the `as _` conversion.
|
||||||
|
@ -238,6 +248,12 @@ fn drtio_link_rx_up() -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SIPHASER_PHASE: u16 = 32;
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
const SYSREF_PHASE_FPGA: u16 = 32;
|
||||||
|
#[cfg(has_ad9154)]
|
||||||
|
const SYSREF_PHASE_DAC: u16 = 61;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn main() -> i32 {
|
pub extern fn main() -> i32 {
|
||||||
clock::init();
|
clock::init();
|
||||||
|
@ -262,7 +278,7 @@ pub extern fn main() -> i32 {
|
||||||
/* must be the first SPI init because of HMC830 SPI mode selection */
|
/* must be the first SPI init because of HMC830 SPI mode selection */
|
||||||
hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
hmc830_7043::init().expect("cannot initialize HMC830/7043");
|
||||||
#[cfg(has_ad9154)]
|
#[cfg(has_ad9154)]
|
||||||
board_artiq::ad9154::init(32, 61);
|
board_artiq::ad9154::init(SYSREF_PHASE_FPGA, SYSREF_PHASE_DAC);
|
||||||
#[cfg(has_allaki_atts)]
|
#[cfg(has_allaki_atts)]
|
||||||
board_artiq::hmc542::program_all(8/*=4dB*/);
|
board_artiq::hmc542::program_all(8/*=4dB*/);
|
||||||
|
|
||||||
|
@ -272,16 +288,23 @@ pub extern fn main() -> i32 {
|
||||||
}
|
}
|
||||||
info!("link is up, switching to recovered clock");
|
info!("link is up, switching to recovered clock");
|
||||||
si5324::siphaser::select_recovered_clock(true).expect("failed to switch clocks");
|
si5324::siphaser::select_recovered_clock(true).expect("failed to switch clocks");
|
||||||
si5324::siphaser::calibrate_skew(32).expect("failed to calibrate skew");
|
si5324::siphaser::calibrate_skew(SIPHASER_PHASE).expect("failed to calibrate skew");
|
||||||
drtioaux::reset(0);
|
drtioaux::reset(0);
|
||||||
drtio_reset(false);
|
drtio_reset(false);
|
||||||
drtio_reset_phy(false);
|
drtio_reset_phy(false);
|
||||||
while drtio_link_rx_up() {
|
while drtio_link_rx_up() {
|
||||||
process_errors();
|
process_errors();
|
||||||
process_aux_packets();
|
process_aux_packets();
|
||||||
|
#[cfg(has_hmc830_7043)]
|
||||||
|
{
|
||||||
|
if drtio_tsc_loaded() {
|
||||||
|
hmc830_7043::hmc7043::sysref_rtio_align(SYSREF_PHASE_FPGA);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
drtio_reset_phy(true);
|
drtio_reset_phy(true);
|
||||||
drtio_reset(true);
|
drtio_reset(true);
|
||||||
|
drtio_tsc_loaded();
|
||||||
info!("link is down, switching to local crystal clock");
|
info!("link is down, switching to local crystal clock");
|
||||||
si5324::siphaser::select_recovered_clock(false).expect("failed to switch clocks");
|
si5324::siphaser::select_recovered_clock(false).expect("failed to switch clocks");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ from types import SimpleNamespace
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
from migen.genlib.cdc import PulseSynchronizer
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
|
|
||||||
from artiq.gateware.rtio.sed.core import *
|
from artiq.gateware.rtio.sed.core import *
|
||||||
|
@ -34,6 +35,7 @@ class DRTIOSatellite(Module):
|
||||||
lane_count=8, fifo_depth=128):
|
lane_count=8, fifo_depth=128):
|
||||||
self.reset = CSRStorage(reset=1)
|
self.reset = CSRStorage(reset=1)
|
||||||
self.reset_phy = CSRStorage(reset=1)
|
self.reset_phy = CSRStorage(reset=1)
|
||||||
|
self.tsc_loaded = CSR()
|
||||||
|
|
||||||
self.clock_domains.cd_rio = ClockDomain()
|
self.clock_domains.cd_rio = ClockDomain()
|
||||||
self.clock_domains.cd_rio_phy = ClockDomain()
|
self.clock_domains.cd_rio_phy = ClockDomain()
|
||||||
|
@ -92,6 +94,14 @@ class DRTIOSatellite(Module):
|
||||||
self.comb += self.rt_packet.cri.counter.eq(coarse_ts << fine_ts_width)
|
self.comb += self.rt_packet.cri.counter.eq(coarse_ts << fine_ts_width)
|
||||||
self.coarse_ts = coarse_ts
|
self.coarse_ts = coarse_ts
|
||||||
|
|
||||||
|
ps_tsc_load = PulseSynchronizer("rtio", "sys")
|
||||||
|
self.submodules += ps_tsc_load
|
||||||
|
self.comb += ps_tsc_load.i.eq(self.rt_packet.tsc_load)
|
||||||
|
self.sync += [
|
||||||
|
If(self.tsc_loaded.re, self.tsc_loaded.w.eq(0)),
|
||||||
|
If(ps_tsc_load.o, self.tsc_loaded.w.eq(1))
|
||||||
|
]
|
||||||
|
|
||||||
self.submodules.outputs = ClockDomainsRenamer("rio")(
|
self.submodules.outputs = ClockDomainsRenamer("rio")(
|
||||||
SED(channels, fine_ts_width, "sync",
|
SED(channels, fine_ts_width, "sync",
|
||||||
lane_count=lane_count, fifo_depth=fifo_depth,
|
lane_count=lane_count, fifo_depth=fifo_depth,
|
||||||
|
@ -112,7 +122,7 @@ class DRTIOSatellite(Module):
|
||||||
self.link_layer)
|
self.link_layer)
|
||||||
|
|
||||||
def get_csrs(self):
|
def get_csrs(self):
|
||||||
return ([self.reset, self.reset_phy] +
|
return ([self.reset, self.reset_phy, self.tsc_loaded] +
|
||||||
self.link_layer.get_csrs() + self.link_stats.get_csrs() +
|
self.link_layer.get_csrs() + self.link_stats.get_csrs() +
|
||||||
self.rt_errors.get_csrs() + self.aux_controller.get_csrs())
|
self.rt_errors.get_csrs() + self.aux_controller.get_csrs())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue