forked from M-Labs/artiq
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:
commit
349a66124b
|
@ -11,4 +11,8 @@ Release notes
|
|||
This requires reflashing the runtime and the flash storage filesystem image
|
||||
or erase and rewrite its entries.
|
||||
* 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", "log_channel dds_channel dds_onehot_sel messages")
|
||||
"DecodedDump", "log_channel dds_onehot_sel messages")
|
||||
|
||||
|
||||
def decode_dump(data):
|
||||
parts = struct.unpack(">IQbbbb", data[:16])
|
||||
parts = struct.unpack(">IQbbb", data[:15])
|
||||
(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):
|
||||
raise ValueError("analyzer dump has incorrect length")
|
||||
expected_len = sent_bytes + 15
|
||||
if expected_len != len(data):
|
||||
raise ValueError("analyzer dump has incorrect length "
|
||||
"(got {}, expected {})".format(
|
||||
len(data), expected_len))
|
||||
if overflow_occured:
|
||||
logger.warning("analyzer FIFO overflow occured, "
|
||||
"some messages have been lost")
|
||||
|
@ -57,14 +60,12 @@ def decode_dump(data):
|
|||
logger.info("analyzer ring buffer has wrapped %d times",
|
||||
total_byte_count//sent_bytes)
|
||||
|
||||
position = 16
|
||||
position = 15
|
||||
messages = []
|
||||
for _ in range(sent_bytes//32):
|
||||
messages.append(decode_message(data[position:position+32]))
|
||||
position += 32
|
||||
return DecodedDump(log_channel,
|
||||
dds_channel, bool(dds_onehot_sel),
|
||||
messages)
|
||||
return DecodedDump(log_channel, bool(dds_onehot_sel), messages)
|
||||
|
||||
|
||||
def vcd_codes():
|
||||
|
@ -299,21 +300,31 @@ def get_vcd_log_channels(log_channel, messages):
|
|||
return vcd_log_channels
|
||||
|
||||
|
||||
def get_ref_period(devices):
|
||||
def get_single_device_argument(devices, module, cls, argument):
|
||||
ref_period = None
|
||||
for desc in devices.values():
|
||||
if isinstance(desc, dict) and desc["type"] == "local":
|
||||
if (desc["module"] == "artiq.coredevice.core"
|
||||
and desc["class"] == "Core"):
|
||||
if (desc["module"] == module
|
||||
and desc["class"] == cls):
|
||||
if ref_period is None:
|
||||
ref_period = desc["arguments"]["ref_period"]
|
||||
ref_period = desc["arguments"][argument]
|
||||
else:
|
||||
return None # more than one core device found
|
||||
return None # more than one device found
|
||||
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,
|
||||
dds_channel, dds_onehot_sel):
|
||||
dds_sysclk, dds_onehot_sel):
|
||||
channel_handlers = dict()
|
||||
for name, desc in sorted(devices.items(), key=itemgetter(0)):
|
||||
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)
|
||||
if (desc["module"] == "artiq.coredevice.dds"
|
||||
and desc["class"] in {"AD9858", "AD9914"}):
|
||||
sysclk = desc["arguments"]["sysclk"]
|
||||
dds_channel_ddsbus = desc["arguments"]["channel"]
|
||||
if dds_channel in channel_handlers:
|
||||
dds_handler = channel_handlers[dds_channel]
|
||||
dds_bus_channel = desc["arguments"]["bus_channel"]
|
||||
dds_channel = desc["arguments"]["channel"]
|
||||
if dds_bus_channel in channel_handlers:
|
||||
dds_handler = channel_handlers[dds_bus_channel]
|
||||
if dds_handler.dds_type != desc["class"]:
|
||||
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:
|
||||
dds_handler = DDSHandler(vcd_manager, desc["class"],
|
||||
dds_onehot_sel, sysclk)
|
||||
channel_handlers[dds_channel] = dds_handler
|
||||
dds_handler.add_dds_channel(name, dds_channel_ddsbus)
|
||||
dds_sysclk, dds_onehot_sel)
|
||||
channel_handlers[dds_bus_channel] = dds_handler
|
||||
dds_handler.add_dds_channel(name, dds_channel)
|
||||
return channel_handlers
|
||||
|
||||
|
||||
|
@ -355,12 +364,16 @@ def decoded_dump_to_vcd(fileobj, devices, dump):
|
|||
else:
|
||||
logger.warning("unable to determine core device ref_period")
|
||||
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)
|
||||
|
||||
channel_handlers = create_channel_handlers(
|
||||
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)
|
||||
channel_handlers[dump.log_channel] = LogHandler(vcd_manager, vcd_log_channels)
|
||||
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)]
|
||||
return "\n".join(lines)
|
||||
|
||||
colors_supported = (os.name == 'posix')
|
||||
colors_supported = os.name == "posix"
|
||||
class _DiagnosticEngine(diagnostic.Engine):
|
||||
def render_diagnostic(self, diagnostic):
|
||||
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:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
class Core:
|
||||
"""Core device driver.
|
||||
|
||||
|
|
|
@ -11,7 +11,12 @@ PHASE_MODE_TRACKING = 2
|
|||
|
||||
|
||||
@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")
|
||||
|
||||
@syscall
|
||||
|
@ -22,35 +27,36 @@ def dds_batch_enter(time_mu: TInt64) -> TNone:
|
|||
def dds_batch_exit() -> TNone:
|
||||
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:
|
||||
def __init__(self, dds_bus):
|
||||
self.dds_bus = dds_bus
|
||||
def __init__(self, core_dds):
|
||||
self.core_dds = core_dds
|
||||
self.core = self.core_dds.core
|
||||
|
||||
@kernel
|
||||
def __enter__(self):
|
||||
self.dds_bus.batch_enter()
|
||||
self.core_dds.dds_batch_enter()
|
||||
|
||||
@kernel
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.dds_bus.batch_exit()
|
||||
self.core_dds.dds_batch_exit()
|
||||
|
||||
|
||||
class DDSBus:
|
||||
"""Core device Direct Digital Synthesis (DDS) bus batching driver.
|
||||
class CoreDDS:
|
||||
"""Core device Direct Digital Synthesis (DDS) driver.
|
||||
|
||||
Manages batching of DDS commands on a DDS shared bus."""
|
||||
def __init__(self, dmgr):
|
||||
self.core = dmgr.get("core")
|
||||
Gives access to the DDS functionality of the core device.
|
||||
|
||||
: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)
|
||||
|
||||
@kernel
|
||||
def batch_enter(self):
|
||||
def dds_batch_enter(self):
|
||||
"""Starts a DDS command batch. All DDS commands are buffered
|
||||
after this call, until ``batch_exit`` is called.
|
||||
|
||||
|
@ -59,26 +65,27 @@ class DDSBus:
|
|||
dds_batch_enter(now_mu())
|
||||
|
||||
@kernel
|
||||
def batch_exit(self):
|
||||
def dds_batch_exit(self):
|
||||
"""Ends a DDS command batch. All buffered DDS commands are issued
|
||||
on the bus."""
|
||||
dds_batch_exit()
|
||||
|
||||
|
||||
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.
|
||||
|
||||
This class should not be used directly, instead, use the chip-specific
|
||||
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.
|
||||
"""
|
||||
def __init__(self, dmgr, sysclk, channel):
|
||||
self.core = dmgr.get("core")
|
||||
self.sysclk = sysclk
|
||||
def __init__(self, dmgr, bus_channel, channel, core_dds_device="core_dds"):
|
||||
self.core_dds = dmgr.get(core_dds_device)
|
||||
self.core = self.core_dds.core
|
||||
self.bus_channel = bus_channel
|
||||
self.channel = channel
|
||||
self.phase_mode = PHASE_MODE_CONTINUOUS
|
||||
|
||||
|
@ -87,14 +94,14 @@ class _DDSGeneric:
|
|||
"""Returns the frequency tuning word corresponding to the given
|
||||
frequency.
|
||||
"""
|
||||
return round(int(2, width=64)**32*frequency/self.sysclk)
|
||||
return round(int(2, width=64)**32*frequency/self.core_dds.sysclk)
|
||||
|
||||
@portable
|
||||
def ftw_to_frequency(self, ftw):
|
||||
"""Returns the frequency corresponding to the given frequency tuning
|
||||
word.
|
||||
"""
|
||||
return ftw*self.sysclk/int(2, width=64)**32
|
||||
return ftw*self.core_dds.sysclk/int(2, width=64)**32
|
||||
|
||||
@portable
|
||||
def turns_to_pow(self, turns):
|
||||
|
@ -124,7 +131,7 @@ class _DDSGeneric:
|
|||
"""Resets and initializes the DDS channel.
|
||||
|
||||
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
|
||||
def set_phase_mode(self, phase_mode):
|
||||
|
@ -163,7 +170,8 @@ class _DDSGeneric:
|
|||
"""
|
||||
if phase_mode == _PHASE_MODE_DEFAULT:
|
||||
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
|
||||
def set(self, frequency, phase=0.0, phase_mode=_PHASE_MODE_DEFAULT,
|
||||
|
|
|
@ -130,15 +130,15 @@ class _OutputManager(Module):
|
|||
collision = Signal()
|
||||
any_error = Signal()
|
||||
nop = Signal()
|
||||
self.sync.rsys += [
|
||||
if interface.enable_replace:
|
||||
# Note: replace may be asserted at the same time as 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
|
||||
# so that they are mutually exclusive with collision errors.
|
||||
sequence_error.eq(self.ev.timestamp[fine_ts_width:]
|
||||
< buf.timestamp[fine_ts_width:])
|
||||
]
|
||||
self.sync.rsys += sequence_error.eq(self.ev.timestamp[fine_ts_width:] <
|
||||
buf.timestamp[fine_ts_width:])
|
||||
if interface.enable_replace:
|
||||
if hasattr(self.ev, "a"):
|
||||
different_addresses = self.ev.a != buf.a
|
||||
else:
|
||||
|
@ -148,6 +148,9 @@ class _OutputManager(Module):
|
|||
(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:
|
||||
self.sync.rsys += collision.eq(
|
||||
self.ev.timestamp[fine_ts_width:] == buf.timestamp[fine_ts_width:])
|
||||
self.comb += any_error.eq(sequence_error | collision)
|
||||
if interface.suppress_nop:
|
||||
# disable NOP at reset: do not suppress a first write with all 0s
|
||||
|
|
|
@ -13,7 +13,8 @@ class RT2WB(Module):
|
|||
rtlink.OInterface(
|
||||
len(wb.dat_w),
|
||||
address_width + 1,
|
||||
suppress_nop=False),
|
||||
suppress_nop=False,
|
||||
enable_replace=False),
|
||||
rtlink.IInterface(
|
||||
len(wb.dat_r),
|
||||
timestamped=False)
|
||||
|
|
|
@ -3,7 +3,8 @@ from migen import *
|
|||
|
||||
class OInterface:
|
||||
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.busy = Signal()
|
||||
|
||||
|
@ -15,6 +16,7 @@ class OInterface:
|
|||
self.fine_ts = Signal(fine_ts_width)
|
||||
|
||||
self.suppress_nop = suppress_nop
|
||||
self.enable_replace = enable_replace
|
||||
|
||||
@classmethod
|
||||
def like(cls, other):
|
||||
|
|
|
@ -204,8 +204,9 @@ class NIST_QC1(_NIST_Ions):
|
|||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
|
||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["DDS_CHANNEL_COUNT"] = 8
|
||||
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["RTIO_DDS_COUNT"] = 1
|
||||
self.config["DDS_CHANNELS_PER_BUS"] = 8
|
||||
self.config["DDS_AD9858"] = True
|
||||
phy = dds.AD9858(platform.request("dds"), 8)
|
||||
self.submodules += phy
|
||||
|
@ -277,8 +278,9 @@ class NIST_CLOCK(_NIST_Ions):
|
|||
rtio_channels.append(rtio.Channel.from_phy(
|
||||
phy, ofifo_depth=128, ififo_depth=128))
|
||||
|
||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["DDS_CHANNEL_COUNT"] = 11
|
||||
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["RTIO_DDS_COUNT"] = 1
|
||||
self.config["DDS_CHANNELS_PER_BUS"] = 11
|
||||
self.config["DDS_AD9914"] = True
|
||||
self.config["DDS_ONEHOT_SEL"] = True
|
||||
phy = dds.AD9914(platform.request("dds"), 11, onehot=True)
|
||||
|
@ -331,8 +333,9 @@ class NIST_QC2(_NIST_Ions):
|
|||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||
|
||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["DDS_CHANNEL_COUNT"] = 12
|
||||
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["RTIO_DDS_COUNT"] = 1
|
||||
self.config["DDS_CHANNELS_PER_BUS"] = 12
|
||||
self.config["DDS_AD9914"] = True
|
||||
self.config["DDS_ONEHOT_SEL"] = 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(
|
||||
phy, ofifo_depth=256, ififo_depth=256))
|
||||
|
||||
self.config["RTIO_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["DDS_CHANNEL_COUNT"] = 8
|
||||
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||
self.config["RTIO_DDS_COUNT"] = 1
|
||||
self.config["DDS_CHANNELS_PER_BUS"] = 8
|
||||
self.config["DDS_AD9858"] = True
|
||||
dds_pins = platform.request("dds")
|
||||
self.comb += dds_pins.p.eq(0)
|
||||
|
|
|
@ -118,7 +118,8 @@ class _TTLWidget(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.sysclk = sysclk
|
||||
|
||||
|
@ -146,13 +147,14 @@ class _DDSWidget(QtWidgets.QFrame):
|
|||
self.set_value(0)
|
||||
|
||||
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>"
|
||||
.format(float(frequency)/1e6))
|
||||
|
||||
|
||||
class _DeviceManager:
|
||||
def __init__(self, send_to_device, init):
|
||||
self.dds_sysclk = 0
|
||||
self.send_to_device = send_to_device
|
||||
self.ddb = dict()
|
||||
self.ttl_cb = lambda: None
|
||||
|
@ -162,6 +164,9 @@ class _DeviceManager:
|
|||
for k, v in init.items():
|
||||
self[k] = v
|
||||
|
||||
def get_dds_sysclk(self):
|
||||
return self.dds_sysclk
|
||||
|
||||
def __setitem__(self, k, v):
|
||||
if k in self.ttl_widgets:
|
||||
del self[k]
|
||||
|
@ -181,12 +186,15 @@ class _DeviceManager:
|
|||
self.ttl_widgets[k] = _TTLWidget(
|
||||
channel, self.send_to_device, force_out, title)
|
||||
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"
|
||||
and v["class"] in {"AD9858", "AD9914"}):
|
||||
bus_channel = v["arguments"]["bus_channel"]
|
||||
channel = v["arguments"]["channel"]
|
||||
sysclk = v["arguments"]["sysclk"]
|
||||
self.dds_widgets[channel] = _DDSWidget(
|
||||
channel, sysclk, title)
|
||||
bus_channel, channel, self.get_dds_sysclk, title)
|
||||
self.dds_cb()
|
||||
except KeyError:
|
||||
pass
|
||||
|
@ -275,19 +283,23 @@ class MonInj(TaskObject):
|
|||
"is not present yet")
|
||||
return
|
||||
try:
|
||||
ttl_levels, ttl_oes, ttl_overrides = \
|
||||
struct.unpack(">QQQ", data[:8*3])
|
||||
hlen = 8*3+4
|
||||
(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():
|
||||
channel = w.channel
|
||||
w.set_value(ttl_levels & (1 << channel),
|
||||
ttl_oes & (1 << channel),
|
||||
ttl_overrides & (1 << channel))
|
||||
dds_data = data[8*3:]
|
||||
dds_data = data[hlen:]
|
||||
ndds = len(dds_data)//4
|
||||
ftws = struct.unpack(">" + "I"*ndds, dds_data)
|
||||
for w in self.dm.dds_widgets.values():
|
||||
offset = (dds_channels_per_bus*w.bus_channel
|
||||
+ w.channel-dds_rtio_first_channel)
|
||||
try:
|
||||
ftw = ftws[w.channel]
|
||||
ftw = ftws[offset]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
|
|
|
@ -12,7 +12,6 @@ struct analyzer_header {
|
|||
unsigned long long int total_byte_count;
|
||||
unsigned char overflow_occured;
|
||||
unsigned char log_channel;
|
||||
unsigned char dds_channel;
|
||||
unsigned char dds_onehot_sel;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
@ -72,7 +71,6 @@ void analyzer_start(void)
|
|||
|
||||
analyzer_header.overflow_occured = rtio_analyzer_message_encoder_overflow_read();
|
||||
analyzer_header.log_channel = CONFIG_RTIO_LOG_CHANNEL;
|
||||
analyzer_header.dds_channel = CONFIG_RTIO_DDS_CHANNEL;
|
||||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||
analyzer_header.dds_onehot_sel = 1;
|
||||
#else
|
||||
|
|
|
@ -16,12 +16,12 @@ static void rtio_output_blind(int channel, int addr, int data)
|
|||
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;
|
||||
|
||||
|
@ -31,7 +31,7 @@ static int dds_read(int addr)
|
|||
#ifdef CONFIG_DDS_AD9914
|
||||
#define DDS_READ_FLAG 256
|
||||
#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);
|
||||
r = rtio_i_data_read();
|
||||
rtio_i_re_write(1);
|
||||
|
@ -75,16 +75,18 @@ void bridge_main(void)
|
|||
struct msg_brg_dds_sel *msg;
|
||||
|
||||
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();
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_BRG_DDS_RESET: {
|
||||
unsigned int g;
|
||||
struct msg_brg_dds_reset *msg;
|
||||
|
||||
g = dds_read(DDS_GPIO);
|
||||
dds_write(DDS_GPIO, g | 1);
|
||||
dds_write(DDS_GPIO, g);
|
||||
msg = (struct msg_brg_dds_reset *)umsg;
|
||||
g = dds_read(msg->bus_channel, DDS_GPIO);
|
||||
dds_write(msg->bus_channel, DDS_GPIO, g | 1);
|
||||
dds_write(msg->bus_channel, DDS_GPIO, g);
|
||||
|
||||
mailbox_acknowledge();
|
||||
break;
|
||||
|
@ -95,7 +97,7 @@ void bridge_main(void)
|
|||
|
||||
msg = (struct msg_brg_dds_read_request *)umsg;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
@ -103,14 +105,18 @@ void bridge_main(void)
|
|||
struct msg_brg_dds_write *msg;
|
||||
|
||||
msg = (struct msg_brg_dds_write *)umsg;
|
||||
dds_write(msg->address, msg->data);
|
||||
dds_write(msg->bus_channel, msg->address, msg->data);
|
||||
mailbox_acknowledge();
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE_BRG_DDS_FUD:
|
||||
dds_write(DDS_FUD, 0);
|
||||
case MESSAGE_TYPE_BRG_DDS_FUD: {
|
||||
struct msg_brg_dds_fud *msg;
|
||||
|
||||
msg = (struct msg_brg_dds_fud *)umsg;
|
||||
dds_write(msg->bus_channel, DDS_FUD, 0);
|
||||
mailbox_acknowledge();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
mailbox_acknowledge();
|
||||
break;
|
||||
|
|
|
@ -43,30 +43,33 @@ void brg_ttlo(int n, int value)
|
|||
mailbox_send_and_wait(&msg);
|
||||
}
|
||||
|
||||
void brg_ddssel(int channel)
|
||||
void brg_ddssel(int bus_channel, int channel)
|
||||
{
|
||||
struct msg_brg_dds_sel msg;
|
||||
|
||||
msg.type = MESSAGE_TYPE_BRG_DDS_SEL;
|
||||
msg.bus_channel = bus_channel;
|
||||
msg.channel = channel;
|
||||
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.bus_channel = bus_channel;
|
||||
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_reply *rmsg;
|
||||
unsigned int r;
|
||||
|
||||
msg.type = MESSAGE_TYPE_BRG_DDS_READ_REQUEST;
|
||||
msg.bus_channel = bus_channel;
|
||||
msg.address = address;
|
||||
mailbox_send(&msg);
|
||||
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;
|
||||
|
||||
msg.type = MESSAGE_TYPE_BRG_DDS_WRITE;
|
||||
msg.bus_channel = bus_channel;
|
||||
msg.address = address;
|
||||
msg.data = data;
|
||||
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.bus_channel = bus_channel;
|
||||
mailbox_send_and_wait(&msg);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ void brg_start(void);
|
|||
void brg_ttloe(int n, int value);
|
||||
void brg_ttlo(int n, int value);
|
||||
|
||||
void brg_ddssel(int channel);
|
||||
void brg_ddsreset(void);
|
||||
unsigned int brg_ddsread(unsigned int address);
|
||||
void brg_ddswrite(unsigned int address, unsigned int data);
|
||||
void brg_ddsfud(void);
|
||||
void brg_ddssel(int bus_channel, int channel);
|
||||
void brg_ddsreset(int bus_channel);
|
||||
unsigned int brg_ddsread(int bus_channel, unsigned int address);
|
||||
void brg_ddswrite(int bus_channel, unsigned int address, unsigned int data);
|
||||
void brg_ddsfud(int bus_channel);
|
||||
|
||||
#endif /* __BRIDGE_CTL_H */
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
#endif
|
||||
|
||||
#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; \
|
||||
} 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;
|
||||
|
||||
|
@ -82,17 +82,23 @@ void dds_init(long long int timestamp, int channel)
|
|||
|
||||
/* Compensation to keep phase continuity when switching from absolute or tracking
|
||||
* 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 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");
|
||||
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
|
||||
channel_enc = 1 << channel;
|
||||
#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. */
|
||||
DDS_WRITE(DDS_CFR1L, 0x0108);
|
||||
#endif
|
||||
pow += continuous_phase_comp[channel];
|
||||
pow += continuous_phase_comp[bus_channel-CONFIG_RTIO_FIRST_DDS_CHANNEL][channel];
|
||||
} else {
|
||||
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);
|
||||
if(phase_mode == PHASE_MODE_TRACKING)
|
||||
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
|
||||
|
@ -157,6 +163,7 @@ static void dds_set_one(long long int now, long long int ref_time, unsigned int
|
|||
}
|
||||
|
||||
struct dds_set_params {
|
||||
int bus_channel;
|
||||
int channel;
|
||||
unsigned int ftw;
|
||||
unsigned int pow;
|
||||
|
@ -189,20 +196,22 @@ void dds_batch_exit(void)
|
|||
now = batch_ref_time - batch_count*(DURATION_PROGRAM + DURATION_WRITE);
|
||||
for(i=0;i<batch_count;i++) {
|
||||
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);
|
||||
now += DURATION_PROGRAM + DURATION_WRITE;
|
||||
}
|
||||
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)
|
||||
{
|
||||
if(batch_mode) {
|
||||
if(batch_count >= DDS_MAX_BATCH)
|
||||
artiq_raise_from_c("DDSBatchError", "DDS batch error", 0, 0, 0);
|
||||
/* timestamp parameter ignored (determined by batch) */
|
||||
batch[batch_count].bus_channel = bus_channel;
|
||||
batch[batch_count].channel = channel;
|
||||
batch[batch_count].ftw = ftw;
|
||||
batch[batch_count].pow = pow;
|
||||
|
@ -210,7 +219,8 @@ void dds_set(long long int timestamp, int channel,
|
|||
batch[batch_count].amplitude = amplitude;
|
||||
batch_count++;
|
||||
} else {
|
||||
dds_set_one(timestamp - DURATION_PROGRAM, timestamp, channel, ftw, pow, phase_mode,
|
||||
amplitude);
|
||||
dds_set_one(timestamp - DURATION_PROGRAM, timestamp,
|
||||
bus_channel, channel,
|
||||
ftw, pow, phase_mode, amplitude);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,10 +54,10 @@ enum {
|
|||
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_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);
|
||||
|
||||
#endif /* __DDS_H */
|
||||
|
|
|
@ -150,23 +150,37 @@ struct msg_brg_ttl_out {
|
|||
|
||||
struct msg_brg_dds_sel {
|
||||
int type;
|
||||
int bus_channel;
|
||||
int channel;
|
||||
};
|
||||
|
||||
struct msg_brg_dds_reset {
|
||||
int type;
|
||||
int bus_channel;
|
||||
};
|
||||
|
||||
struct msg_brg_dds_read_request {
|
||||
int type;
|
||||
int bus_channel;
|
||||
unsigned int address;
|
||||
};
|
||||
|
||||
struct msg_brg_dds_read_reply {
|
||||
int type;
|
||||
int bus_channel;
|
||||
unsigned int data;
|
||||
};
|
||||
|
||||
struct msg_brg_dds_write {
|
||||
int type;
|
||||
int bus_channel;
|
||||
unsigned int address;
|
||||
unsigned int data;
|
||||
};
|
||||
|
||||
struct msg_brg_dds_fud {
|
||||
int type;
|
||||
int bus_channel;
|
||||
};
|
||||
|
||||
#endif /* __MESSAGES_H */
|
||||
|
|
|
@ -36,13 +36,15 @@ struct monitor_reply {
|
|||
long long int ttl_levels;
|
||||
long long int ttl_oes;
|
||||
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)
|
||||
{
|
||||
struct monitor_reply reply;
|
||||
int i;
|
||||
int i, j;
|
||||
struct pbuf *reply_p;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
rtio_moninj_mon_chan_sel_write(CONFIG_RTIO_DDS_CHANNEL);
|
||||
for(i=0;i<CONFIG_DDS_CHANNEL_COUNT;i++) {
|
||||
reply.dds_rtio_first_channel = CONFIG_RTIO_FIRST_DDS_CHANNEL;
|
||||
reply.dds_channels_per_bus = CONFIG_DDS_CHANNELS_PER_BUS;
|
||||
for(j=0;j<CONFIG_RTIO_DDS_COUNT;j++) {
|
||||
rtio_moninj_mon_chan_sel_write(CONFIG_RTIO_FIRST_DDS_CHANNEL+j);
|
||||
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[i] = rtio_moninj_mon_value_read();
|
||||
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);
|
||||
|
|
|
@ -104,6 +104,28 @@ static void ttlo(char *n, char *value)
|
|||
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)
|
||||
{
|
||||
char *c;
|
||||
|
@ -123,7 +145,7 @@ static void ddssel(char *n)
|
|||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||
n2 = 1 << n2;
|
||||
#endif
|
||||
brg_ddssel(n2);
|
||||
brg_ddssel(bus_channel, n2);
|
||||
}
|
||||
|
||||
static void ddsw(char *addr, char *value)
|
||||
|
@ -147,7 +169,7 @@ static void ddsw(char *addr, char *value)
|
|||
return;
|
||||
}
|
||||
|
||||
brg_ddswrite(addr2, value2);
|
||||
brg_ddswrite(bus_channel, addr2, value2);
|
||||
}
|
||||
|
||||
static void ddsr(char *addr)
|
||||
|
@ -167,16 +189,16 @@ static void ddsr(char *addr)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_DDS_AD9858
|
||||
printf("0x%02x\n", brg_ddsread(addr2));
|
||||
printf("0x%02x\n", brg_ddsread(bus_channel, addr2));
|
||||
#endif
|
||||
#ifdef CONFIG_DDS_AD9914
|
||||
printf("0x%04x\n", brg_ddsread(addr2));
|
||||
printf("0x%04x\n", brg_ddsread(bus_channel, addr2));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ddsfud(void)
|
||||
{
|
||||
brg_ddsfud();
|
||||
brg_ddsfud(bus_channel);
|
||||
}
|
||||
|
||||
static void ddsftw(char *n, char *ftw)
|
||||
|
@ -203,36 +225,36 @@ static void ddsftw(char *n, char *ftw)
|
|||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||
n2 = 1 << n2;
|
||||
#endif
|
||||
brg_ddssel(n2);
|
||||
brg_ddssel(bus_channel, n2);
|
||||
|
||||
#ifdef CONFIG_DDS_AD9858
|
||||
brg_ddswrite(DDS_FTW0, ftw2 & 0xff);
|
||||
brg_ddswrite(DDS_FTW1, (ftw2 >> 8) & 0xff);
|
||||
brg_ddswrite(DDS_FTW2, (ftw2 >> 16) & 0xff);
|
||||
brg_ddswrite(DDS_FTW3, (ftw2 >> 24) & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW0, ftw2 & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW1, (ftw2 >> 8) & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW2, (ftw2 >> 16) & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW3, (ftw2 >> 24) & 0xff);
|
||||
#endif
|
||||
#ifdef CONFIG_DDS_AD9914
|
||||
brg_ddswrite(DDS_FTWL, ftw2 & 0xffff);
|
||||
brg_ddswrite(DDS_FTWH, (ftw2 >> 16) & 0xffff);
|
||||
brg_ddswrite(bus_channel, DDS_FTWL, ftw2 & 0xffff);
|
||||
brg_ddswrite(bus_channel, DDS_FTWH, (ftw2 >> 16) & 0xffff);
|
||||
#endif
|
||||
|
||||
brg_ddsfud();
|
||||
brg_ddsfud(bus_channel);
|
||||
}
|
||||
|
||||
static void ddsreset(void)
|
||||
{
|
||||
brg_ddsreset();
|
||||
brg_ddsreset(bus_channel);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DDS_AD9858
|
||||
static void ddsinit(void)
|
||||
{
|
||||
brg_ddsreset();
|
||||
brg_ddswrite(DDS_CFR0, 0x78);
|
||||
brg_ddswrite(DDS_CFR1, 0x00);
|
||||
brg_ddswrite(DDS_CFR2, 0x00);
|
||||
brg_ddswrite(DDS_CFR3, 0x00);
|
||||
brg_ddsfud();
|
||||
brg_ddsreset(bus_channel);
|
||||
brg_ddswrite(bus_channel, DDS_CFR0, 0x78);
|
||||
brg_ddswrite(bus_channel, DDS_CFR1, 0x00);
|
||||
brg_ddswrite(bus_channel, DDS_CFR2, 0x00);
|
||||
brg_ddswrite(bus_channel, DDS_CFR3, 0x00);
|
||||
brg_ddsfud(bus_channel);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -241,17 +263,17 @@ static void ddsinit(void)
|
|||
{
|
||||
long long int t;
|
||||
|
||||
brg_ddsreset();
|
||||
brg_ddswrite(DDS_CFR1H, 0x0000); /* Enable cosine output */
|
||||
brg_ddswrite(DDS_CFR2L, 0x8900); /* Enable matched latency */
|
||||
brg_ddswrite(DDS_CFR2H, 0x0080); /* Enable profile mode */
|
||||
brg_ddswrite(DDS_ASF, 0x0fff); /* Set amplitude to maximum */
|
||||
brg_ddswrite(DDS_CFR4H, 0x0105); /* Enable DAC calibration */
|
||||
brg_ddswrite(DDS_FUD, 0);
|
||||
brg_ddsreset(bus_channel);
|
||||
brg_ddswrite(bus_channel, DDS_CFR1H, 0x0000); /* Enable cosine output */
|
||||
brg_ddswrite(bus_channel, DDS_CFR2L, 0x8900); /* Enable matched latency */
|
||||
brg_ddswrite(bus_channel, DDS_CFR2H, 0x0080); /* Enable profile mode */
|
||||
brg_ddswrite(bus_channel, DDS_ASF, 0x0fff); /* Set amplitude to maximum */
|
||||
brg_ddswrite(bus_channel, DDS_CFR4H, 0x0105); /* Enable DAC calibration */
|
||||
brg_ddswrite(bus_channel, DDS_FUD, 0);
|
||||
t = clock_get_ms();
|
||||
while(clock_get_ms() < t + 2);
|
||||
brg_ddswrite(DDS_CFR4H, 0x0005); /* Disable DAC calibration */
|
||||
brg_ddsfud();
|
||||
brg_ddswrite(bus_channel, DDS_CFR4H, 0x0005); /* Disable DAC calibration */
|
||||
brg_ddsfud(bus_channel);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -265,34 +287,34 @@ static void do_ddstest_one(unsigned int i)
|
|||
unsigned int f, g, j;
|
||||
|
||||
#ifdef CONFIG_DDS_ONEHOT_SEL
|
||||
brg_ddssel(1 << i);
|
||||
brg_ddssel(bus_channel, 1 << i);
|
||||
#else
|
||||
brg_ddssel(i);
|
||||
brg_ddssel(bus_channel, i);
|
||||
#endif
|
||||
ddsinit();
|
||||
|
||||
for(j=0; j<12; j++) {
|
||||
f = v[j];
|
||||
#ifdef CONFIG_DDS_AD9858
|
||||
brg_ddswrite(DDS_FTW0, f & 0xff);
|
||||
brg_ddswrite(DDS_FTW1, (f >> 8) & 0xff);
|
||||
brg_ddswrite(DDS_FTW2, (f >> 16) & 0xff);
|
||||
brg_ddswrite(DDS_FTW3, (f >> 24) & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW0, f & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW1, (f >> 8) & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW2, (f >> 16) & 0xff);
|
||||
brg_ddswrite(bus_channel, DDS_FTW3, (f >> 24) & 0xff);
|
||||
#endif
|
||||
#ifdef CONFIG_DDS_AD9914
|
||||
brg_ddswrite(DDS_FTWL, f & 0xffff);
|
||||
brg_ddswrite(DDS_FTWH, (f >> 16) & 0xffff);
|
||||
brg_ddswrite(bus_channel, DDS_FTWL, f & 0xffff);
|
||||
brg_ddswrite(bus_channel, DDS_FTWH, (f >> 16) & 0xffff);
|
||||
#endif
|
||||
brg_ddsfud();
|
||||
brg_ddsfud(bus_channel);
|
||||
#ifdef CONFIG_DDS_AD9858
|
||||
g = brg_ddsread(DDS_FTW0);
|
||||
g |= brg_ddsread(DDS_FTW1) << 8;
|
||||
g |= brg_ddsread(DDS_FTW2) << 16;
|
||||
g |= brg_ddsread(DDS_FTW3) << 24;
|
||||
g = brg_ddsread(bus_channel, DDS_FTW0);
|
||||
g |= brg_ddsread(bus_channel, DDS_FTW1) << 8;
|
||||
g |= brg_ddsread(bus_channel, DDS_FTW2) << 16;
|
||||
g |= brg_ddsread(bus_channel, DDS_FTW3) << 24;
|
||||
#endif
|
||||
#ifdef CONFIG_DDS_AD9914
|
||||
g = brg_ddsread(DDS_FTWL);
|
||||
g |= brg_ddsread(DDS_FTWH) << 16;
|
||||
g = brg_ddsread(bus_channel, DDS_FTWL);
|
||||
g |= brg_ddsread(bus_channel, DDS_FTWH) << 16;
|
||||
#endif
|
||||
if(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);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -542,6 +564,7 @@ static void help(void)
|
|||
puts("clksrc <n> - select RTIO clock source");
|
||||
puts("ttloe <n> <v> - set TTL output enable");
|
||||
puts("ttlo <n> <v> - set TTL output value");
|
||||
puts("ddsbus <n> - select the DDS bus RTIO channel");
|
||||
puts("ddssel <n> - select a DDS");
|
||||
puts("ddsinit - reset, config, FUD 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, "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, "ddsw") == 0) ddsw(get_token(&c), 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 |
|
||||
+--------------+-------------+-------------+-----------+------------+
|
||||
|
||||
The DDS bus is on channel 26.
|
||||
|
||||
|
||||
NIST QC2
|
||||
++++++++
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
"class": "Core",
|
||||
"arguments": {"ref_period": 1e-9}
|
||||
},
|
||||
"core_dds": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "CoreDDS",
|
||||
"arguments": {"sysclk": 3e9}
|
||||
},
|
||||
|
||||
"i2c_switch": {
|
||||
"type": "local",
|
||||
|
@ -121,30 +127,24 @@
|
|||
"arguments": {"spi_device": "spi0", "ldac_device": "ttl0"}
|
||||
},
|
||||
|
||||
"dds_bus": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "DDSBus",
|
||||
"arguments": {}
|
||||
},
|
||||
"dds0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "AD9914",
|
||||
"arguments": {"sysclk": 3e9, "channel": 0},
|
||||
"arguments": {"bus_channel": 26, "channel": 0},
|
||||
"comment": "Comments work in DDS panel as well"
|
||||
},
|
||||
"dds1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "AD9914",
|
||||
"arguments": {"sysclk": 3e9, "channel": 1}
|
||||
"arguments": {"bus_channel": 26, "channel": 1}
|
||||
},
|
||||
"dds2": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.dds",
|
||||
"class": "AD9914",
|
||||
"arguments": {"sysclk": 3e9, "channel": 2}
|
||||
"arguments": {"bus_channel": 26, "channel": 2}
|
||||
},
|
||||
|
||||
"qc_q1_0": {
|
||||
|
|
|
@ -6,7 +6,7 @@ class PhotonHistogram(EnvExperiment):
|
|||
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("dds_bus")
|
||||
self.setattr_device("core_dds")
|
||||
self.setattr_device("bd_dds")
|
||||
self.setattr_device("bd_sw")
|
||||
self.setattr_device("bdd_dds")
|
||||
|
@ -22,7 +22,7 @@ class PhotonHistogram(EnvExperiment):
|
|||
|
||||
@kernel
|
||||
def program_cooling(self):
|
||||
with self.dds_bus.batch:
|
||||
with self.core_dds.batch:
|
||||
self.bd_dds.set(200*MHz)
|
||||
self.bdd_dds.set(300*MHz)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ class DDSTest(EnvExperiment):
|
|||
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("dds_bus")
|
||||
self.setattr_device("core_dds")
|
||||
self.setattr_device("dds0")
|
||||
self.setattr_device("dds1")
|
||||
self.setattr_device("dds2")
|
||||
|
@ -17,7 +17,7 @@ class DDSTest(EnvExperiment):
|
|||
|
||||
@kernel
|
||||
def run(self):
|
||||
with self.dds_bus.batch:
|
||||
with self.core_dds.batch:
|
||||
self.dds1.set(120*MHz)
|
||||
self.dds2.set(200*MHz)
|
||||
delay(1*us)
|
||||
|
|
Loading…
Reference in New Issue