forked from M-Labs/artiq
1
0
Fork 0

Merge branch 'master' into rtiobusy

* master:
  coredevice: fix _DDSGeneric __init__ args
  rtio/core: fix syntax
  rtio: disable replace on rt2wb channels
  examples: dds_bus -> core_dds
  fix more multi-DDS-bus problems
  runtime: fix dds declarations
  support for multiple DDS buses (untested)
This commit is contained in:
Robert Jördens 2016-03-09 17:58:58 +01:00
commit 349a66124b
23 changed files with 301 additions and 188 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -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, 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,

View File

@ -130,24 +130,27 @@ class _OutputManager(Module):
collision = Signal() collision = Signal()
any_error = Signal() any_error = Signal()
nop = Signal() nop = Signal()
self.sync.rsys += [ if interface.enable_replace:
# Note: replace may be asserted at the same time as collision # Note: replace may be asserted at the same time as collision
# when addresses are different. In that case, it is a collision. # when addresses are different. In that case, it is a collision.
replace.eq(self.ev.timestamp == buf.timestamp), self.sync.rsys += replace.eq(self.ev.timestamp == buf.timestamp)
# Detect sequence errors on coarse timestamps only # Detect sequence errors on coarse timestamps only
# so that they are mutually exclusive with collision errors. # so that they are mutually exclusive with collision errors.
sequence_error.eq(self.ev.timestamp[fine_ts_width:] self.sync.rsys += sequence_error.eq(self.ev.timestamp[fine_ts_width:] <
< buf.timestamp[fine_ts_width:]) buf.timestamp[fine_ts_width:])
] if interface.enable_replace:
if hasattr(self.ev, "a"): if hasattr(self.ev, "a"):
different_addresses = self.ev.a != buf.a different_addresses = self.ev.a != buf.a
else:
different_addresses = 0
if fine_ts_width:
self.sync.rsys += collision.eq(
(self.ev.timestamp[fine_ts_width:] == buf.timestamp[fine_ts_width:])
& ((self.ev.timestamp[:fine_ts_width] != buf.timestamp[:fine_ts_width])
|different_addresses))
else: else:
different_addresses = 0
if fine_ts_width:
self.sync.rsys += collision.eq( self.sync.rsys += collision.eq(
(self.ev.timestamp[fine_ts_width:] == buf.timestamp[fine_ts_width:]) self.ev.timestamp[fine_ts_width:] == buf.timestamp[fine_ts_width:])
& ((self.ev.timestamp[:fine_ts_width] != buf.timestamp[:fine_ts_width])
|different_addresses))
self.comb += any_error.eq(sequence_error | collision) self.comb += any_error.eq(sequence_error | collision)
if interface.suppress_nop: if interface.suppress_nop:
# disable NOP at reset: do not suppress a first write with all 0s # disable NOP at reset: do not suppress a first write with all 0s

View File

@ -13,7 +13,8 @@ class RT2WB(Module):
rtlink.OInterface( rtlink.OInterface(
len(wb.dat_w), len(wb.dat_w),
address_width + 1, address_width + 1,
suppress_nop=False), suppress_nop=False,
enable_replace=False),
rtlink.IInterface( rtlink.IInterface(
len(wb.dat_r), len(wb.dat_r),
timestamped=False) timestamped=False)

View File

@ -3,7 +3,8 @@ from migen import *
class OInterface: class OInterface:
def __init__(self, data_width, address_width=0, def __init__(self, data_width, address_width=0,
fine_ts_width=0, suppress_nop=True): fine_ts_width=0, suppress_nop=True,
enable_replace=True):
self.stb = Signal() self.stb = Signal()
self.busy = Signal() self.busy = Signal()
@ -15,6 +16,7 @@ class OInterface:
self.fine_ts = Signal(fine_ts_width) self.fine_ts = Signal(fine_ts_width)
self.suppress_nop = suppress_nop self.suppress_nop = suppress_nop
self.enable_replace = enable_replace
@classmethod @classmethod
def like(cls, other): def like(cls, other):

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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);
} }

View File

@ -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 */

View File

