From e80a527f2eca6a980b447034e776d673e358a269 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 26 Oct 2017 02:26:59 +0800 Subject: [PATCH] dashboard: add DAC monitoring widgets --- artiq/dashboard/moninj.py | 91 ++++++++++++++++++++++++++----- artiq/frontend/artiq_dashboard.py | 2 +- 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/artiq/dashboard/moninj.py b/artiq/dashboard/moninj.py index 4a6f17706..7d553d762 100644 --- a/artiq/dashboard/moninj.py +++ b/artiq/dashboard/moninj.py @@ -1,5 +1,6 @@ import asyncio import logging +from itertools import chain from PyQt5 import QtCore, QtWidgets, QtGui @@ -130,13 +131,10 @@ class _TTLWidget(QtWidgets.QFrame): return self.channel -class _DDSWidget(QtWidgets.QFrame): - def __init__(self, bus_channel, channel, title): +class _SimpleDisplayWidget(QtWidgets.QFrame): + def __init__(self, title): QtWidgets.QFrame.__init__(self) - self.bus_channel = bus_channel - self.channel = channel - self.setFrameShape(QtWidgets.QFrame.Box) self.setFrameShadow(QtWidgets.QFrame.Raised) @@ -159,9 +157,22 @@ class _DDSWidget(QtWidgets.QFrame): grid.setRowStretch(2, 0) grid.setRowStretch(3, 1) - self.cur_frequency = 0 self.refresh_display() + def refresh_display(self): + raise NotImplementedError + + def sort_key(self): + raise NotImplementedError + + +class _DDSWidget(_SimpleDisplayWidget): + def __init__(self, bus_channel, channel, title): + self.bus_channel = bus_channel + self.channel = channel + self.cur_frequency = 0 + _SimpleDisplayWidget.__init__(self, title) + def refresh_display(self): self.value.setText("{:.7f} MHz" .format(self.cur_frequency/1e6)) @@ -170,6 +181,21 @@ class _DDSWidget(QtWidgets.QFrame): return (self.bus_channel, self.channel) +class _DACWidget(_SimpleDisplayWidget): + def __init__(self, spi_channel, channel, title): + self.spi_channel = spi_channel + self.channel = channel + self.cur_value = 0 + _SimpleDisplayWidget.__init__(self, "{} ch{}".format(title, channel)) + + def refresh_display(self): + self.value.setText("{:.3f} %" + .format(self.cur_value*100/2**16)) + + def sort_key(self): + return (self.spi_channel, self.channel) + + class _DeviceManager: def __init__(self, init): self.core_addr = None @@ -184,6 +210,9 @@ class _DeviceManager: self.dds_cb = lambda: None self.dds_widgets = dict() self.dds_widgets_by_channel = dict() + self.dac_cb = lambda: None + self.dac_widgets = dict() + self.dac_widgets_by_channel = dict() for k, v in init.items(): self[k] = v @@ -192,11 +221,13 @@ class _DeviceManager: del self[k] if k in self.dds_widgets: del self[k] + if k in self.dac_widgets: + del self[k] if not isinstance(v, dict): return + widgets = [] try: if v["type"] == "local": - widget = None if k == "core": self.core_addr = v["arguments"]["host"] self.new_core_addr.set() @@ -209,6 +240,7 @@ class _DeviceManager: self.ttl_widgets_by_channel[channel] = widget self.ttl_cb() self.setup_ttl_monitoring(True, channel) + widgets.append(widget) elif (v["module"] == "artiq.coredevice.dds" and v["class"] == "DDSGroupAD9914"): self.dds_sysclk = v["arguments"]["sysclk"] @@ -221,10 +253,22 @@ class _DeviceManager: self.dds_widgets_by_channel[(bus_channel, channel)] = widget self.dds_cb() self.setup_dds_monitoring(True, bus_channel, channel) - if widget is not None and "comment" in v: - widget.setToolTip(v["comment"]) + widgets.append(widget) + elif (v["module"] == "artiq.coredevice.ad5360" + and v["class"] == "AD5360"): + spi_channel = 27 # TODO/FIXME + for channel in range(32): + widget = _DACWidget(spi_channel, channel, k) + self.dac_widgets_by_channel[(spi_channel, channel)] = widget + self.setup_dds_monitoring(True, spi_channel, channel) + widgets.append(widget) + self.dac_widgets[k+str(channel)] = widgets + self.dac_cb() except KeyError: pass + if "comment" in v: + for widget in widgets: + widget.setToolTip(v["comment"]) def __delitem__(self, k): if k in self.ttl_widgets: @@ -241,6 +285,13 @@ class _DeviceManager: del self.dds_widgets_by_channel[(widget.bus_channel, widget.channel)] del self.dds_widgets[k] self.dds_cb() + if k in self.dac_widgets: + for widget in self.dac_widgets[k]: + self.setup_dac_monitoring(False, widget.spi_channel, widget.channel) + widget.deleteLater() + del self.dac_widgets_by_channel[(widget.spi_channel, widget.channel)] + del self.dac_widgets[k] + self.dds_cb() def ttl_set_mode(self, channel, mode): if self.core_connection is not None: @@ -276,6 +327,10 @@ class _DeviceManager: if self.core_connection is not None: self.core_connection.monitor(enable, bus_channel, channel) + def setup_dac_monitoring(self, enable, spi_channel, channel): + if self.core_connection is not None: + self.core_connection.monitor(enable, spi_channel, channel) + def monitor_cb(self, channel, probe, value): if channel in self.ttl_widgets_by_channel: widget = self.ttl_widgets_by_channel[channel] @@ -288,6 +343,10 @@ class _DeviceManager: widget = self.dds_widgets_by_channel[(channel, probe)] widget.cur_frequency = value*self.dds_sysclk/2**32 widget.refresh_display() + if (channel, probe) in self.dac_widgets_by_channel: + widget = self.dac_widgets_by_channel[(channel, probe)] + widget.cur_value = value + widget.refresh_display() def injection_status_cb(self, channel, override, value): if channel in self.ttl_widgets_by_channel: @@ -312,6 +371,8 @@ class _DeviceManager: self.setup_ttl_monitoring(True, ttl_channel) for bus_channel, channel in self.dds_widgets_by_channel.keys(): self.setup_dds_monitoring(True, bus_channel, channel) + for spi_channel, channel in self.dac_widgets_by_channel.keys(): + self.setup_dac_monitoring(True, spi_channel, channel) async def close(self): self.core_connector_task.cancel() @@ -339,8 +400,8 @@ class _MonInjDock(QtWidgets.QDockWidget): grid_widget = QtWidgets.QWidget() grid_widget.setLayout(grid) - for _, w in sorted(widgets, key=lambda i: i[1].sort_key()): - grid.addWidget(w) + for widget in sorted(widgets, key=lambda w: w.sort_key()): + grid.addWidget(widget) scroll_area.setWidgetResizable(True) scroll_area.setWidget(grid_widget) @@ -350,6 +411,7 @@ class MonInj: def __init__(self): self.ttl_dock = _MonInjDock("TTL") self.dds_dock = _MonInjDock("DDS") + self.dac_dock = _MonInjDock("DAC") self.subscriber = Subscriber("devices", self.init_devices) self.dm = None @@ -365,9 +427,12 @@ class MonInj: def init_devices(self, d): self.dm = _DeviceManager(d) self.dm.ttl_cb = lambda: self.ttl_dock.layout_widgets( - self.dm.ttl_widgets.items()) + self.dm.ttl_widgets.values()) self.dm.dds_cb = lambda: self.dds_dock.layout_widgets( - self.dm.dds_widgets.items()) + self.dm.dds_widgets.values()) + self.dm.dac_cb = lambda: self.dac_dock.layout_widgets( + chain(*self.dm.dac_widgets.values())) self.dm.ttl_cb() self.dm.dds_cb() + self.dm.dac_cb() return self.dm diff --git a/artiq/frontend/artiq_dashboard.py b/artiq/frontend/artiq_dashboard.py index b3a06ddbf..18dd2b9fb 100755 --- a/artiq/frontend/artiq_dashboard.py +++ b/artiq/frontend/artiq_dashboard.py @@ -185,7 +185,7 @@ def main(): # lay out docks right_docks = [ d_explorer, d_shortcuts, - d_ttl_dds.ttl_dock, d_ttl_dds.dds_dock, + d_ttl_dds.ttl_dock, d_ttl_dds.dds_dock, d_ttl_dds.dac_dock, d_datasets, d_applets ] main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_docks[0])