mirror of https://github.com/m-labs/artiq.git
support for multiple DDS buses (untested)
This commit is contained in:
parent
9d1903a4e2
commit
f0b0b1bac7
|
@ -11,4 +11,8 @@ Release notes
|
||||||
This requires reflashing the runtime and the flash storage filesystem image
|
This requires reflashing the runtime and the flash storage filesystem image
|
||||||
or erase and rewrite its entries.
|
or erase and rewrite its entries.
|
||||||
* RTIOCollisionError has been renamed to RTIOCollision
|
* RTIOCollisionError has been renamed to RTIOCollision
|
||||||
|
* the new API for DDS batches is:
|
||||||
|
with self.core_dds.batch:
|
||||||
|
...
|
||||||
|
with core_dds a device of type artiq.coredevice.dds.CoreDDS.
|
||||||
|
The dds_bus device should not be used anymore.
|
||||||
|
|
|
@ -40,16 +40,19 @@ def decode_message(data):
|
||||||
|
|
||||||
|
|
||||||
DecodedDump = namedtuple(
|
DecodedDump = namedtuple(
|
||||||
"DecodedDump", "log_channel dds_channel dds_onehot_sel messages")
|
"DecodedDump", "log_channel dds_onehot_sel messages")
|
||||||
|
|
||||||
|
|
||||||
def decode_dump(data):
|
def decode_dump(data):
|
||||||
parts = struct.unpack(">IQbbbb", data[:16])
|
parts = struct.unpack(">IQbbb", data[:15])
|
||||||
(sent_bytes, total_byte_count,
|
(sent_bytes, total_byte_count,
|
||||||
overflow_occured, log_channel, dds_channel, dds_onehot_sel) = parts
|
overflow_occured, log_channel, dds_onehot_sel) = parts
|
||||||
|
|
||||||
if sent_bytes + 16 != len(data):
|
expected_len = sent_bytes + 15
|
||||||
raise ValueError("analyzer dump has incorrect length")
|
if expected_len != len(data):
|
||||||
|
raise ValueError("analyzer dump has incorrect length "
|
||||||
|
"(got {}, expected {})".format(
|
||||||
|
len(data), expected_len))
|
||||||
if overflow_occured:
|
if overflow_occured:
|
||||||
logger.warning("analyzer FIFO overflow occured, "
|
logger.warning("analyzer FIFO overflow occured, "
|
||||||
"some messages have been lost")
|
"some messages have been lost")
|
||||||
|
@ -57,14 +60,12 @@ def decode_dump(data):
|
||||||
logger.info("analyzer ring buffer has wrapped %d times",
|
logger.info("analyzer ring buffer has wrapped %d times",
|
||||||
total_byte_count//sent_bytes)
|
total_byte_count//sent_bytes)
|
||||||
|
|
||||||
position = 16
|
position = 15
|
||||||
messages = []
|
messages = []
|
||||||
for _ in range(sent_bytes//32):
|
for _ in range(sent_bytes//32):
|
||||||
messages.append(decode_message(data[position:position+32]))
|
messages.append(decode_message(data[position:position+32]))
|
||||||
position += 32
|
position += 32
|
||||||
return DecodedDump(log_channel,
|
return DecodedDump(log_channel, bool(dds_onehot_sel), messages)
|
||||||
dds_channel, bool(dds_onehot_sel),
|
|
||||||
messages)
|
|
||||||
|
|
||||||
|
|
||||||
def vcd_codes():
|
def vcd_codes():
|
||||||
|
@ -299,21 +300,31 @@ def get_vcd_log_channels(log_channel, messages):
|
||||||
return vcd_log_channels
|
return vcd_log_channels
|
||||||
|
|
||||||
|
|
||||||
def get_ref_period(devices):
|
def get_single_device_argument(devices, module, cls, argument):
|
||||||
ref_period = None
|
ref_period = None
|
||||||
for desc in devices.values():
|
for desc in devices.values():
|
||||||
if isinstance(desc, dict) and desc["type"] == "local":
|
if isinstance(desc, dict) and desc["type"] == "local":
|
||||||
if (desc["module"] == "artiq.coredevice.core"
|
if (desc["module"] == module
|
||||||
and desc["class"] == "Core"):
|
and desc["class"] == cls):
|
||||||
if ref_period is None:
|
if ref_period is None:
|
||||||
ref_period = desc["arguments"]["ref_period"]
|
ref_period = desc["arguments"][argument]
|
||||||
else:
|
else:
|
||||||
return None # more than one core device found
|
return None # more than one device found
|
||||||
return ref_period
|
return ref_period
|
||||||
|
|
||||||
|
|
||||||
|
def get_ref_period(devices):
|
||||||
|
return get_single_device_argument(devices, "artiq.coredevice.core",
|
||||||
|
"Core", "ref_period")
|
||||||
|
|
||||||
|
|
||||||
|
def get_dds_sysclk(devices):
|
||||||
|
return get_single_device_argument(devices, "artiq.coredevice.core",
|
||||||
|
"CoreDDS", "sysclk")
|
||||||
|
|
||||||
|
|
||||||
def create_channel_handlers(vcd_manager, devices, ref_period,
|
def create_channel_handlers(vcd_manager, devices, ref_period,
|
||||||
dds_channel, dds_onehot_sel):
|
dds_sysclk, dds_onehot_sel):
|
||||||
channel_handlers = dict()
|
channel_handlers = dict()
|
||||||
for name, desc in sorted(devices.items(), key=itemgetter(0)):
|
for name, desc in sorted(devices.items(), key=itemgetter(0)):
|
||||||
if isinstance(desc, dict) and desc["type"] == "local":
|
if isinstance(desc, dict) and desc["type"] == "local":
|
||||||
|
@ -327,19 +338,17 @@ def create_channel_handlers(vcd_manager, devices, ref_period,
|
||||||
channel_handlers[channel] = TTLClockGenHandler(vcd_manager, name, ref_period)
|
channel_handlers[channel] = TTLClockGenHandler(vcd_manager, name, ref_period)
|
||||||
if (desc["module"] == "artiq.coredevice.dds"
|
if (desc["module"] == "artiq.coredevice.dds"
|
||||||
and desc["class"] in {"AD9858", "AD9914"}):
|
and desc["class"] in {"AD9858", "AD9914"}):
|
||||||
sysclk = desc["arguments"]["sysclk"]
|
dds_bus_channel = desc["arguments"]["bus_channel"]
|
||||||
dds_channel_ddsbus = desc["arguments"]["channel"]
|
dds_channel = desc["arguments"]["channel"]
|
||||||
if dds_channel in channel_handlers:
|
if dds_bus_channel in channel_handlers:
|
||||||
dds_handler = channel_handlers[dds_channel]
|
dds_handler = channel_handlers[dds_bus_channel]
|
||||||
if dds_handler.dds_type != desc["class"]:
|
if dds_handler.dds_type != desc["class"]:
|
||||||
raise ValueError("All DDS channels must have the same type")
|
raise ValueError("All DDS channels must have the same type")
|
||||||
if dds_handler.sysclk != sysclk:
|
|
||||||
raise ValueError("All DDS channels must have the same sysclk")
|
|
||||||
else:
|
else:
|
||||||
dds_handler = DDSHandler(vcd_manager, desc["class"],
|
dds_handler = DDSHandler(vcd_manager, desc["class"],
|
||||||
dds_onehot_sel, sysclk)
|
dds_sysclk, dds_onehot_sel)
|
||||||
channel_handlers[dds_channel] = dds_handler
|
channel_handlers[dds_bus_channel] = dds_handler
|
||||||
dds_handler.add_dds_channel(name, dds_channel_ddsbus)
|
dds_handler.add_dds_channel(name, dds_channel)
|
||||||
return channel_handlers
|
return channel_handlers
|
||||||
|
|
||||||
|
|
||||||
|
@ -355,12 +364,16 @@ def decoded_dump_to_vcd(fileobj, devices, dump):
|
||||||
else:
|
else:
|
||||||
logger.warning("unable to determine core device ref_period")
|
logger.warning("unable to determine core device ref_period")
|
||||||
ref_period = 1e-9 # guess
|
ref_period = 1e-9 # guess
|
||||||
|
dds_sysclk = get_dds_sysclk(devices)
|
||||||
|
if dds_sysclk is None:
|
||||||
|
logger.warning("unable to determine DDS sysclk")
|
||||||
|
dds_sysclk = 3e9 # guess
|
||||||
|
|
||||||
messages = sorted(dump.messages, key=get_message_time)
|
messages = sorted(dump.messages, key=get_message_time)
|
||||||
|
|
||||||
channel_handlers = create_channel_handlers(
|
channel_handlers = create_channel_handlers(
|
||||||
vcd_manager, devices, ref_period,
|
vcd_manager, devices, ref_period,
|
||||||
dump.dds_channel, dump.dds_onehot_sel)
|
dds_sysclk, dump.dds_onehot_sel)
|
||||||
vcd_log_channels = get_vcd_log_channels(dump.log_channel, messages)
|
vcd_log_channels = get_vcd_log_channels(dump.log_channel, messages)
|
||||||
channel_handlers[dump.log_channel] = LogHandler(vcd_manager, vcd_log_channels)
|
channel_handlers[dump.log_channel] = LogHandler(vcd_manager, vcd_log_channels)
|
||||||
slack = vcd_manager.get_channel("rtio_slack", 64)
|
slack = vcd_manager.get_channel("rtio_slack", 64)
|
||||||
|
|
|
@ -22,7 +22,7 @@ def _render_diagnostic(diagnostic, colored):
|
||||||
lines = [shorten_path(path) for path in diagnostic.render(colored=colored)]
|
lines = [shorten_path(path) for path in diagnostic.render(colored=colored)]
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
colors_supported = (os.name == 'posix')
|
colors_supported = os.name == "posix"
|
||||||
class _DiagnosticEngine(diagnostic.Engine):
|
class _DiagnosticEngine(diagnostic.Engine):
|
||||||
def render_diagnostic(self, diagnostic):
|
def render_diagnostic(self, diagnostic):
|
||||||
sys.stderr.write(_render_diagnostic(diagnostic, colored=colors_supported) + "\n")
|
sys.stderr.write(_render_diagnostic(diagnostic, colored=colors_supported) + "\n")
|
||||||
|
@ -49,6 +49,7 @@ def cache_get(key: TStr) -> TList(TInt32):
|
||||||
def cache_put(key: TStr, value: TList(TInt32)) -> TNone:
|
def cache_put(key: TStr, value: TList(TInt32)) -> TNone:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
"""Core device driver.
|
"""Core device driver.
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,12 @@ PHASE_MODE_TRACKING = 2
|
||||||
|
|
||||||
|
|
||||||
@syscall
|
@syscall
|
||||||
def dds_init(time_mu: TInt64, channel: TInt32) -> TNone:
|
def dds_init(time_mu: TInt64, bus_channel: TInt32, channel: TInt32) -> TNone:
|
||||||
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
@syscall
|
||||||
|
def dds_set(time_mu: TInt64, bus_channel: TInt32, channel: TInt32, ftw: TInt32,
|
||||||
|
pow: TInt32, phase_mode: TInt32, amplitude: TInt32) -> TNone:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
@syscall
|
@syscall
|
||||||
|
@ -22,35 +27,36 @@ def dds_batch_enter(time_mu: TInt64) -> TNone:
|
||||||
def dds_batch_exit() -> TNone:
|
def dds_batch_exit() -> TNone:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
@syscall
|
|
||||||
def dds_set(time_mu: TInt64, channel: TInt32, ftw: TInt32,
|
|
||||||
pow: TInt32, phase_mode: TInt32, amplitude: TInt32) -> TNone:
|
|
||||||
raise NotImplementedError("syscall not simulated")
|
|
||||||
|
|
||||||
|
|
||||||
class _BatchContextManager:
|
class _BatchContextManager:
|
||||||
def __init__(self, dds_bus):
|
def __init__(self, core_dds):
|
||||||
self.dds_bus = dds_bus
|
self.core_dds = core_dds
|
||||||
|
self.core = self.core_dds.core
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self.dds_bus.batch_enter()
|
self.core_dds.dds_batch_enter()
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def __exit__(self, type, value, traceback):
|
def __exit__(self, type, value, traceback):
|
||||||
self.dds_bus.batch_exit()
|
self.core_dds.dds_batch_exit()
|
||||||
|
|
||||||
|
|
||||||
class DDSBus:
|
class CoreDDS:
|
||||||
"""Core device Direct Digital Synthesis (DDS) bus batching driver.
|
"""Core device Direct Digital Synthesis (DDS) driver.
|
||||||
|
|
||||||
Manages batching of DDS commands on a DDS shared bus."""
|
Gives access to the DDS functionality of the core device.
|
||||||
def __init__(self, dmgr):
|
|
||||||
self.core = dmgr.get("core")
|
:param sysclk: DDS system frequency. The DDS system clock must be a
|
||||||
|
phase-locked multiple of the RTIO clock.
|
||||||
|
"""
|
||||||
|
def __init__(self, dmgr, sysclk, core_device="core"):
|
||||||
|
self.core = dmgr.get(core_device)
|
||||||
|
self.sysclk = sysclk
|
||||||
self.batch = _BatchContextManager(self)
|
self.batch = _BatchContextManager(self)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def batch_enter(self):
|
def dds_batch_enter(self):
|
||||||
"""Starts a DDS command batch. All DDS commands are buffered
|
"""Starts a DDS command batch. All DDS commands are buffered
|
||||||
after this call, until ``batch_exit`` is called.
|
after this call, until ``batch_exit`` is called.
|
||||||
|
|
||||||
|
@ -59,26 +65,27 @@ class DDSBus:
|
||||||
dds_batch_enter(now_mu())
|
dds_batch_enter(now_mu())
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def batch_exit(self):
|
def dds_batch_exit(self):
|
||||||
"""Ends a DDS command batch. All buffered DDS commands are issued
|
"""Ends a DDS command batch. All buffered DDS commands are issued
|
||||||
on the bus."""
|
on the bus."""
|
||||||
dds_batch_exit()
|
dds_batch_exit()
|
||||||
|
|
||||||
|
|
||||||
class _DDSGeneric:
|
class _DDSGeneric:
|
||||||
"""Core device Direct Digital Synthesis (DDS) driver.
|
"""Core device Direct Digital Synthesis (DDS) channel driver.
|
||||||
|
|
||||||
Controls one DDS channel managed directly by the core device's runtime.
|
Controls one DDS channel managed directly by the core device's runtime.
|
||||||
|
|
||||||
This class should not be used directly, instead, use the chip-specific
|
This class should not be used directly, instead, use the chip-specific
|
||||||
drivers such as ``AD9858`` and ``AD9914``.
|
drivers such as ``AD9858`` and ``AD9914``.
|
||||||
|
|
||||||
:param sysclk: DDS system frequency.
|
:param bus: name of the DDS bus device that this DDS is connected to.
|
||||||
:param channel: channel number of the DDS device to control.
|
:param channel: channel number of the DDS device to control.
|
||||||
"""
|
"""
|
||||||
def __init__(self, dmgr, sysclk, channel):
|
def __init__(self, dmgr, sysclk, bus_channel, channel, core_dds_device="core_dds"):
|
||||||
self.core = dmgr.get("core")
|
self.core_dds = dmgr.get(core_dds_device)
|
||||||
self.sysclk = sysclk
|
self.core = self.core_dds.core
|
||||||
|
self.bus_channel = bus_channel
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self.phase_mode = PHASE_MODE_CONTINUOUS
|
self.phase_mode = PHASE_MODE_CONTINUOUS
|
||||||
|
|
||||||
|
@ -87,14 +94,14 @@ class _DDSGeneric:
|
||||||
"""Returns the frequency tuning word corresponding to the given
|
"""Returns the frequency tuning word corresponding to the given
|
||||||
frequency.
|
frequency.
|
||||||
"""
|
"""
|
||||||
return round(int(2, width=64)**32*frequency/self.sysclk)
|
return round(int(2, width=64)**32*frequency/self.core_dds.sysclk)
|
||||||
|
|
||||||
@portable
|
@portable
|
||||||
def ftw_to_frequency(self, ftw):
|
def ftw_to_frequency(self, ftw):
|
||||||
"""Returns the frequency corresponding to the given frequency tuning
|
"""Returns the frequency corresponding to the given frequency tuning
|
||||||
word.
|
word.
|
||||||
"""
|
"""
|
||||||
return ftw*self.sysclk/int(2, width=64)**32
|
return ftw*self.core_dds.sysclk/int(2, width=64)**32
|
||||||
|
|
||||||
@portable
|
@portable
|
||||||
def turns_to_pow(self, turns):
|
def turns_to_pow(self, turns):
|
||||||
|
@ -124,7 +131,7 @@ class _DDSGeneric:
|
||||||
"""Resets and initializes the DDS channel.
|
"""Resets and initializes the DDS channel.
|
||||||
|
|
||||||
The runtime does this for all channels upon core device startup."""
|
The runtime does this for all channels upon core device startup."""
|
||||||
dds_init(now_mu(), self.channel)
|
dds_init(now_mu(), self.bus_channel, self.channel)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_phase_mode(self, phase_mode):
|
def set_phase_mode(self, phase_mode):
|
||||||
|
@ -163,7 +170,8 @@ class _DDSGeneric:
|
||||||
"""
|
"""
|
||||||
if phase_mode == _PHASE_MODE_DEFAULT:
|
if phase_mode == _PHASE_MODE_DEFAULT:
|
||||||
phase_mode = self.phase_mode
|
phase_mode = self.phase_mode
|
||||||
dds_set(now_mu(), self.channel, frequency, phase, phase_mode, amplitude)
|
dds_set(now_mu(), self.bus_channel, self.channel,
|
||||||
|
frequency, phase, phase_mode, amplitude)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set(self, frequency, phase=0.0, phase_mode=_PHASE_MODE_DEFAULT,
|
def set(self, frequency, phase=0.0, phase_mode=_PHASE_MODE_DEFAULT,
|
||||||
|
|
|
@ -204,8 +204,9 @@ class NIST_QC1(_NIST_Ions):
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||||
self.config["DDS_CHANNEL_COUNT"] = 8
|
self.config["RTIO_DDS_COUNT"] = 1
|
||||||
|
self.config["DDS_CHANNELS_PER_BUS"] = 8
|
||||||
self.config["DDS_AD9858"] = True
|
self.config["DDS_AD9858"] = True
|
||||||
phy = dds.AD9858(platform.request("dds"), 8)
|
phy = dds.AD9858(platform.request("dds"), 8)
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
|
@ -277,8 +278,9 @@ class NIST_CLOCK(_NIST_Ions):
|
||||||
rtio_channels.append(rtio.Channel.from_phy(
|
rtio_channels.append(rtio.Channel.from_phy(
|
||||||
phy, ofifo_depth=128, ififo_depth=128))
|
phy, ofifo_depth=128, ififo_depth=128))
|
||||||
|
|
||||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||||
self.config["DDS_CHANNEL_COUNT"] = 11
|
self.config["RTIO_DDS_COUNT"] = 1
|
||||||
|
self.config["DDS_CHANNELS_PER_BUS"] = 11
|
||||||
self.config["DDS_AD9914"] = True
|
self.config["DDS_AD9914"] = True
|
||||||
self.config["DDS_ONEHOT_SEL"] = True
|
self.config["DDS_ONEHOT_SEL"] = True
|
||||||
phy = dds.AD9914(platform.request("dds"), 11, onehot=True)
|
phy = dds.AD9914(platform.request("dds"), 11, onehot=True)
|
||||||
|
@ -331,8 +333,9 @@ class NIST_QC2(_NIST_Ions):
|
||||||
self.submodules += phy
|
self.submodules += phy
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||||
self.config["DDS_CHANNEL_COUNT"] = 12
|
self.config["RTIO_DDS_COUNT"] = 1
|
||||||
|
self.config["DDS_CHANNELS_PER_BUS"] = 12
|
||||||
self.config["DDS_AD9914"] = True
|
self.config["DDS_AD9914"] = True
|
||||||
self.config["DDS_ONEHOT_SEL"] = True
|
self.config["DDS_ONEHOT_SEL"] = True
|
||||||
phy = dds.AD9914(platform.request("dds"), 12, onehot=True)
|
phy = dds.AD9914(platform.request("dds"), 12, onehot=True)
|
||||||
|
|
|
@ -215,8 +215,9 @@ trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd
|
||||||
rtio_channels.append(rtio.Channel.from_phy(
|
rtio_channels.append(rtio.Channel.from_phy(
|
||||||
phy, ofifo_depth=256, ififo_depth=256))
|
phy, ofifo_depth=256, ififo_depth=256))
|
||||||
|
|
||||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||||
self.config["DDS_CHANNEL_COUNT"] = 8
|
self.config["RTIO_DDS_COUNT"] = 1
|
||||||
|
self.config["DDS_CHANNELS_PER_BUS"] = 8
|
||||||
self.config["DDS_AD9858"] = True
|
self.config["DDS_AD9858"] = True
|
||||||
dds_pins = platform.request("dds")
|
dds_pins = platform.request("dds")
|
||||||
self.comb += dds_pins.p.eq(0)
|
self.comb += dds_pins.p.eq(0)
|
||||||
|
|
|
@ -118,7 +118,8 @@ class _TTLWidget(QtWidgets.QFrame):
|
||||||
|
|
||||||
|
|
||||||
class _DDSWidget(QtWidgets.QFrame):
|
class _DDSWidget(QtWidgets.QFrame):
|
||||||
def __init__(self, channel, sysclk, title):
|
def __init__(self, bus_channel, channel, sysclk, title):
|
||||||
|
self.bus_channel = bus_channel
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self.sysclk = sysclk
|
self.sysclk = sysclk
|
||||||
|
|
||||||
|
@ -146,13 +147,14 @@ class _DDSWidget(QtWidgets.QFrame):
|
||||||
self.set_value(0)
|
self.set_value(0)
|
||||||
|
|
||||||
def set_value(self, ftw):
|
def set_value(self, ftw):
|
||||||
frequency = ftw*self.sysclk/2**32
|
frequency = ftw*self.sysclk()/2**32
|
||||||
self._value.setText("<font size=\"6\">{:.7f} MHz</font>"
|
self._value.setText("<font size=\"6\">{:.7f} MHz</font>"
|
||||||
.format(float(frequency)/1e6))
|
.format(float(frequency)/1e6))
|
||||||
|
|
||||||
|
|
||||||
class _DeviceManager:
|
class _DeviceManager:
|
||||||
def __init__(self, send_to_device, init):
|
def __init__(self, send_to_device, init):
|
||||||
|
self.dds_sysclk = 0
|
||||||
self.send_to_device = send_to_device
|
self.send_to_device = send_to_device
|
||||||
self.ddb = dict()
|
self.ddb = dict()
|
||||||
self.ttl_cb = lambda: None
|
self.ttl_cb = lambda: None
|
||||||
|
@ -162,6 +164,9 @@ class _DeviceManager:
|
||||||
for k, v in init.items():
|
for k, v in init.items():
|
||||||
self[k] = v
|
self[k] = v
|
||||||
|
|
||||||
|
def get_dds_sysclk(self):
|
||||||
|
return self.dds_sysclk
|
||||||
|
|
||||||
def __setitem__(self, k, v):
|
def __setitem__(self, k, v):
|
||||||
if k in self.ttl_widgets:
|
if k in self.ttl_widgets:
|
||||||
del self[k]
|
del self[k]
|
||||||
|
@ -181,12 +186,15 @@ class _DeviceManager:
|
||||||
self.ttl_widgets[k] = _TTLWidget(
|
self.ttl_widgets[k] = _TTLWidget(
|
||||||
channel, self.send_to_device, force_out, title)
|
channel, self.send_to_device, force_out, title)
|
||||||
self.ttl_cb()
|
self.ttl_cb()
|
||||||
|
if (v["module"] == "artiq.coredevice.dds"
|
||||||
|
and v["class"] == "CoreDDS"):
|
||||||
|
self.dds_sysclk = v["arguments"]["sysclk"]
|
||||||
if (v["module"] == "artiq.coredevice.dds"
|
if (v["module"] == "artiq.coredevice.dds"
|
||||||
and v["class"] in {"AD9858", "AD9914"}):
|
and v["class"] in {"AD9858", "AD9914"}):
|
||||||
|
bus_channel = v["arguments"]["bus_channel"]
|
||||||
channel = v["arguments"]["channel"]
|
channel = v["arguments"]["channel"]
|
||||||
sysclk = v["arguments"]["sysclk"]
|
|
||||||
self.dds_widgets[channel] = _DDSWidget(
|
self.dds_widgets[channel] = _DDSWidget(
|
||||||
channel, sysclk, title)
|
bus_channel, channel, self.get_dds_sysclk, title)
|
||||||
self.dds_cb()
|
self.dds_cb()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
@ -275,19 +283,23 @@ class MonInj(TaskObject):
|
||||||
"is not present yet")
|
"is not present yet")
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
ttl_levels, ttl_oes, ttl_overrides = \
|
hlen = 8*3+4
|
||||||
struct.unpack(">QQQ", data[:8*3])
|
(ttl_levels, ttl_oes, ttl_overrides,
|
||||||
|
dds_rtio_first_channel, dds_channels_per_bus) = \
|
||||||
|
struct.unpack(">QQQHH", data[:hlen])
|
||||||
for w in self.dm.ttl_widgets.values():
|
for w in self.dm.ttl_widgets.values():
|
||||||
channel = w.channel
|
channel = w.channel
|
||||||
w.set_value(ttl_levels & (1 << channel),
|
w.set_value(ttl_levels & (1 << channel),
|
||||||
ttl_oes & (1 << channel),
|
ttl_oes & (1 << channel),
|
||||||
ttl_overrides & (1 << channel))
|
ttl_overrides & (1 << channel))
|
||||||
dds_data = data[8*3:]
|
dds_data = data[hlen:]
|
||||||
ndds = len(dds_data)//4
|
ndds = len(dds_data)//4
|
||||||
ftws = struct.unpack(">" + "I"*ndds, dds_data)
|
ftws = struct.unpack(">" + "I"*ndds, dds_data)
|
||||||
for w in self.dm.dds_widgets.values():
|
for w in self.dm.dds_widgets.values():
|
||||||
|
offset = (dds_channels_per_bus*w.bus_channel
|
||||||
|
+ w.channel-dds_rtio_first_channel)
|
||||||
try:
|
try:
|
||||||
ftw = ftws[w.channel]
|
ftw = ftws[offset]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -12,7 +12,6 @@ struct analyzer_header {
|
||||||
unsigned long long int total_byte_count;
|
unsigned long long int total_byte_count;
|
||||||
unsigned char overflow_occured;
|
unsigned char overflow_occured;
|
||||||
unsigned char log_channel;
|
unsigned char log_channel;
|
||||||
unsigned char dds_channel;
|
|
||||||
unsigned char dds_onehot_sel;
|
unsigned char dds_onehot_sel;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
@ -72,7 +71,6 @@ void analyzer_start(void)
|
||||||
|
|
||||||
analyzer_header.overflow_occured = rtio_analyzer_message_encoder_overflow_read();
|
analyzer_header.overflow_occured = rtio_analyzer_message_encoder_overflow_read();
|
||||||
analyzer_header.log_channel = CONFIG_RTIO_LOG_CHANNEL;
|
analyzer_header.log_channel = CONFIG_RTIO_LOG_CHANNEL;
|
||||||
analyzer_header.dds_channel = CONFIG_RTIO_DDS_CHANNEL;
|
|
||||||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||||
analyzer_header.dds_onehot_sel = 1;
|
analyzer_header.dds_onehot_sel = 1;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -16,12 +16,12 @@ static void rtio_output_blind(int channel, int addr, int data)
|
||||||
rtio_o_we_write(1);
|
rtio_o_we_write(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dds_write(int addr, int data)
|
static void dds_write(int bus_channel, int addr, int data)
|
||||||
{
|
{
|
||||||
rtio_output_blind(CONFIG_RTIO_DDS_CHANNEL, addr, data);
|
rtio_output_blind(bus_channel, addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dds_read(int addr)
|
static int dds_read(int bus_channel, int addr)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ static int dds_read(int addr)
|
||||||
#ifdef CONFIG_DDS_AD9914
|
#ifdef CONFIG_DDS_AD9914
|
||||||
#define DDS_READ_FLAG 256
|
#define DDS_READ_FLAG 256
|
||||||
#endif
|
#endif
|
||||||
dds_write(addr | DDS_READ_FLAG, 0);
|
dds_write(bus_channel, addr | DDS_READ_FLAG, 0);
|
||||||
while(rtio_i_status_read() & RTIO_I_STATUS_EMPTY);
|
while(rtio_i_status_read() & RTIO_I_STATUS_EMPTY);
|
||||||
r = rtio_i_data_read();
|
r = rtio_i_data_read();
|
||||||
rtio_i_re_write(1);
|
rtio_i_re_write(1);
|
||||||
|
@ -75,16 +75,18 @@ void bridge_main(void)
|
||||||
struct msg_brg_dds_sel *msg;
|
struct msg_brg_dds_sel *msg;
|
||||||
|
|
||||||
msg = (struct msg_brg_dds_sel *)umsg;
|
msg = (struct msg_brg_dds_sel *)umsg;
|
||||||
dds_write(DDS_GPIO, msg->channel << 1);
|
dds_write(msg->bus_channel, DDS_GPIO, msg->channel << 1);
|
||||||
mailbox_acknowledge();
|
mailbox_acknowledge();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MESSAGE_TYPE_BRG_DDS_RESET: {
|
case MESSAGE_TYPE_BRG_DDS_RESET: {
|
||||||
unsigned int g;
|
unsigned int g;
|
||||||
|
struct msg_brg_dds_reset *msg;
|
||||||
|
|
||||||
g = dds_read(DDS_GPIO);
|
msg = (struct msg_brg_dds_reset *)umsg;
|
||||||
dds_write(DDS_GPIO, g | 1);
|
g = dds_read(msg->bus_channel, DDS_GPIO);
|
||||||
dds_write(DDS_GPIO, g);
|
dds_write(msg->bus_channel, DDS_GPIO, g | 1);
|
||||||
|
dds_write(msg->bus_channel, DDS_GPIO, g);
|
||||||
|
|
||||||
mailbox_acknowledge();
|
mailbox_acknowledge();
|
||||||
break;
|
break;
|
||||||
|
@ -95,7 +97,7 @@ void bridge_main(void)
|
||||||
|
|
||||||
msg = (struct msg_brg_dds_read_request *)umsg;
|
msg = (struct msg_brg_dds_read_request *)umsg;
|
||||||
rmsg.type = MESSAGE_TYPE_BRG_DDS_READ_REPLY;
|
rmsg.type = MESSAGE_TYPE_BRG_DDS_READ_REPLY;
|
||||||
rmsg.data = dds_read(msg->address);
|
rmsg.data = dds_read(msg->bus_channel, msg->address);
|
||||||
mailbox_send_and_wait(&rmsg);
|
mailbox_send_and_wait(&rmsg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -103,14 +105,18 @@ void bridge_main(void)
|
||||||
struct msg_brg_dds_write *msg;
|
struct msg_brg_dds_write *msg;
|
||||||
|
|
||||||
msg = (struct msg_brg_dds_write *)umsg;
|
msg = (struct msg_brg_dds_write *)umsg;
|
||||||
dds_write(msg->address, msg->data);
|
dds_write(msg->bus_channel, msg->address, msg->data);
|
||||||
mailbox_acknowledge();
|
mailbox_acknowledge();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MESSAGE_TYPE_BRG_DDS_FUD:
|
case MESSAGE_TYPE_BRG_DDS_FUD: {
|
||||||
dds_write(DDS_FUD, 0);
|
struct msg_brg_dds_fud *msg;
|
||||||
|
|
||||||
|
msg = (struct msg_brg_dds_fud *)umsg;
|
||||||
|
dds_write(msg->bus_channel, DDS_FUD, 0);
|
||||||
mailbox_acknowledge();
|
mailbox_acknowledge();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
mailbox_acknowledge();
|
mailbox_acknowledge();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -43,30 +43,33 @@ void brg_ttlo(int n, int value)
|
||||||
mailbox_send_and_wait(&msg);
|
mailbox_send_and_wait(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void brg_ddssel(int channel)
|
void brg_ddssel(int bus_channel, int channel)
|
||||||
{
|
{
|
||||||
struct msg_brg_dds_sel msg;
|
struct msg_brg_dds_sel msg;
|
||||||
|
|
||||||
msg.type = MESSAGE_TYPE_BRG_DDS_SEL;
|
msg.type = MESSAGE_TYPE_BRG_DDS_SEL;
|
||||||
|
msg.bus_channel = bus_channel;
|
||||||
msg.channel = channel;
|
msg.channel = channel;
|
||||||
mailbox_send_and_wait(&msg);
|
mailbox_send_and_wait(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void brg_ddsreset(void)
|
void brg_ddsreset(int bus_channel)
|
||||||
{
|
{
|
||||||
struct msg_base msg;
|
struct msg_brg_dds_reset msg;
|
||||||
|
|
||||||
msg.type = MESSAGE_TYPE_BRG_DDS_RESET;
|
msg.type = MESSAGE_TYPE_BRG_DDS_RESET;
|
||||||
|
msg.bus_channel = bus_channel;
|
||||||
mailbox_send_and_wait(&msg);
|
mailbox_send_and_wait(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int brg_ddsread(unsigned int address)
|
unsigned int brg_ddsread(int bus_channel, unsigned int address)
|
||||||
{
|
{
|
||||||
struct msg_brg_dds_read_request msg;
|
struct msg_brg_dds_read_request msg;
|
||||||
struct msg_brg_dds_read_reply *rmsg;
|
struct msg_brg_dds_read_reply *rmsg;
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
|
|
||||||
msg.type = MESSAGE_TYPE_BRG_DDS_READ_REQUEST;
|
msg.type = MESSAGE_TYPE_BRG_DDS_READ_REQUEST;
|
||||||
|
msg.bus_channel = bus_channel;
|
||||||
msg.address = address;
|
msg.address = address;
|
||||||
mailbox_send(&msg);
|
mailbox_send(&msg);
|
||||||
while(1) {
|
while(1) {
|
||||||
|
@ -82,20 +85,22 @@ unsigned int brg_ddsread(unsigned int address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void brg_ddswrite(unsigned int address, unsigned int data)
|
void brg_ddswrite(int bus_channel, unsigned int address, unsigned int data)
|
||||||
{
|
{
|
||||||
struct msg_brg_dds_write msg;
|
struct msg_brg_dds_write msg;
|
||||||
|
|
||||||
msg.type = MESSAGE_TYPE_BRG_DDS_WRITE;
|
msg.type = MESSAGE_TYPE_BRG_DDS_WRITE;
|
||||||
|
msg.bus_channel = bus_channel;
|
||||||
msg.address = address;
|
msg.address = address;
|
||||||
msg.data = data;
|
msg.data = data;
|
||||||
mailbox_send_and_wait(&msg);
|
mailbox_send_and_wait(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void brg_ddsfud(void)
|
void brg_ddsfud(int bus_channel)
|
||||||
{
|
{
|
||||||
struct msg_base msg;
|
struct msg_brg_dds_fud msg;
|
||||||
|
|
||||||
msg.type = MESSAGE_TYPE_BRG_DDS_FUD;
|
msg.type = MESSAGE_TYPE_BRG_DDS_FUD;
|
||||||
|
msg.bus_channel = bus_channel;
|
||||||
mailbox_send_and_wait(&msg);
|
mailbox_send_and_wait(&msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@ void brg_start(void);
|
||||||
void brg_ttloe(int n, int value);
|
void brg_ttloe(int n, int value);
|
||||||
void brg_ttlo(int n, int value);
|
void brg_ttlo(int n, int value);
|
||||||
|
|
||||||
void brg_ddssel(int channel);
|
void brg_ddssel(int bus_channel, int channel);
|
||||||
void brg_ddsreset(void);
|
void brg_ddsreset(int bus_channel);
|
||||||
unsigned int brg_ddsread(unsigned int address);
|
unsigned int brg_ddsread(int bus_channel, unsigned int address);
|
||||||
void brg_ddswrite(unsigned int address, unsigned int data);
|
void brg_ddswrite(int bus_channel, unsigned int address, unsigned int data);
|
||||||
void brg_ddsfud(void);
|
void brg_ddsfud(int bus_channel);
|
||||||
|
|
||||||
#endif /* __BRIDGE_CTL_H */
|
#endif /* __BRIDGE_CTL_H */
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DDS_WRITE(addr, data) do { \
|
#define DDS_WRITE(addr, data) do { \
|
||||||
rtio_output(now, CONFIG_RTIO_DDS_CHANNEL, addr, data); \
|
rtio_output(now, bus_channel, addr, data); \
|
||||||
now += DURATION_WRITE; \
|
now += DURATION_WRITE; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
void dds_init(long long int timestamp, int channel)
|
void dds_init(long long int timestamp, int bus_channel, int channel)
|
||||||
{
|
{
|
||||||
long long int now;
|
long long int now;
|
||||||
|
|
||||||
|
@ -84,7 +84,8 @@ void dds_init(long long int timestamp, int channel)
|
||||||
* to continuous phase mode. */
|
* to continuous phase mode. */
|
||||||
static unsigned int continuous_phase_comp[CONFIG_DDS_CHANNEL_COUNT];
|
static unsigned int continuous_phase_comp[CONFIG_DDS_CHANNEL_COUNT];
|
||||||
|
|
||||||
static void dds_set_one(long long int now, long long int ref_time, unsigned int channel,
|
static void dds_set_one(long long int now, long long int ref_time,
|
||||||
|
unsigned int bus_channel, unsigned int channel,
|
||||||
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
|
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
|
||||||
{
|
{
|
||||||
unsigned int channel_enc;
|
unsigned int channel_enc;
|
||||||
|
@ -157,6 +158,7 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dds_set_params {
|
struct dds_set_params {
|
||||||
|
int bus_channel;
|
||||||
int channel;
|
int channel;
|
||||||
unsigned int ftw;
|
unsigned int ftw;
|
||||||
unsigned int pow;
|
unsigned int pow;
|
||||||
|
@ -189,20 +191,22 @@ void dds_batch_exit(void)
|
||||||
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
|
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
|
||||||
for(i=0;i<batch_count;i++) {
|
for(i=0;i<batch_count;i++) {
|
||||||
dds_set_one(now, batch_ref_time,
|
dds_set_one(now, batch_ref_time,
|
||||||
batch[i].channel, batch[i].ftw, batch[i].pow, batch[i].phase_mode,
|
batch[i].bus_channel, batch[i].channel,
|
||||||
|
batch[i].ftw, batch[i].pow, batch[i].phase_mode,
|
||||||
batch[i].amplitude);
|
batch[i].amplitude);
|
||||||
now += DURATION_PROGRAM + DURATION_WRITE;
|
now += DURATION_PROGRAM + DURATION_WRITE;
|
||||||
}
|
}
|
||||||
batch_mode = 0;
|
batch_mode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dds_set(long long int timestamp, int channel,
|
void dds_set(long long int timestamp, int bus_channel, int channel,
|
||||||
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
|
unsigned int ftw, unsigned int pow, int phase_mode, unsigned int amplitude)
|
||||||
{
|
{
|
||||||
if(batch_mode) {
|
if(batch_mode) {
|
||||||
if(batch_count >= DDS_MAX_BATCH)
|
if(batch_count >= DDS_MAX_BATCH)
|
||||||
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
|
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
|
||||||
/* timestamp parameter ignored (determined by batch) */
|
/* timestamp parameter ignored (determined by batch) */
|
||||||
|
batch[batch_count].bus_channel = bus_channel;
|
||||||
batch[batch_count].channel = channel;
|
batch[batch_count].channel = channel;
|
||||||
batch[batch_count].ftw = ftw;
|
batch[batch_count].ftw = ftw;
|
||||||
batch[batch_count].pow = pow;
|
batch[batch_count].pow = pow;
|
||||||
|
@ -210,7 +214,8 @@ void dds_set(long long int timestamp, int channel,
|
||||||
batch[batch_count].amplitude = amplitude;
|
batch[batch_count].amplitude = amplitude;
|
||||||
batch_count++;
|
batch_count++;
|
||||||
} else {
|
} else {
|
||||||
dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode,
|
dds_set_one(timestamp - DURATION_PROGRAM, timestamp,
|
||||||
amplitude);
|
bus_channel, channel,
|
||||||
|
ftw, pow, phase_mode, amplitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,23 +150,37 @@ struct msg_brg_ttl_out {
|
||||||
|
|
||||||
struct msg_brg_dds_sel {
|
struct msg_brg_dds_sel {
|
||||||
int type;
|
int type;
|
||||||
|
int bus_channel;
|
||||||
int channel;
|
int channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct msg_brg_dds_reset {
|
||||||
|
int type;
|
||||||
|
int bus_channel;
|
||||||
|
};
|
||||||
|
|
||||||
struct msg_brg_dds_read_request {
|
struct msg_brg_dds_read_request {
|
||||||
int type;
|
int type;
|
||||||
|
int bus_channel;
|
||||||
unsigned int address;
|
unsigned int address;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msg_brg_dds_read_reply {
|
struct msg_brg_dds_read_reply {
|
||||||
int type;
|
int type;
|
||||||
|
int bus_channel;
|
||||||
unsigned int data;
|
unsigned int data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct msg_brg_dds_write {
|
struct msg_brg_dds_write {
|
||||||
int type;
|
int type;
|
||||||
|
int bus_channel;
|
||||||
unsigned int address;
|
unsigned int address;
|
||||||
unsigned int data;
|
unsigned int data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct msg_brg_dds_fud {
|
||||||
|
int type;
|
||||||
|
int bus_channel;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __MESSAGES_H */
|
#endif /* __MESSAGES_H */
|
||||||
|
|
|
@ -36,13 +36,15 @@ struct monitor_reply {
|
||||||
long long int ttl_levels;
|
long long int ttl_levels;
|
||||||
long long int ttl_oes;
|
long long int ttl_oes;
|
||||||
long long int ttl_overrides;
|
long long int ttl_overrides;
|
||||||
unsigned int dds_ftws[CONFIG_DDS_CHANNEL_COUNT];
|
unsigned short int dds_rtio_first_channel;
|
||||||
};
|
unsigned short int dds_channels_per_bus;
|
||||||
|
unsigned int dds_ftws[CONFIG_RTIO_DDS_COUNT*CONFIG_DDS_CHANNELS_PER_BUS];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
static void moninj_monitor(const ip_addr_t *addr, u16_t port)
|
static void moninj_monitor(const ip_addr_t *addr, u16_t port)
|
||||||
{
|
{
|
||||||
struct monitor_reply reply;
|
struct monitor_reply reply;
|
||||||
int i;
|
int i, j;
|
||||||
struct pbuf *reply_p;
|
struct pbuf *reply_p;
|
||||||
|
|
||||||
reply.ttl_levels = 0;
|
reply.ttl_levels = 0;
|
||||||
|
@ -64,11 +66,15 @@ static void moninj_monitor(const ip_addr_t *addr, u16_t port)
|
||||||
reply.ttl_overrides |= 1LL << i;
|
reply.ttl_overrides |= 1LL << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtio_moninj_mon_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL);
|
reply.dds_rtio_first_channel = CONFIG_RTIO_FIRST_DDS_CHANNEL;
|
||||||
for(i=0;i<CONFIG_DDS_CHANNEL_COUNT;i++) {
|
reply.dds_channels_per_bus = CONFIG_DDS_CHANNELS_PER_BUS;
|
||||||
rtio_moninj_mon_probe_sel_write(i);
|
for(j=0;j<CONFIG_RTIO_DDS_COUNT;j++) {
|
||||||
rtio_moninj_mon_value_update_write(1);
|
rtio_moninj_mon_chan_sel_write(CONFIG_RTIO_FIRST_DDS_CHANNEL+j);
|
||||||
reply.dds_ftws[i] = rtio_moninj_mon_value_read();
|
for(i=0;i<CONFIG_DDS_CHANNELS_PER_BUS;i++) {
|
||||||
|
rtio_moninj_mon_probe_sel_write(i);
|
||||||
|
rtio_moninj_mon_value_update_write(1);
|
||||||
|
reply.dds_ftws[CONFIG_DDS_CHANNELS_PER_BUS*j+i] = rtio_moninj_mon_value_read();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reply_p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct monitor_reply), PBUF_RAM);
|
reply_p = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct monitor_reply), PBUF_RAM);
|
||||||
|
|
|
@ -104,6 +104,28 @@ static void ttlo(char *n, char *value)
|
||||||
brg_ttlo(n2, value2);
|
brg_ttlo(n2, value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bus_channel = CONFIG_RTIO_FIRST_DDS_CHANNEL;
|
||||||
|
|
||||||
|
static void ddsbus(char *n)
|
||||||
|
{
|
||||||
|
char *c;
|
||||||
|
unsigned int n2;
|
||||||
|
|
||||||
|
if(*n == 0) {
|
||||||
|
printf("ddsbus <n>\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n2 = strtoul(n, &c, 0);
|
||||||
|
if(*c != 0) {
|
||||||
|
printf("incorrect bus channel\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bus_channel = n2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ddssel(char *n)
|
static void ddssel(char *n)
|
||||||
{
|
{
|
||||||
char *c;
|
char *c;
|
||||||
|
@ -123,7 +145,7 @@ static void ddssel(char *n)
|
||||||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||||
n2 = 1 << n2;
|
n2 = 1 << n2;
|
||||||
#endif
|
#endif
|
||||||
brg_ddssel(n2);
|
brg_ddssel(bus_channel, n2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddsw(char *addr, char *value)
|
static void ddsw(char *addr, char *value)
|
||||||
|
@ -147,7 +169,7 @@ static void ddsw(char *addr, char *value)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
brg_ddswrite(addr2, value2);
|
brg_ddswrite(bus_channel, addr2, value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddsr(char *addr)
|
static void ddsr(char *addr)
|
||||||
|
@ -167,16 +189,16 @@ static void ddsr(char *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DDS_AD9858
|
#ifdef CONFIG_DDS_AD9858
|
||||||
printf("0x%02x\n", brg_ddsread(addr2));
|
printf("0x%02x\n", brg_ddsread(bus_channel, addr2));
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_DDS_AD9914
|
#ifdef CONFIG_DDS_AD9914
|
||||||
printf("0x%04x\n", brg_ddsread(addr2));
|
printf("0x%04x\n", brg_ddsread(bus_channel, addr2));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddsfud(void)
|
static void ddsfud(void)
|
||||||
{
|
{
|
||||||
brg_ddsfud();
|
brg_ddsfud(bus_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddsftw(char *n, char *ftw)
|
static void ddsftw(char *n, char *ftw)
|
||||||
|
@ -203,36 +225,36 @@ static void ddsftw(char *n, char *ftw)
|
||||||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||||
n2 = 1 << n2;
|
n2 = 1 << n2;
|
||||||
#endif
|
#endif
|
||||||
brg_ddssel(n2);
|
brg_ddssel(bus_channel, n2);
|
||||||
|
|
||||||
#ifdef CONFIG_DDS_AD9858
|
#ifdef CONFIG_DDS_AD9858
|
||||||
brg_ddswrite(DDS_FTW0, ftw2 & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW0, ftw2 & 0xff);
|
||||||
brg_ddswrite(DDS_FTW1, (ftw2 >> 8) & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW1, (ftw2 >> 8) & 0xff);
|
||||||
brg_ddswrite(DDS_FTW2, (ftw2 >> 16) & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW2, (ftw2 >> 16) & 0xff);
|
||||||
brg_ddswrite(DDS_FTW3, (ftw2 >> 24) & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW3, (ftw2 >> 24) & 0xff);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_DDS_AD9914
|
#ifdef CONFIG_DDS_AD9914
|
||||||
brg_ddswrite(DDS_FTWL, ftw2 & 0xffff);
|
brg_ddswrite(bus_channel, DDS_FTWL, ftw2 & 0xffff);
|
||||||
brg_ddswrite(DDS_FTWH, (ftw2 >> 16) & 0xffff);
|
brg_ddswrite(bus_channel, DDS_FTWH, (ftw2 >> 16) & 0xffff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
brg_ddsfud();
|
brg_ddsfud(bus_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddsreset(void)
|
static void ddsreset(void)
|
||||||
{
|
{
|
||||||
brg_ddsreset();
|
brg_ddsreset(bus_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DDS_AD9858
|
#ifdef CONFIG_DDS_AD9858
|
||||||
static void ddsinit(void)
|
static void ddsinit(void)
|
||||||
{
|
{
|
||||||
brg_ddsreset();
|
brg_ddsreset(bus_channel);
|
||||||
brg_ddswrite(DDS_CFR0, 0x78);
|
brg_ddswrite(bus_channel, DDS_CFR0, 0x78);
|
||||||
brg_ddswrite(DDS_CFR1, 0x00);
|
brg_ddswrite(bus_channel, DDS_CFR1, 0x00);
|
||||||
brg_ddswrite(DDS_CFR2, 0x00);
|
brg_ddswrite(bus_channel, DDS_CFR2, 0x00);
|
||||||
brg_ddswrite(DDS_CFR3, 0x00);
|
brg_ddswrite(bus_channel, DDS_CFR3, 0x00);
|
||||||
brg_ddsfud();
|
brg_ddsfud(bus_channel);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -241,17 +263,17 @@ static void ddsinit(void)
|
||||||
{
|
{
|
||||||
long long int t;
|
long long int t;
|
||||||
|
|
||||||
brg_ddsreset();
|
brg_ddsreset(bus_channel);
|
||||||
brg_ddswrite(DDS_CFR1H, 0x0000); /* Enable cosine output */
|
brg_ddswrite(bus_channel, DDS_CFR1H, 0x0000); /* Enable cosine output */
|
||||||
brg_ddswrite(DDS_CFR2L, 0x8900); /* Enable matched latency */
|
brg_ddswrite(bus_channel, DDS_CFR2L, 0x8900); /* Enable matched latency */
|
||||||
brg_ddswrite(DDS_CFR2H, 0x0080); /* Enable profile mode */
|
brg_ddswrite(bus_channel, DDS_CFR2H, 0x0080); /* Enable profile mode */
|
||||||
brg_ddswrite(DDS_ASF, 0x0fff); /* Set amplitude to maximum */
|
brg_ddswrite(bus_channel, DDS_ASF, 0x0fff); /* Set amplitude to maximum */
|
||||||
brg_ddswrite(DDS_CFR4H, 0x0105); /* Enable DAC calibration */
|
brg_ddswrite(bus_channel, DDS_CFR4H, 0x0105); /* Enable DAC calibration */
|
||||||
brg_ddswrite(DDS_FUD, 0);
|
brg_ddswrite(bus_channel, DDS_FUD, 0);
|
||||||
t = clock_get_ms();
|
t = clock_get_ms();
|
||||||
while(clock_get_ms() < t + 2);
|
while(clock_get_ms() < t + 2);
|
||||||
brg_ddswrite(DDS_CFR4H, 0x0005); /* Disable DAC calibration */
|
brg_ddswrite(bus_channel, DDS_CFR4H, 0x0005); /* Disable DAC calibration */
|
||||||
brg_ddsfud();
|
brg_ddsfud(bus_channel);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -265,34 +287,34 @@ static void do_ddstest_one(unsigned int i)
|
||||||
unsigned int f, g, j;
|
unsigned int f, g, j;
|
||||||
|
|
||||||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||||
brg_ddssel(1 << i);
|
brg_ddssel(bus_channel, 1 << i);
|
||||||
#else
|
#else
|
||||||
brg_ddssel(i);
|
brg_ddssel(bus_channel, i);
|
||||||
#endif
|
#endif
|
||||||
ddsinit();
|
ddsinit();
|
||||||
|
|
||||||
for(j=0; j<12; j++) {
|
for(j=0; j<12; j++) {
|
||||||
f = v[j];
|
f = v[j];
|
||||||
#ifdef CONFIG_DDS_AD9858
|
#ifdef CONFIG_DDS_AD9858
|
||||||
brg_ddswrite(DDS_FTW0, f & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW0, f & 0xff);
|
||||||
brg_ddswrite(DDS_FTW1, (f >> 8) & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW1, (f >> 8) & 0xff);
|
||||||
brg_ddswrite(DDS_FTW2, (f >> 16) & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW2, (f >> 16) & 0xff);
|
||||||
brg_ddswrite(DDS_FTW3, (f >> 24) & 0xff);
|
brg_ddswrite(bus_channel, DDS_FTW3, (f >> 24) & 0xff);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_DDS_AD9914
|
#ifdef CONFIG_DDS_AD9914
|
||||||
brg_ddswrite(DDS_FTWL, f & 0xffff);
|
brg_ddswrite(bus_channel, DDS_FTWL, f & 0xffff);
|
||||||
brg_ddswrite(DDS_FTWH, (f >> 16) & 0xffff);
|
brg_ddswrite(bus_channel, DDS_FTWH, (f >> 16) & 0xffff);
|
||||||
#endif
|
#endif
|
||||||
brg_ddsfud();
|
brg_ddsfud();
|
||||||
#ifdef CONFIG_DDS_AD9858
|
#ifdef CONFIG_DDS_AD9858
|
||||||
g = brg_ddsread(DDS_FTW0);
|
g = brg_ddsread(bus_channel, DDS_FTW0);
|
||||||
g |= brg_ddsread(DDS_FTW1) << 8;
|
g |= brg_ddsread(bus_channel, DDS_FTW1) << 8;
|
||||||
g |= brg_ddsread(DDS_FTW2) << 16;
|
g |= brg_ddsread(bus_channel, DDS_FTW2) << 16;
|
||||||
g |= brg_ddsread(DDS_FTW3) << 24;
|
g |= brg_ddsread(bus_channel, DDS_FTW3) << 24;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_DDS_AD9914
|
#ifdef CONFIG_DDS_AD9914
|
||||||
g = brg_ddsread(DDS_FTWL);
|
g = brg_ddsread(bus_channel, DDS_FTWL);
|
||||||
g |= brg_ddsread(DDS_FTWH) << 16;
|
g |= brg_ddsread(bus_channel, DDS_FTWH) << 16;
|
||||||
#endif
|
#endif
|
||||||
if(g != f)
|
if(g != f)
|
||||||
printf("readback fail on DDS %d, 0x%08x != 0x%08x\n", i, g, f);
|
printf("readback fail on DDS %d, 0x%08x != 0x%08x\n", i, g, f);
|
||||||
|
@ -330,7 +352,7 @@ static void ddstest(char *n, char *channel)
|
||||||
do_ddstest_one(channel2);
|
do_ddstest_one(channel2);
|
||||||
} else {
|
} else {
|
||||||
for(i=0;i<n2;i++)
|
for(i=0;i<n2;i++)
|
||||||
for(j=0;j<CONFIG_DDS_CHANNEL_COUNT;j++)
|
for(j=0;j<CONFIG_DDS_CHANNELS_PER_BUS;j++)
|
||||||
do_ddstest_one(j);
|
do_ddstest_one(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,6 +564,7 @@ static void help(void)
|
||||||
puts("clksrc <n> - select RTIO clock source");
|
puts("clksrc <n> - select RTIO clock source");
|
||||||
puts("ttloe <n> <v> - set TTL output enable");
|
puts("ttloe <n> <v> - set TTL output enable");
|
||||||
puts("ttlo <n> <v> - set TTL output value");
|
puts("ttlo <n> <v> - set TTL output value");
|
||||||
|
puts("ddsbus <n> - select the DDS bus RTIO channel");
|
||||||
puts("ddssel <n> - select a DDS");
|
puts("ddssel <n> - select a DDS");
|
||||||
puts("ddsinit - reset, config, FUD DDS");
|
puts("ddsinit - reset, config, FUD DDS");
|
||||||
puts("ddsreset - reset DDS");
|
puts("ddsreset - reset DDS");
|
||||||
|
@ -624,6 +647,7 @@ static void do_command(char *c)
|
||||||
else if(strcmp(token, "ttloe") == 0) ttloe(get_token(&c), get_token(&c));
|
else if(strcmp(token, "ttloe") == 0) ttloe(get_token(&c), get_token(&c));
|
||||||
else if(strcmp(token, "ttlo") == 0) ttlo(get_token(&c), get_token(&c));
|
else if(strcmp(token, "ttlo") == 0) ttlo(get_token(&c), get_token(&c));
|
||||||
|
|
||||||
|
else if(strcmp(token, "ddsbus") == 0) ddsbus(get_token(&c));
|
||||||
else if(strcmp(token, "ddssel") == 0) ddssel(get_token(&c));
|
else if(strcmp(token, "ddssel") == 0) ddssel(get_token(&c));
|
||||||
else if(strcmp(token, "ddsw") == 0) ddsw(get_token(&c), get_token(&c));
|
else if(strcmp(token, "ddsw") == 0) ddsw(get_token(&c), get_token(&c));
|
||||||
else if(strcmp(token, "ddsr") == 0) ddsr(get_token(&c));
|
else if(strcmp(token, "ddsr") == 0) ddsr(get_token(&c));
|
||||||
|
|
|
@ -89,6 +89,8 @@ The board has RTIO SPI buses mapped as follows:
|
||||||
| 25 | SPI2_CS_N | SPI2_MOSI | SPI2_MISO | SPI2_CLK |
|
| 25 | SPI2_CS_N | SPI2_MOSI | SPI2_MISO | SPI2_CLK |
|
||||||
+--------------+-------------+-------------+-----------+------------+
|
+--------------+-------------+-------------+-----------+------------+
|
||||||
|
|
||||||
|
The DDS bus is on channel 26.
|
||||||
|
|
||||||
|
|
||||||
NIST QC2
|
NIST QC2
|
||||||
++++++++
|
++++++++
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
"class": "Core",
|
"class": "Core",
|
||||||
"arguments": {"ref_period": 1e-9}
|
"arguments": {"ref_period": 1e-9}
|
||||||
},
|
},
|
||||||
|
"core_dds": {
|
||||||
|
"type": "local",
|
||||||
|
"module": "artiq.coredevice.dds",
|
||||||
|
"class": "CoreDDS",
|
||||||
|
"arguments": {"sysclk": 3e9}
|
||||||
|
},
|
||||||
|
|
||||||
"i2c_switch": {
|
"i2c_switch": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
|
@ -121,30 +127,24 @@
|
||||||
"arguments": {"spi_device": "spi0", "ldac_device": "ttl0"}
|
"arguments": {"spi_device": "spi0", "ldac_device": "ttl0"}
|
||||||
},
|
},
|
||||||
|
|
||||||
"dds_bus": {
|
|
||||||
"type": "local",
|
|
||||||
"module": "artiq.coredevice.dds",
|
|
||||||
"class": "DDSBus",
|
|
||||||
"arguments": {}
|
|
||||||
},
|
|
||||||
"dds0": {
|
"dds0": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.dds",
|
"module": "artiq.coredevice.dds",
|
||||||
"class": "AD9914",
|
"class": "AD9914",
|
||||||
"arguments": {"sysclk": 3e9, "channel": 0},
|
"arguments": {"bus_channel": 26, "channel": 0},
|
||||||
"comment": "Comments work in DDS panel as well"
|
"comment": "Comments work in DDS panel as well"
|
||||||
},
|
},
|
||||||
"dds1": {
|
"dds1": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.dds",
|
"module": "artiq.coredevice.dds",
|
||||||
"class": "AD9914",
|
"class": "AD9914",
|
||||||
"arguments": {"sysclk": 3e9, "channel": 1}
|
"arguments": {"bus_channel": 26, "channel": 1}
|
||||||
},
|
},
|
||||||
"dds2": {
|
"dds2": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.dds",
|
"module": "artiq.coredevice.dds",
|
||||||
"class": "AD9914",
|
"class": "AD9914",
|
||||||
"arguments": {"sysclk": 3e9, "channel": 2}
|
"arguments": {"bus_channel": 26, "channel": 2}
|
||||||
},
|
},
|
||||||
|
|
||||||
"qc_q1_0": {
|
"qc_q1_0": {
|
||||||
|
|
Loading…
Reference in New Issue