forked from M-Labs/artiq
make RTIO clock switch optional and simplify
Kasli no longer has an internal RTIO clock. Switching clocks dynamically is no longer supported.
This commit is contained in:
parent
8a988d0feb
commit
b10d3ee4b4
|
@ -35,6 +35,8 @@ ARTIQ-4
|
||||||
* ``artiq.coredevice.dds`` has been renamed to ``artiq.coredevice.ad9914`` and
|
* ``artiq.coredevice.dds`` has been renamed to ``artiq.coredevice.ad9914`` and
|
||||||
simplified. DDS batch mode is no longer supported. The ``core_dds`` device
|
simplified. DDS batch mode is no longer supported. The ``core_dds`` device
|
||||||
is no longer necessary.
|
is no longer necessary.
|
||||||
|
* The configuration entry ``startup_clock`` is renamed ``rtio_clock``. Switching
|
||||||
|
clocks dynamically (i.e. without device restart) is no longer supported.
|
||||||
|
|
||||||
|
|
||||||
ARTIQ-3
|
ARTIQ-3
|
||||||
|
|
|
@ -16,7 +16,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Request(Enum):
|
class Request(Enum):
|
||||||
SystemInfo = 3
|
SystemInfo = 3
|
||||||
SwitchClock = 4
|
|
||||||
|
|
||||||
LoadKernel = 5
|
LoadKernel = 5
|
||||||
RunKernel = 6
|
RunKernel = 6
|
||||||
|
@ -27,8 +26,6 @@ class Request(Enum):
|
||||||
|
|
||||||
class Reply(Enum):
|
class Reply(Enum):
|
||||||
SystemInfo = 2
|
SystemInfo = 2
|
||||||
ClockSwitchCompleted = 3
|
|
||||||
ClockSwitchFailed = 4
|
|
||||||
|
|
||||||
LoadCompleted = 5
|
LoadCompleted = 5
|
||||||
LoadFailed = 6
|
LoadFailed = 6
|
||||||
|
@ -60,9 +57,6 @@ class CommKernelDummy:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def switch_clock(self, external):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def load(self, kernel_library):
|
def load(self, kernel_library):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -237,12 +231,6 @@ class CommKernel:
|
||||||
if not finished_cleanly:
|
if not finished_cleanly:
|
||||||
logger.warning("Previous kernel did not cleanly finish")
|
logger.warning("Previous kernel did not cleanly finish")
|
||||||
|
|
||||||
def switch_clock(self, external):
|
|
||||||
self._write_header(Request.SwitchClock)
|
|
||||||
self._write_int8(external)
|
|
||||||
|
|
||||||
self._read_empty(Reply.ClockSwitchCompleted)
|
|
||||||
|
|
||||||
def load(self, kernel_library):
|
def load(self, kernel_library):
|
||||||
self._write_header(Request.LoadKernel)
|
self._write_header(Request.LoadKernel)
|
||||||
self._write_bytes(kernel_library)
|
self._write_bytes(kernel_library)
|
||||||
|
|
|
@ -62,8 +62,6 @@ class Core:
|
||||||
clocked at 125MHz and a SERDES multiplication factor of 8, the
|
clocked at 125MHz and a SERDES multiplication factor of 8, the
|
||||||
reference period is 1ns.
|
reference period is 1ns.
|
||||||
The time machine unit is equal to this period.
|
The time machine unit is equal to this period.
|
||||||
:param external_clock: whether the core device should switch to its
|
|
||||||
external RTIO clock input instead of using its internal oscillator.
|
|
||||||
:param ref_multiplier: ratio between the RTIO fine timestamp frequency
|
:param ref_multiplier: ratio between the RTIO fine timestamp frequency
|
||||||
and the RTIO coarse timestamp frequency (e.g. SERDES multiplication
|
and the RTIO coarse timestamp frequency (e.g. SERDES multiplication
|
||||||
factor).
|
factor).
|
||||||
|
@ -71,13 +69,10 @@ class Core:
|
||||||
|
|
||||||
kernel_invariants = {
|
kernel_invariants = {
|
||||||
"core", "ref_period", "coarse_ref_period", "ref_multiplier",
|
"core", "ref_period", "coarse_ref_period", "ref_multiplier",
|
||||||
"external_clock",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, dmgr, host, ref_period, external_clock=False,
|
def __init__(self, dmgr, host, ref_period, ref_multiplier=8):
|
||||||
ref_multiplier=8):
|
|
||||||
self.ref_period = ref_period
|
self.ref_period = ref_period
|
||||||
self.external_clock = external_clock
|
|
||||||
self.ref_multiplier = ref_multiplier
|
self.ref_multiplier = ref_multiplier
|
||||||
self.coarse_ref_period = ref_period*ref_multiplier
|
self.coarse_ref_period = ref_period*ref_multiplier
|
||||||
if host is None:
|
if host is None:
|
||||||
|
@ -129,7 +124,6 @@ class Core:
|
||||||
|
|
||||||
if self.first_run:
|
if self.first_run:
|
||||||
self.comm.check_system_info()
|
self.comm.check_system_info()
|
||||||
self.comm.switch_clock(self.external_clock)
|
|
||||||
self.first_run = False
|
self.first_run = False
|
||||||
|
|
||||||
self.comm.load(kernel_library)
|
self.comm.load(kernel_library)
|
||||||
|
|
|
@ -64,7 +64,6 @@ fn write_sync<W>(writer: &mut W) -> Result<(), IoError<W::WriteError>>
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Request {
|
pub enum Request {
|
||||||
SystemInfo,
|
SystemInfo,
|
||||||
SwitchClock(u8),
|
|
||||||
|
|
||||||
LoadKernel(Vec<u8>),
|
LoadKernel(Vec<u8>),
|
||||||
RunKernel,
|
RunKernel,
|
||||||
|
@ -87,8 +86,6 @@ pub enum Reply<'a> {
|
||||||
ident: &'a str,
|
ident: &'a str,
|
||||||
finished_cleanly: bool
|
finished_cleanly: bool
|
||||||
},
|
},
|
||||||
ClockSwitchCompleted,
|
|
||||||
ClockSwitchFailed,
|
|
||||||
|
|
||||||
LoadCompleted,
|
LoadCompleted,
|
||||||
LoadFailed(&'a str),
|
LoadFailed(&'a str),
|
||||||
|
@ -118,10 +115,7 @@ impl Request {
|
||||||
{
|
{
|
||||||
read_sync(reader)?;
|
read_sync(reader)?;
|
||||||
Ok(match reader.read_u8()? {
|
Ok(match reader.read_u8()? {
|
||||||
// 1-2, 13 were log requests
|
|
||||||
|
|
||||||
3 => Request::SystemInfo,
|
3 => Request::SystemInfo,
|
||||||
4 => Request::SwitchClock(reader.read_u8()?),
|
|
||||||
|
|
||||||
5 => Request::LoadKernel(reader.read_bytes()?),
|
5 => Request::LoadKernel(reader.read_bytes()?),
|
||||||
6 => Request::RunKernel,
|
6 => Request::RunKernel,
|
||||||
|
@ -141,10 +135,6 @@ impl Request {
|
||||||
function: reader.read_string()?
|
function: reader.read_string()?
|
||||||
},
|
},
|
||||||
|
|
||||||
// 9-12 were flash requests
|
|
||||||
|
|
||||||
// 14 was hotswap request
|
|
||||||
|
|
||||||
ty => return Err(Error::UnknownPacket(ty))
|
ty => return Err(Error::UnknownPacket(ty))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -156,20 +146,12 @@ impl<'a> Reply<'a> {
|
||||||
{
|
{
|
||||||
write_sync(writer)?;
|
write_sync(writer)?;
|
||||||
match *self {
|
match *self {
|
||||||
// 1 was log reply
|
|
||||||
|
|
||||||
Reply::SystemInfo { ident, finished_cleanly } => {
|
Reply::SystemInfo { ident, finished_cleanly } => {
|
||||||
writer.write_u8(2)?;
|
writer.write_u8(2)?;
|
||||||
writer.write(b"AROR")?;
|
writer.write(b"AROR")?;
|
||||||
writer.write_string(ident)?;
|
writer.write_string(ident)?;
|
||||||
writer.write_u8(finished_cleanly as u8)?;
|
writer.write_u8(finished_cleanly as u8)?;
|
||||||
},
|
},
|
||||||
Reply::ClockSwitchCompleted => {
|
|
||||||
writer.write_u8(3)?;
|
|
||||||
},
|
|
||||||
Reply::ClockSwitchFailed => {
|
|
||||||
writer.write_u8(4)?;
|
|
||||||
},
|
|
||||||
|
|
||||||
Reply::LoadCompleted => {
|
Reply::LoadCompleted => {
|
||||||
writer.write_u8(5)?;
|
writer.write_u8(5)?;
|
||||||
|
@ -209,16 +191,12 @@ impl<'a> Reply<'a> {
|
||||||
writer.write_u8(async as u8)?;
|
writer.write_u8(async as u8)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 11-13 were flash requests
|
|
||||||
|
|
||||||
Reply::WatchdogExpired => {
|
Reply::WatchdogExpired => {
|
||||||
writer.write_u8(14)?;
|
writer.write_u8(14)?;
|
||||||
},
|
},
|
||||||
Reply::ClockFailure => {
|
Reply::ClockFailure => {
|
||||||
writer.write_u8(15)?;
|
writer.write_u8(15)?;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 16 was hotswap imminent reply
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,32 @@
|
||||||
use board_misoc::{csr, config};
|
use board_misoc::csr;
|
||||||
|
#[cfg(has_rtio_clock_switch)]
|
||||||
|
use board_misoc::config;
|
||||||
use sched::Io;
|
use sched::Io;
|
||||||
|
|
||||||
#[cfg(has_rtio_crg)]
|
#[cfg(has_rtio_crg)]
|
||||||
pub mod crg {
|
pub mod crg {
|
||||||
use board_misoc::{clock, csr};
|
use board_misoc::{clock, csr};
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
unsafe { csr::rtio_crg::pll_reset_write(0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check() -> bool {
|
pub fn check() -> bool {
|
||||||
unsafe { csr::rtio_crg::pll_locked_read() != 0 }
|
unsafe { csr::rtio_crg::pll_locked_read() != 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn switch_clock(clk: u8) -> bool {
|
#[cfg(has_rtio_clock_switch)]
|
||||||
|
pub fn init(clk: u8) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
let cur_clk = csr::rtio_crg::clock_sel_read();
|
csr::rtio_crg::pll_reset_write(1);
|
||||||
if clk != cur_clk {
|
csr::rtio_crg::clock_sel_write(clk);
|
||||||
csr::rtio_crg::pll_reset_write(1);
|
csr::rtio_crg::pll_reset_write(0);
|
||||||
csr::rtio_crg::clock_sel_write(clk);
|
|
||||||
csr::rtio_crg::pll_reset_write(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
clock::spin_us(150);
|
||||||
|
return check()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(has_rtio_clock_switch))]
|
||||||
|
pub fn init() -> bool {
|
||||||
|
unsafe {
|
||||||
|
csr::rtio_crg::pll_reset_write(0);
|
||||||
|
}
|
||||||
clock::spin_us(150);
|
clock::spin_us(150);
|
||||||
return check()
|
return check()
|
||||||
}
|
}
|
||||||
|
@ -30,9 +34,7 @@ pub mod crg {
|
||||||
|
|
||||||
#[cfg(not(has_rtio_crg))]
|
#[cfg(not(has_rtio_crg))]
|
||||||
pub mod crg {
|
pub mod crg {
|
||||||
pub fn init() {}
|
|
||||||
pub fn check() -> bool { true }
|
pub fn check() -> bool { true }
|
||||||
pub fn switch_clock(_clk: u8) -> bool { true }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
@ -227,40 +229,43 @@ fn async_error_thread(io: Io) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn startup(io: &Io) {
|
pub fn startup(io: &Io) {
|
||||||
crg::init();
|
#[cfg(has_rtio_crg)]
|
||||||
|
{
|
||||||
|
#[cfg(has_rtio_clock_switch)]
|
||||||
|
{
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum RtioClock {
|
||||||
|
Internal = 0,
|
||||||
|
External = 1
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
let clk = config::read("rtio_clock", |result| {
|
||||||
enum RtioClock {
|
match result {
|
||||||
Internal = 0,
|
Ok(b"i") => {
|
||||||
External = 1
|
info!("using internal RTIO clock");
|
||||||
};
|
RtioClock::Internal
|
||||||
|
},
|
||||||
|
Ok(b"e") => {
|
||||||
|
info!("using external RTIO clock");
|
||||||
|
RtioClock::External
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
info!("using internal RTIO clock (by default)");
|
||||||
|
RtioClock::Internal
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let clk = config::read("startup_clock", |result| {
|
if !crg::init(clk as u8) {
|
||||||
match result {
|
error!("RTIO clock failed");
|
||||||
Ok(b"i") => {
|
}
|
||||||
info!("using internal startup RTIO clock");
|
}
|
||||||
RtioClock::Internal
|
#[cfg(not(has_rtio_clock_switch))]
|
||||||
},
|
{
|
||||||
Ok(b"e") => {
|
if !crg::init() {
|
||||||
info!("using external startup RTIO clock");
|
error!("RTIO clock failed");
|
||||||
RtioClock::External
|
|
||||||
},
|
|
||||||
Err(_) => {
|
|
||||||
info!("using internal startup RTIO clock (by default)");
|
|
||||||
RtioClock::Internal
|
|
||||||
},
|
|
||||||
Ok(_) => {
|
|
||||||
error!("unrecognized startup_clock configuration entry, \
|
|
||||||
using internal RTIO clock");
|
|
||||||
RtioClock::Internal
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if !crg::switch_clock(clk as u8) {
|
|
||||||
error!("startup RTIO clock failed");
|
|
||||||
warn!("this may cause the system initialization to fail");
|
|
||||||
warn!("fix clocking and reset the device");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drtio::startup(io);
|
drtio::startup(io);
|
||||||
|
|
|
@ -250,24 +250,6 @@ fn process_host_message(io: &Io,
|
||||||
session.congress.finished_cleanly.set(true)
|
session.congress.finished_cleanly.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
host::Request::SwitchClock(clk) => {
|
|
||||||
if session.running() {
|
|
||||||
unexpected!("attempted to switch RTIO clock while a kernel was running")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(has_rtio_core)]
|
|
||||||
{
|
|
||||||
if rtio_mgt::crg::switch_clock(clk) {
|
|
||||||
host_write(stream, host::Reply::ClockSwitchCompleted)?;
|
|
||||||
} else {
|
|
||||||
host_write(stream, host::Reply::ClockSwitchFailed)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(has_rtio_core))]
|
|
||||||
host_write(stream, host::Reply::ClockSwitchFailed)?
|
|
||||||
}
|
|
||||||
|
|
||||||
host::Request::LoadKernel(kernel) =>
|
host::Request::LoadKernel(kernel) =>
|
||||||
match unsafe { kern_load(io, session, &kernel) } {
|
match unsafe { kern_load(io, session, &kernel) } {
|
||||||
Ok(()) => host_write(stream, host::Reply::LoadCompleted)?,
|
Ok(()) => host_write(stream, host::Reply::LoadCompleted)?,
|
||||||
|
|
|
@ -29,25 +29,22 @@ from artiq import __version__ as artiq_version
|
||||||
|
|
||||||
|
|
||||||
class _RTIOCRG(Module, AutoCSR):
|
class _RTIOCRG(Module, AutoCSR):
|
||||||
def __init__(self, platform, rtio_internal_clk):
|
def __init__(self, platform):
|
||||||
self._clock_sel = CSRStorage()
|
|
||||||
self._pll_reset = CSRStorage(reset=1)
|
self._pll_reset = CSRStorage(reset=1)
|
||||||
self._pll_locked = CSRStatus()
|
self._pll_locked = CSRStatus()
|
||||||
self.clock_domains.cd_rtio = ClockDomain()
|
self.clock_domains.cd_rtio = ClockDomain()
|
||||||
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
||||||
|
|
||||||
rtio_external_clk = Signal()
|
|
||||||
clk_synth_se = Signal()
|
|
||||||
clk_synth = platform.request("si5324_clkout_fabric")
|
clk_synth = platform.request("si5324_clkout_fabric")
|
||||||
|
clk_synth_se = Signal()
|
||||||
|
clk_synth_buffered = Signal()
|
||||||
platform.add_period_constraint(clk_synth.p, 8.0)
|
platform.add_period_constraint(clk_synth.p, 8.0)
|
||||||
self.specials += [
|
self.specials += [
|
||||||
Instance("IBUFGDS",
|
Instance("IBUFGDS",
|
||||||
p_DIFF_TERM="TRUE", p_IBUF_LOW_PWR="TRUE",
|
p_DIFF_TERM="TRUE", p_IBUF_LOW_PWR="TRUE",
|
||||||
i_I=clk_synth.p, i_IB=clk_synth.n, o_O=clk_synth_se),
|
i_I=clk_synth.p, i_IB=clk_synth.n, o_O=clk_synth_se),
|
||||||
Instance("BUFG", i_I=clk_synth_se, o_O=rtio_external_clk),
|
Instance("BUFG", i_I=clk_synth_se, o_O=clk_synth_buffered),
|
||||||
]
|
]
|
||||||
platform.add_false_path_constraints(
|
|
||||||
rtio_external_clk, rtio_internal_clk)
|
|
||||||
|
|
||||||
pll_locked = Signal()
|
pll_locked = Signal()
|
||||||
rtio_clk = Signal()
|
rtio_clk = Signal()
|
||||||
|
@ -59,9 +56,9 @@ class _RTIOCRG(Module, AutoCSR):
|
||||||
|
|
||||||
p_REF_JITTER1=0.01,
|
p_REF_JITTER1=0.01,
|
||||||
p_CLKIN1_PERIOD=8.0, p_CLKIN2_PERIOD=8.0,
|
p_CLKIN1_PERIOD=8.0, p_CLKIN2_PERIOD=8.0,
|
||||||
i_CLKIN1=rtio_internal_clk, i_CLKIN2=rtio_external_clk,
|
i_CLKIN2=clk_synth_buffered,
|
||||||
# Warning: CLKINSEL=0 means CLKIN2 is selected
|
# Warning: CLKINSEL=0 means CLKIN2 is selected
|
||||||
i_CLKINSEL=~self._clock_sel.storage,
|
i_CLKINSEL=0,
|
||||||
|
|
||||||
# VCO @ 1GHz when using 125MHz input
|
# VCO @ 1GHz when using 125MHz input
|
||||||
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
|
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
|
||||||
|
@ -123,7 +120,7 @@ class _StandaloneBase(MiniSoC, AMPSoC):
|
||||||
self.config["SI5324_SOFT_RESET"] = None
|
self.config["SI5324_SOFT_RESET"] = None
|
||||||
|
|
||||||
def add_rtio(self, rtio_channels):
|
def add_rtio(self, rtio_channels):
|
||||||
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
|
self.submodules.rtio_crg = _RTIOCRG(self.platform)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
fix_serdes_timing_path(self.platform)
|
fix_serdes_timing_path(self.platform)
|
||||||
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
||||||
|
|
|
@ -256,6 +256,7 @@ class _StandaloneBase(MiniSoC, AMPSoC):
|
||||||
def add_rtio(self, rtio_channels):
|
def add_rtio(self, rtio_channels):
|
||||||
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
|
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
|
self.config["HAS_RTIO_CLOCK_SWITCH"] = None
|
||||||
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
||||||
self.csr_devices.append("rtio_core")
|
self.csr_devices.append("rtio_core")
|
||||||
self.submodules.rtio = rtio.KernelInitiator()
|
self.submodules.rtio = rtio.KernelInitiator()
|
||||||
|
@ -502,6 +503,7 @@ class SMA_SPI(_StandaloneBase):
|
||||||
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk,
|
self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk,
|
||||||
use_sma=False)
|
use_sma=False)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
|
self.config["HAS_RTIO_CLOCK_SWITCH"] = None
|
||||||
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
self.submodules.rtio_core = rtio.Core(rtio_channels)
|
||||||
self.csr_devices.append("rtio_core")
|
self.csr_devices.append("rtio_core")
|
||||||
self.submodules.rtio = rtio.KernelInitiator()
|
self.submodules.rtio = rtio.KernelInitiator()
|
||||||
|
|
|
@ -159,6 +159,11 @@ To avoid I/O contention, the startup kernel should first program the TCA6424A ex
|
||||||
|
|
||||||
See :mod:`artiq.coredevice.i2c` for more details.
|
See :mod:`artiq.coredevice.i2c` for more details.
|
||||||
|
|
||||||
|
Clocking
|
||||||
|
++++++++
|
||||||
|
|
||||||
|
The KC705 supports an internal 125MHz RTIO clock (based on its crystal oscillator) and an external clock, that can be selected using the ``rtio_clock`` configuration entry.
|
||||||
|
|
||||||
Kasli
|
Kasli
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
|
@ -189,12 +189,12 @@ The startup kernel is executed once when the core device powers up. It should in
|
||||||
|
|
||||||
For DRTIO systems, the startup kernel should wait until the desired links are up, using :meth:`artiq.coredevice.Core.get_drtio_link_status`.
|
For DRTIO systems, the startup kernel should wait until the desired links are up, using :meth:`artiq.coredevice.Core.get_drtio_link_status`.
|
||||||
|
|
||||||
* (optional) Select the startup clock
|
* (optional) Select the RTIO clock source
|
||||||
|
|
||||||
The core device may use either an external clock signal or its internal clock. This clock can be switched dynamically after the PC is connected using the ``external_clock`` parameter of the core device driver; however, one may want to select the clock at power-up so that it is used for the startup and idle kernels. Use one of these commands: ::
|
Some core devices may use either an external clock signal or their internal clock. The clock is selected at power-up. Use one of these commands: ::
|
||||||
|
|
||||||
$ artiq_coreconfig write -s startup_clock i # internal clock (default)
|
$ artiq_coreconfig write -s rtio_clock i # internal clock (default)
|
||||||
$ artiq_coreconfig write -s startup_clock e # external clock
|
$ artiq_coreconfig write -s rtio_clock e # external clock
|
||||||
|
|
||||||
|
|
||||||
.. rubric:: Footnotes
|
.. rubric:: Footnotes
|
||||||
|
|
Loading…
Reference in New Issue