forked from M-Labs/artiq
moninj: merge _DDSModel and _DDSHandler
parent
585d8a4d5b
commit
3b8f6edd52
|
@ -152,37 +152,6 @@ class _TTLHandler:
|
||||||
return self.channel
|
return self.channel
|
||||||
|
|
||||||
|
|
||||||
class _DDSModel:
|
|
||||||
def __init__(self, dds_type, ref_clk, cpld=None, pll=1, clk_div=0):
|
|
||||||
self.cpld = cpld
|
|
||||||
self.cur_frequency = 0
|
|
||||||
self.cur_reg = 0
|
|
||||||
self.dds_type = dds_type
|
|
||||||
self.is_urukul = dds_type in ["AD9910", "AD9912"]
|
|
||||||
|
|
||||||
if dds_type == "AD9914":
|
|
||||||
self.ftw_per_hz = 2**32 / ref_clk
|
|
||||||
else:
|
|
||||||
if dds_type == "AD9910":
|
|
||||||
max_freq = 1 << 32
|
|
||||||
clk_mult = [4, 1, 2, 4]
|
|
||||||
elif dds_type == "AD9912": # AD9912
|
|
||||||
max_freq = 1 << 48
|
|
||||||
clk_mult = [1, 1, 2, 4]
|
|
||||||
else:
|
|
||||||
raise NotImplementedError
|
|
||||||
sysclk = ref_clk / clk_mult[clk_div] * pll
|
|
||||||
self.ftw_per_hz = 1 / sysclk * max_freq
|
|
||||||
|
|
||||||
def monitor_update(self, probe, value):
|
|
||||||
if self.dds_type == "AD9912":
|
|
||||||
value = value << 16
|
|
||||||
self.cur_frequency = self._ftw_to_freq(value)
|
|
||||||
|
|
||||||
def _ftw_to_freq(self, ftw):
|
|
||||||
return ftw / self.ftw_per_hz
|
|
||||||
|
|
||||||
|
|
||||||
class _DDSWidget(QtWidgets.QFrame):
|
class _DDSWidget(QtWidgets.QFrame):
|
||||||
apply_changes = QtCore.pyqtSignal()
|
apply_changes = QtCore.pyqtSignal()
|
||||||
off_clicked = QtCore.pyqtSignal()
|
off_clicked = QtCore.pyqtSignal()
|
||||||
|
@ -310,27 +279,53 @@ class _DDSWidget(QtWidgets.QFrame):
|
||||||
|
|
||||||
|
|
||||||
class _DDSHandler:
|
class _DDSHandler:
|
||||||
def __init__(self, dm, title, bus_channel=0, channel=0, dds_model=None):
|
def __init__(self, dm, title, bus_channel, channel, dds_type,
|
||||||
|
ref_clk, cpld=None, pll=1, clk_div=0):
|
||||||
self.dm = dm
|
self.dm = dm
|
||||||
self.bus_channel = bus_channel
|
self.bus_channel = bus_channel
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self.cur_frequency = 0
|
self.cur_frequency = 0
|
||||||
self.dds_name = title
|
self.dds_name = title
|
||||||
self.dds_model = dds_model
|
self.cpld = cpld
|
||||||
self.widget = _DDSWidget(title, dds_model.is_urukul)
|
self.cur_frequency = 0
|
||||||
|
self.cur_reg = 0
|
||||||
|
self.dds_type = dds_type
|
||||||
|
self.is_urukul = dds_type in ["AD9910", "AD9912"]
|
||||||
|
|
||||||
|
if dds_type == "AD9914":
|
||||||
|
self.ftw_per_hz = 2**32 / ref_clk
|
||||||
|
else:
|
||||||
|
if dds_type == "AD9910":
|
||||||
|
max_freq = 1 << 32
|
||||||
|
clk_mult = [4, 1, 2, 4]
|
||||||
|
elif dds_type == "AD9912": # AD9912
|
||||||
|
max_freq = 1 << 48
|
||||||
|
clk_mult = [1, 1, 2, 4]
|
||||||
|
else:
|
||||||
|
raise NotImplementedError
|
||||||
|
sysclk = ref_clk / clk_mult[clk_div] * pll
|
||||||
|
self.ftw_per_hz = 1 / sysclk * max_freq
|
||||||
|
self.widget = _DDSWidget(title, self.is_urukul)
|
||||||
self.widget.apply_changes.connect(self.apply_changes)
|
self.widget.apply_changes.connect(self.apply_changes)
|
||||||
self.widget.off_clicked.connect(self.off_clicked)
|
self.widget.off_clicked.connect(self.off_clicked)
|
||||||
self.widget.set_clicked.connect(self.set_clicked)
|
self.widget.set_clicked.connect(self.set_clicked)
|
||||||
self.refresh_display()
|
self.refresh_display()
|
||||||
|
|
||||||
|
def monitor_update(self, probe, value):
|
||||||
|
if self.dds_type == "AD9912":
|
||||||
|
value = value << 16
|
||||||
|
self.cur_frequency = self._ftw_to_freq(value)
|
||||||
|
|
||||||
|
def _ftw_to_freq(self, ftw):
|
||||||
|
return ftw / self.ftw_per_hz
|
||||||
|
|
||||||
def refresh_display(self):
|
def refresh_display(self):
|
||||||
self.cur_frequency = self.dds_model.cur_frequency
|
|
||||||
self.widget.set_value(self.cur_frequency / 1e6)
|
self.widget.set_value(self.cur_frequency / 1e6)
|
||||||
|
|
||||||
def apply_changes(self):
|
def apply_changes(self):
|
||||||
self.widget.set_page(0)
|
self.widget.set_page(0)
|
||||||
frequency = self.widget.get_value() * 1e6
|
frequency = self.widget.get_value() * 1e6
|
||||||
self.dm.dds_set_frequency(self.dds_name, self.dds_model, frequency)
|
self.dm.dds_set_frequency(self.dds_name, frequency)
|
||||||
|
|
||||||
def set_clicked(self):
|
def set_clicked(self):
|
||||||
self.widget.set_page(1)
|
self.widget.set_page(1)
|
||||||
|
@ -338,7 +333,7 @@ class _DDSHandler:
|
||||||
self.widget.start_edit()
|
self.widget.start_edit()
|
||||||
|
|
||||||
def off_clicked(self):
|
def off_clicked(self):
|
||||||
self.dm.dds_channel_toggle(self.dds_name, self.dds_model, sw=False)
|
self.dm.dds_channel_toggle(self.dds_name, sw=False)
|
||||||
|
|
||||||
def sort_key(self):
|
def sort_key(self):
|
||||||
return (self.bus_channel, self.channel)
|
return (self.bus_channel, self.channel)
|
||||||
|
@ -413,9 +408,8 @@ def setup_from_ddb(ddb):
|
||||||
bus_channel = v["arguments"]["bus_channel"]
|
bus_channel = v["arguments"]["bus_channel"]
|
||||||
channel = v["arguments"]["channel"]
|
channel = v["arguments"]["channel"]
|
||||||
dds_sysclk = v["arguments"]["sysclk"]
|
dds_sysclk = v["arguments"]["sysclk"]
|
||||||
model = _DDSModel(v["class"], dds_sysclk)
|
|
||||||
handler = _HandlerDesc(k, comment, _DDSHandler,
|
handler = _HandlerDesc(k, comment, _DDSHandler,
|
||||||
(k, bus_channel, channel, model))
|
(k, bus_channel, channel, v["class"], dds_sysclk))
|
||||||
description.add(handler)
|
description.add(handler)
|
||||||
elif (v["module"] == "artiq.coredevice.ad9910" and v["class"] == "AD9910") or \
|
elif (v["module"] == "artiq.coredevice.ad9910" and v["class"] == "AD9910") or \
|
||||||
(v["module"] == "artiq.coredevice.ad9912" and v["class"] == "AD9912"):
|
(v["module"] == "artiq.coredevice.ad9912" and v["class"] == "AD9912"):
|
||||||
|
@ -428,9 +422,9 @@ def setup_from_ddb(ddb):
|
||||||
pll = v["arguments"]["pll_n"]
|
pll = v["arguments"]["pll_n"]
|
||||||
refclk = ddb[dds_cpld]["arguments"]["refclk"]
|
refclk = ddb[dds_cpld]["arguments"]["refclk"]
|
||||||
clk_div = v["arguments"].get("clk_div", 0)
|
clk_div = v["arguments"].get("clk_div", 0)
|
||||||
model = _DDSModel(v["class"], refclk, dds_cpld, pll, clk_div)
|
|
||||||
handler = _HandlerDesc(k, comment, _DDSHandler,
|
handler = _HandlerDesc(k, comment, _DDSHandler,
|
||||||
(k, bus_channel, channel, model))
|
(k, bus_channel, channel, v["class"], refclk,
|
||||||
|
dds_cpld, pll, clk_div))
|
||||||
description.add(handler)
|
description.add(handler)
|
||||||
elif (v["module"] == "artiq.coredevice.ad53xx" and v["class"] == "AD53xx") or \
|
elif (v["module"] == "artiq.coredevice.ad53xx" and v["class"] == "AD53xx") or \
|
||||||
(v["module"] == "artiq.coredevice.zotino" and v["class"] == "Zotino"):
|
(v["module"] == "artiq.coredevice.zotino" and v["class"] == "Zotino"):
|
||||||
|
@ -572,14 +566,15 @@ class _DeviceManager:
|
||||||
scheduling["flush"])
|
scheduling["flush"])
|
||||||
logger.info("Submitted '%s', RID is %d", title, rid)
|
logger.info("Submitted '%s', RID is %d", title, rid)
|
||||||
|
|
||||||
def _dds_faux_injection(self, dds_channel, dds_model, action, title, log_msg):
|
def _dds_faux_injection(self, dds_channel, action, title, log_msg):
|
||||||
|
handler = self.handlers_by_uid[dds_channel]
|
||||||
# create kernel and fill it in and send-by-content
|
# create kernel and fill it in and send-by-content
|
||||||
|
|
||||||
# initialize CPLD (if applicable)
|
# initialize CPLD (if applicable)
|
||||||
if dds_model.is_urukul:
|
if handler.is_urukul:
|
||||||
# urukuls need CPLD init and switch to on
|
# urukuls need CPLD init and switch to on
|
||||||
cpld_dev = """self.setattr_device("core_cache")
|
cpld_dev = """self.setattr_device("core_cache")
|
||||||
self.setattr_device("{}")""".format(dds_model.cpld)
|
self.setattr_device("{}")""".format(handler.cpld)
|
||||||
|
|
||||||
# `sta`/`rf_sw`` variables are guaranteed for urukuls
|
# `sta`/`rf_sw`` variables are guaranteed for urukuls
|
||||||
# so {action} can use it
|
# so {action} can use it
|
||||||
|
@ -593,20 +588,20 @@ class _DeviceManager:
|
||||||
delay(15*ms)
|
delay(15*ms)
|
||||||
self.{cpld}.init()
|
self.{cpld}.init()
|
||||||
self.core_cache.put("_{cpld}_init", [1])
|
self.core_cache.put("_{cpld}_init", [1])
|
||||||
""".format(cpld=dds_model.cpld)
|
""".format(cpld=handler.cpld)
|
||||||
else:
|
else:
|
||||||
cpld_dev = ""
|
cpld_dev = ""
|
||||||
cpld_init = ""
|
cpld_init = ""
|
||||||
|
|
||||||
# AD9912/9910: init channel (if uninitialized)
|
# AD9912/9910: init channel (if uninitialized)
|
||||||
if dds_model.dds_type == "AD9912":
|
if handler.dds_type == "AD9912":
|
||||||
# 0xFF before init, 0x99 after
|
# 0xFF before init, 0x99 after
|
||||||
channel_init = """
|
channel_init = """
|
||||||
if self.{dds_channel}.read({cfgreg}, length=1) == 0xFF:
|
if self.{dds_channel}.read({cfgreg}, length=1) == 0xFF:
|
||||||
delay(10*ms)
|
delay(10*ms)
|
||||||
self.{dds_channel}.init()
|
self.{dds_channel}.init()
|
||||||
""".format(dds_channel=dds_channel, cfgreg=AD9912_SER_CONF)
|
""".format(dds_channel=dds_channel, cfgreg=AD9912_SER_CONF)
|
||||||
elif dds_model.dds_type == "AD9910":
|
elif handler.dds_type == "AD9910":
|
||||||
# -1 before init, 2 after
|
# -1 before init, 2 after
|
||||||
channel_init = """
|
channel_init = """
|
||||||
if self.{dds_channel}.read32({cfgreg}) == -1:
|
if self.{dds_channel}.read32({cfgreg}) == -1:
|
||||||
|
@ -644,22 +639,23 @@ class _DeviceManager:
|
||||||
title,
|
title,
|
||||||
log_msg))
|
log_msg))
|
||||||
|
|
||||||
def dds_set_frequency(self, dds_channel, dds_model, freq):
|
def dds_set_frequency(self, dds_channel, freq):
|
||||||
|
handler = self.handlers_by_uid[dds_channel]
|
||||||
action = "self.{ch}.set({freq})".format(
|
action = "self.{ch}.set({freq})".format(
|
||||||
freq=freq, ch=dds_channel)
|
freq=freq, ch=dds_channel)
|
||||||
if dds_model.is_urukul:
|
if handler.is_urukul:
|
||||||
action += """
|
action += """
|
||||||
ch_no = self.{ch}.chip_select - 4
|
ch_no = self.{ch}.chip_select - 4
|
||||||
self.{cpld}.cfg_switches(rf_sw | 1 << ch_no)
|
self.{cpld}.cfg_switches(rf_sw | 1 << ch_no)
|
||||||
""".format(ch=dds_channel, cpld=dds_model.cpld)
|
""".format(ch=dds_channel, cpld=handler.cpld)
|
||||||
self._dds_faux_injection(
|
self._dds_faux_injection(
|
||||||
dds_channel,
|
dds_channel,
|
||||||
dds_model,
|
|
||||||
action,
|
action,
|
||||||
"SetDDS",
|
"SetDDS",
|
||||||
"Set DDS {} {}MHz".format(dds_channel, freq / 1e6))
|
"Set DDS {} {}MHz".format(dds_channel, freq / 1e6))
|
||||||
|
|
||||||
def dds_channel_toggle(self, dds_channel, dds_model, sw=True):
|
def dds_channel_toggle(self, dds_channel, sw=True):
|
||||||
|
handler = self.handlers_by_uid[dds_channel]
|
||||||
# urukul only
|
# urukul only
|
||||||
if sw:
|
if sw:
|
||||||
switch = "| 1 << ch_no"
|
switch = "| 1 << ch_no"
|
||||||
|
@ -670,12 +666,11 @@ class _DeviceManager:
|
||||||
self.{cpld}.cfg_switches(rf_sw {switch})
|
self.{cpld}.cfg_switches(rf_sw {switch})
|
||||||
""".format(
|
""".format(
|
||||||
dds_channel=dds_channel,
|
dds_channel=dds_channel,
|
||||||
cpld=dds_model.cpld,
|
cpld=handler.cpld,
|
||||||
switch=switch
|
switch=switch
|
||||||
)
|
)
|
||||||
self._dds_faux_injection(
|
self._dds_faux_injection(
|
||||||
dds_channel,
|
dds_channel,
|
||||||
dds_model,
|
|
||||||
action,
|
action,
|
||||||
"ToggleDDS",
|
"ToggleDDS",
|
||||||
"Toggle DDS {} {}".format(dds_channel, "on" if sw else "off"))
|
"Toggle DDS {} {}".format(dds_channel, "on" if sw else "off"))
|
||||||
|
@ -707,7 +702,7 @@ class _DeviceManager:
|
||||||
handler.refresh_display()
|
handler.refresh_display()
|
||||||
elif (channel, probe) in self.dds_handlers:
|
elif (channel, probe) in self.dds_handlers:
|
||||||
handler = self.dds_handlers[(channel, probe)]
|
handler = self.dds_handlers[(channel, probe)]
|
||||||
handler.dds_model.monitor_update(probe, value)
|
handler.monitor_update(probe, value)
|
||||||
handler.refresh_display()
|
handler.refresh_display()
|
||||||
elif (channel, probe) in self.dac_handlers:
|
elif (channel, probe) in self.dac_handlers:
|
||||||
handler = self.dac_handlers[(channel, probe)]
|
handler = self.dac_handlers[(channel, probe)]
|
||||||
|
|
Loading…
Reference in New Issue