@ -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;
@ -82,17 +82,23 @@ void dds_init(long long int timestamp, int channel)
/* Compensation to keep phase continuity when switching from absolute or tracking /* Compensation to keep phase continuity when switching from absolute or tracking
* 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_RTIO_DDS_COUNT][CONFIG_DDS_CHANNELS_PER_BUS];
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,
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)
{ {
unsigned int channel_enc; unsigned int channel_enc;
if(channel >= CONFIG_DDS_CHANNEL_COUNT) { if((channel < 0) || (channel >= CONFIG_DDS_CHANNELS_PER_BUS)) {
core_log("Attempted to set invalid DDS channel\n"); core_log("Attempted to set invalid DDS channel\n");
return; return;
} }
if((bus_channel < CONFIG_RTIO_FIRST_DDS_CHANNEL)
|| (bus_channel >= (CONFIG_RTIO_FIRST_DDS_CHANNEL+CONFIG_RTIO_DDS_COUNT))) {
core_log("Attempted to use invalid DDS bus\n");
return;
}
#ifdef CONFIG_DDS_ONEHOT_SEL #ifdef CONFIG_DDS_ONEHOT_SEL
channel_enc = 1 << channel; channel_enc = 1 << channel;
#else #else
@ -124,7 +130,7 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
/* Disable autoclear phase accumulator and enables OSK. */ /* Disable autoclear phase accumulator and enables OSK. */
DDS_WRITE(DDS_CFR1L, 0x0108); DDS_WRITE(DDS_CFR1L, 0x0108);
#endif #endif
pow += continuous_phase_comp[channel]; pow += continuous_phase_comp[bus_channel-CONFIG_RTIO_FIRST_DDS_CHANNEL][channel];
} else { } else {
long long int fud_time; long long int fud_time;
@ -140,7 +146,7 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
pow -= (ref_time - fud_time)*CONFIG_DDS_RTIO_CLK_RATIO*ftw >> (32-DDS_POW_WIDTH); pow -= (ref_time - fud_time)*CONFIG_DDS_RTIO_CLK_RATIO*ftw >> (32-DDS_POW_WIDTH);
if(phase_mode == PHASE_MODE_TRACKING) if(phase_mode == PHASE_MODE_TRACKING)
pow += ref_time*CONFIG_DDS_RTIO_CLK_RATIO*ftw >> (32-DDS_POW_WIDTH); pow += ref_time*CONFIG_DDS_RTIO_CLK_RATIO*ftw >> (32-DDS_POW_WIDTH);
continuous_phase_comp[channel] = pow; continuous_phase_comp[bus_channel-CONFIG_RTIO_FIRST_DDS_CHANNEL][channel] = pow;
} }
#ifdef CONFIG_DDS_AD9858 #ifdef CONFIG_DDS_AD9858
@ -157,6 +163,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 +196,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 +219,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);
} }
} }

View File

@ -54,10 +54,10 @@ enum {
PHASE_MODE_TRACKING = 2 PHASE_MODE_TRACKING = 2
}; };
void dds_init(long long int timestamp, int channel); void dds_init(long long int timestamp, int bus_channel, int channel);
void dds_batch_enter(long long int timestamp); void dds_batch_enter(long long int timestamp);
void dds_batch_exit(void); void dds_batch_exit(void);
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);
#endif /* __DDS_H */ #endif /* __DDS_H */

View File

@ -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 */

View File

@ -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);

View File

@ -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(bus_channel);
#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));

View File

@ -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
++++++++ ++++++++

View File

@ -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": {

View File

@ -6,7 +6,7 @@ class PhotonHistogram(EnvExperiment):
def build(self): def build(self):
self.setattr_device("core") self.setattr_device("core")
self.setattr_device("dds_bus") self.setattr_device("core_dds")
self.setattr_device("bd_dds") self.setattr_device("bd_dds")
self.setattr_device("bd_sw") self.setattr_device("bd_sw")
self.setattr_device("bdd_dds") self.setattr_device("bdd_dds")
@ -22,7 +22,7 @@ class PhotonHistogram(EnvExperiment):
@kernel @kernel
def program_cooling(self): def program_cooling(self):
with self.dds_bus.batch: with self.core_dds.batch:
self.bd_dds.set(200*MHz) self.bd_dds.set(200*MHz)
self.bdd_dds.set(300*MHz) self.bdd_dds.set(300*MHz)

View File

@ -6,7 +6,7 @@ class DDSTest(EnvExperiment):
def build(self): def build(self):
self.setattr_device("core") self.setattr_device("core")
self.setattr_device("dds_bus") self.setattr_device("core_dds")
self.setattr_device("dds0") self.setattr_device("dds0")
self.setattr_device("dds1") self.setattr_device("dds1")
self.setattr_device("dds2") self.setattr_device("dds2")
@ -17,7 +17,7 @@ class DDSTest(EnvExperiment):
@kernel @kernel
def run(self): def run(self):
with self.dds_bus.batch: with self.core_dds.batch:
self.dds1.set(120*MHz) self.dds1.set(120*MHz)
self.dds2.set(200*MHz) self.dds2.set(200*MHz)
delay(1*us) delay(1*us)