]> sigrok.org Git - libsigrok.git/commitdiff
Rename rigol-ds1xx2 driver to rigol-ds.
authorMartin Ling <redacted>
Thu, 31 Oct 2013 17:31:39 +0000 (17:31 +0000)
committerMartin Ling <redacted>
Fri, 29 Nov 2013 00:50:59 +0000 (00:50 +0000)
13 files changed:
README.devices
configure.ac
contrib/gnuplot_rigol_ds1xx2.gpi
hardware/Makefile.am
hardware/rigol-ds/Makefile.am [new file with mode: 0644]
hardware/rigol-ds/api.c [new file with mode: 0644]
hardware/rigol-ds/protocol.c [new file with mode: 0644]
hardware/rigol-ds/protocol.h [new file with mode: 0644]
hardware/rigol-ds1xx2/Makefile.am [deleted file]
hardware/rigol-ds1xx2/api.c [deleted file]
hardware/rigol-ds1xx2/protocol.c [deleted file]
hardware/rigol-ds1xx2/protocol.h [deleted file]
hwdriver.c

index f28462a02977a2dc2d5da968fd98d7ed0be67e8d..a99fc7e2e95f8fb0e9783e99c7adf8f0022b533c 100644 (file)
@@ -66,7 +66,7 @@ The following drivers/devices do not need any firmware upload:
  - mic-985xx
  - norma-dmm
  - openbench-logic-sniffer
  - mic-985xx
  - norma-dmm
  - openbench-logic-sniffer
- - rigol-ds1xx2
+ - rigol-ds
  - serial-dmm
  - teleinfo
  - tondaj-sl-814
  - serial-dmm
  - teleinfo
  - tondaj-sl-814
@@ -118,7 +118,7 @@ The following drivers/devices do not require a serial port specification:
  - ikalogic-scanaplus
  - kecheng-kc-330b
  - lascar-el-usb
  - ikalogic-scanaplus
  - kecheng-kc-330b
  - lascar-el-usb
- - rigol-ds1xx2
+ - rigol-ds
  - saleae-logic16
  - uni-t-dmm
  - uni-t-ut32x
  - saleae-logic16
  - uni-t-dmm
  - uni-t-ut32x
@@ -344,12 +344,12 @@ Example:
  $ sigrok-cli --driver ols:conn=/dev/ttyACM0 ...
 
 
  $ sigrok-cli --driver ols:conn=/dev/ttyACM0 ...
 
 
-Rigol DS1xx2 oscilloscopes
---------------------------
+Rigol DS oscilloscopes
+----------------------
 
 
-The 'rigol-ds1xx2' driver (for the Rigol DS1052E and some other, similar DSOs)
-currently uses the Linux usbtmc kernel driver. This means it can currently
-only be built and used on Linux (i.e., it's non-portable).
+The 'rigol-ds' driver (for the Rigol DS series DSOs) currently uses the Linux
+usbtmc kernel driver. This means it can currently only be built and used on
+Linux (i.e., it's non-portable).
 
 The use of a kernel module also means it is dependent on the kernel version
 used, as well as on whether this specific module is available in the kernel.
 
 The use of a kernel module also means it is dependent on the kernel version
 used, as well as on whether this specific module is available in the kernel.
@@ -360,4 +360,3 @@ module as opposed to a libusb-based driver that works in user-space.
 We plan to change the driver to use the 'librevisa' user-space shared
 library (which uses libusb) soon, which will fix all these issues and make
 the driver portable at the same time.
 We plan to change the driver to use the 'librevisa' user-space shared
 library (which uses libusb) soon, which will fix all these issues and make
 the driver portable at the same time.
-
index 29880ee5d9041993d4f124c70dc4f134320ab690..c1c4aedce85a2bcf392b99d61199bdde8c7be75e 100644 (file)
@@ -189,10 +189,10 @@ AC_ARG_ENABLE(ols, AC_HELP_STRING([--enable-ols],
        [HW_OLS="$enableval"],
        [HW_OLS=$HW_ENABLED_DEFAULT])
 
        [HW_OLS="$enableval"],
        [HW_OLS=$HW_ENABLED_DEFAULT])
 
-AC_ARG_ENABLE(rigol-ds1xx2, AC_HELP_STRING([--enable-rigol-ds1xx2],
-       [enable Rigol DS1xx2 support [default=yes]]),
-       [HW_RIGOL_DS1XX2="$enableval"],
-       [HW_RIGOL_DS1XX2=$HW_ENABLED_DEFAULT])
+AC_ARG_ENABLE(rigol-ds, AC_HELP_STRING([--enable-rigol-ds],
+       [enable Rigol DS support [default=yes]]),
+       [HW_RIGOL_DS="$enableval"],
+       [HW_RIGOL_DS=$HW_ENABLED_DEFAULT])
 
 AC_ARG_ENABLE(saleae-logic16, AC_HELP_STRING([--enable-saleae-logic16],
        [enable Saleae Logic16 support [default=yes]]),
 
 AC_ARG_ENABLE(saleae-logic16, AC_HELP_STRING([--enable-saleae-logic16],
        [enable Saleae Logic16 support [default=yes]]),
@@ -334,18 +334,18 @@ PKG_CHECK_MODULES([check], [check >= 0.9.4],
        LIBS="$LIBS $check_LIBS"], [have_check="no"])
 AM_CONDITIONAL(HAVE_CHECK, test x"$have_check" = "xyes")
 
        LIBS="$LIBS $check_LIBS"], [have_check="no"])
 AM_CONDITIONAL(HAVE_CHECK, test x"$have_check" = "xyes")
 
-# The Rigol DS1xx2 driver currently uses the Linux kernel usbtmc module
+# The Rigol DS driver currently uses the Linux kernel usbtmc module
 # (though it is planned to rewrite the driver to be portable later).
 # Thus, it will be disabled for non-Linux builds for now.
 case "$host" in
 *linux*)
        # Do nothing. Whether the driver is enabled is determined by the
        # previous --enable-all-drivers/--disable-all-drivers and/or any
 # (though it is planned to rewrite the driver to be portable later).
 # Thus, it will be disabled for non-Linux builds for now.
 case "$host" in
 *linux*)
        # Do nothing. Whether the driver is enabled is determined by the
        # previous --enable-all-drivers/--disable-all-drivers and/or any
-       # --enable-rigol-ds1xx2/--disable-rigol-ds1xx2 options.
+       # --enable-rigol-ds/--disable-rigol-ds options.
        ;;
 *)
        # Disable the driver for builds that don't target Linux.
        ;;
 *)
        # Disable the driver for builds that don't target Linux.
-       HW_RIGOL_DS1XX2="no"
+       HW_RIGOL_DS="no"
        ;;
 esac
 
        ;;
 esac
 
@@ -458,9 +458,9 @@ if test "x$HW_OLS" = "xyes"; then
        AC_DEFINE(HAVE_HW_OLS, 1, [OpenBench Logic Sniffer (OLS) support])
 fi
 
        AC_DEFINE(HAVE_HW_OLS, 1, [OpenBench Logic Sniffer (OLS) support])
 fi
 
-AM_CONDITIONAL(HW_RIGOL_DS1XX2, test x$HW_RIGOL_DS1XX2 = xyes)
-if test "x$HW_RIGOL_DS1XX2" = "xyes"; then
-       AC_DEFINE(HAVE_HW_RIGOL_DS1XX2, 1, [Rigol DS1xx2 support])
+AM_CONDITIONAL(HW_RIGOL_DS, test x$HW_RIGOL_DS = xyes)
+if test "x$HW_RIGOL_DS" = "xyes"; then
+       AC_DEFINE(HAVE_HW_RIGOL_DS, 1, [Rigol DS support])
 fi
 
 AM_CONDITIONAL(HW_SALEAE_LOGIC16, test x$HW_SALEAE_LOGIC16 = xyes)
 fi
 
 AM_CONDITIONAL(HW_SALEAE_LOGIC16, test x$HW_SALEAE_LOGIC16 = xyes)
@@ -553,7 +553,7 @@ AC_CONFIG_FILES([Makefile version.h hardware/Makefile
                 hardware/kecheng-kc-330b/Makefile
                 hardware/lascar-el-usb/Makefile
                 hardware/mic-985xx/Makefile
                 hardware/kecheng-kc-330b/Makefile
                 hardware/lascar-el-usb/Makefile
                 hardware/mic-985xx/Makefile
-                hardware/rigol-ds1xx2/Makefile
+                hardware/rigol-ds/Makefile
                 hardware/saleae-logic16/Makefile
                 hardware/teleinfo/Makefile
                 hardware/tondaj-sl-814/Makefile
                 hardware/saleae-logic16/Makefile
                 hardware/teleinfo/Makefile
                 hardware/tondaj-sl-814/Makefile
@@ -625,7 +625,7 @@ echo "  - link-mso19 (EXPERIMENTAL)....... $HW_LINK_MSO19"
 echo "  - mic-985xx....................... $HW_MIC_985XX"
 echo "  - norma-dmm....................... $HW_NORMA_DMM"
 echo "  - openbench-logic-sniffer......... $HW_OLS"
 echo "  - mic-985xx....................... $HW_MIC_985XX"
 echo "  - norma-dmm....................... $HW_NORMA_DMM"
 echo "  - openbench-logic-sniffer......... $HW_OLS"
-echo "  - rigol-ds1xx2.................... $HW_RIGOL_DS1XX2"
+echo "  - rigol-ds........................ $HW_RIGOL_DS"
 echo "  - saleae-logic16.................. $HW_SALEAE_LOGIC16"
 echo "  - serial-dmm...................... $HW_SERIAL_DMM"
 echo "  - teleinfo........................ $HW_TELEINFO"
 echo "  - saleae-logic16.................. $HW_SALEAE_LOGIC16"
 echo "  - serial-dmm...................... $HW_SERIAL_DMM"
 echo "  - teleinfo........................ $HW_TELEINFO"
index 6800158b1a0490eb8cc9c5972d8428dcb07fbc72..a598b9ebc10bcc825b03cb5ccd7f1ae0bedd2246 100644 (file)
@@ -30,7 +30,7 @@ set output "sigrok_gnuplot.png"
 # Rigol DS1xx2 output is currently always 600 samples in size.
 # This script currently also assumes only one channel is acquired like this:
 #
 # Rigol DS1xx2 output is currently always 600 samples in size.
 # This script currently also assumes only one channel is acquired like this:
 #
-#   $ sigrok-cli --driver rigol-ds1xx2 --frames 1 -p CH1 ...
+#   $ sigrok-cli --driver rigol-ds --frames 1 -p CH1 ...
 #
 plot [0:600] \
 "sigrok_gnuplot.dat" using 1 with lines linewidth 2 title "CH1"
 #
 plot [0:600] \
 "sigrok_gnuplot.dat" using 1 with lines linewidth 2 title "CH1"
index 27735af6ffa21b7d5caf39b67972bd2e9ba4ed66..fec45790c0de35f9b443887901374e851aadb82f 100644 (file)
@@ -41,7 +41,7 @@ SUBDIRS = \
        mic-985xx \
        norma-dmm \
        openbench-logic-sniffer \
        mic-985xx \
        norma-dmm \
        openbench-logic-sniffer \
-       rigol-ds1xx2 \
+       rigol-ds \
        saleae-logic16 \
        serial-dmm \
        teleinfo \
        saleae-logic16 \
        serial-dmm \
        teleinfo \
@@ -142,8 +142,8 @@ if HW_OLS
 libsigrokhardware_la_LIBADD += openbench-logic-sniffer/libsigrok_hw_ols.la
 endif
 
 libsigrokhardware_la_LIBADD += openbench-logic-sniffer/libsigrok_hw_ols.la
 endif
 
-if HW_RIGOL_DS1XX2
-libsigrokhardware_la_LIBADD += rigol-ds1xx2/libsigrok_hw_rigol_ds1xx2.la
+if HW_RIGOL_DS
+libsigrokhardware_la_LIBADD += rigol-ds/libsigrok_hw_rigol_ds.la
 endif
 
 if HW_SALEAE_LOGIC16
 endif
 
 if HW_SALEAE_LOGIC16
diff --git a/hardware/rigol-ds/Makefile.am b/hardware/rigol-ds/Makefile.am
new file mode 100644 (file)
index 0000000..fba4226
--- /dev/null
@@ -0,0 +1,33 @@
+##
+## This file is part of the libsigrok project.
+##
+## Copyright (C) 2012 Martin Ling <martin-git@earth.li>
+##
+## This program is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+if HW_RIGOL_DS
+
+# Local lib, this is NOT meant to be installed!
+noinst_LTLIBRARIES = libsigrok_hw_rigol_ds.la
+
+libsigrok_hw_rigol_ds_la_SOURCES = \
+       api.c \
+       protocol.c \
+       protocol.h
+
+libsigrok_hw_rigol_ds_la_CFLAGS = \
+       -I$(top_srcdir)
+
+endif
diff --git a/hardware/rigol-ds/api.c b/hardware/rigol-ds/api.c
new file mode 100644 (file)
index 0000000..e0f4eae
--- /dev/null
@@ -0,0 +1,758 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
+ * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+#include "protocol.h"
+
+#define NUM_TIMEBASE  12
+#define NUM_VDIV      8
+
+static const int32_t hwopts[] = {
+       SR_CONF_CONN,
+};
+
+static const int32_t hwcaps[] = {
+       SR_CONF_OSCILLOSCOPE,
+       SR_CONF_TIMEBASE,
+       SR_CONF_TRIGGER_SOURCE,
+       SR_CONF_TRIGGER_SLOPE,
+       SR_CONF_HORIZ_TRIGGERPOS,
+       SR_CONF_NUM_TIMEBASE,
+};
+
+static const int32_t analog_hwcaps[] = {
+       SR_CONF_NUM_VDIV,
+       SR_CONF_VDIV,
+       SR_CONF_COUPLING,
+};
+
+static const uint64_t timebases[][2] = {
+       /* nanoseconds */
+       { 2, 1000000000 },
+       { 5, 1000000000 },
+       { 10, 1000000000 },
+       { 20, 1000000000 },
+       { 50, 1000000000 },
+       { 100, 1000000000 },
+       { 500, 1000000000 },
+       /* microseconds */
+       { 1, 1000000 },
+       { 2, 1000000 },
+       { 5, 1000000 },
+       { 10, 1000000 },
+       { 20, 1000000 },
+       { 50, 1000000 },
+       { 100, 1000000 },
+       { 200, 1000000 },
+       { 500, 1000000 },
+       /* milliseconds */
+       { 1, 1000 },
+       { 2, 1000 },
+       { 5, 1000 },
+       { 10, 1000 },
+       { 20, 1000 },
+       { 50, 1000 },
+       { 100, 1000 },
+       { 200, 1000 },
+       { 500, 1000 },
+       /* seconds */
+       { 1, 1 },
+       { 2, 1 },
+       { 5, 1 },
+       { 10, 1 },
+       { 20, 1 },
+       { 50, 1 },
+};
+
+static const uint64_t vdivs[][2] = {
+       /* millivolts */
+       { 2, 1000 },
+       { 5, 1000 },
+       { 10, 1000 },
+       { 20, 1000 },
+       { 50, 1000 },
+       { 100, 1000 },
+       { 200, 1000 },
+       { 500, 1000 },
+       /* volts */
+       { 1, 1 },
+       { 2, 1 },
+       { 5, 1 },
+       { 10, 1 },
+};
+
+static const char *trigger_sources[] = {
+       "CH1",
+       "CH2",
+       "EXT",
+       "AC Line",
+       "D0",
+       "D1",
+       "D2",
+       "D3",
+       "D4",
+       "D5",
+       "D6",
+       "D7",
+       "D8",
+       "D9",
+       "D10",
+       "D11",
+       "D12",
+       "D13",
+       "D14",
+       "D15",
+};
+
+static const char *coupling[] = {
+       "AC",
+       "DC",
+       "GND",
+};
+
+static const char *supported_models[] = {
+       "DS1052E",
+       "DS1102E",
+       "DS1152E",
+       "DS1052D",
+       "DS1102D",
+       "DS1152D",
+};
+
+SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
+static struct sr_dev_driver *di = &rigol_ds_driver_info;
+
+static void clear_helper(void *priv)
+{
+       struct dev_context *devc;
+
+       devc = priv;
+       g_free(devc->coupling[0]);
+       g_free(devc->coupling[1]);
+       g_free(devc->trigger_source);
+       g_free(devc->trigger_slope);
+       g_slist_free(devc->analog_groups[0].probes);
+       g_slist_free(devc->analog_groups[1].probes);
+       g_slist_free(devc->digital_group.probes);
+}
+
+static int dev_clear(void)
+{
+       return std_dev_clear(di, clear_helper);
+}
+
+static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
+{
+       va_list args;
+       char buf[256];
+
+       va_start(args, format);
+       vsnprintf(buf, 255, format, args);
+       va_end(args);
+       if (rigol_ds_send(sdi, buf) != SR_OK)
+               return SR_ERR;
+
+       /* When setting a bunch of parameters in a row, the DS1052E scrambles
+        * some of them unless there is at least 100ms delay in between. */
+       sr_spew("delay %dms", 100);
+       g_usleep(100000);
+
+       return SR_OK;
+}
+
+static int init(struct sr_context *sr_ctx)
+{
+       return std_init(sr_ctx, di, LOG_PREFIX);
+}
+
+static int probe_port(const char *port, GSList **devices)
+{
+       struct dev_context *devc;
+       struct sr_dev_inst *sdi;
+       struct sr_serial_dev_inst *serial;
+       struct sr_probe *probe;
+       unsigned int i;
+       int len, num_tokens;
+       gboolean matched, has_digital;
+       const char *manufacturer, *model, *version;
+       char buf[256];
+       gchar **tokens, *channel_name;
+
+       *devices = NULL;
+       if (!(serial = sr_serial_dev_inst_new(port, NULL)))
+               return SR_ERR_MALLOC;
+
+       if (serial_open(serial, SERIAL_RDWR) != SR_OK)
+               return SR_ERR;
+       len = serial_write(serial, "*IDN?", 5);
+       len = serial_read(serial, buf, sizeof(buf));
+       if (serial_close(serial) != SR_OK)
+               return SR_ERR;
+
+       sr_serial_dev_inst_free(serial);
+
+       if (len == 0)
+               return SR_ERR_NA;
+
+       buf[len] = 0;
+       tokens = g_strsplit(buf, ",", 0);
+       sr_dbg("response: %s [%s]", port, buf);
+
+       for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
+
+       if (num_tokens < 4) {
+               g_strfreev(tokens);
+               return SR_ERR_NA;
+       }
+
+       manufacturer = tokens[0];
+       model = tokens[1];
+       version = tokens[3];
+
+       if (strcmp(manufacturer, "Rigol Technologies")) {
+               g_strfreev(tokens);
+               return SR_ERR_NA;
+       }
+
+       matched = has_digital = FALSE;
+       for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
+               if (!strcmp(model, supported_models[i])) {
+                       matched = TRUE;
+                       has_digital = g_str_has_suffix(model, "D");
+                       break;
+               }
+       }
+
+       if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
+               manufacturer, model, version))) {
+               g_strfreev(tokens);
+               return SR_ERR_NA;
+       }
+
+       g_strfreev(tokens);
+
+       if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
+               return SR_ERR_MALLOC;
+       sdi->driver = di;
+       sdi->inst_type = SR_INST_SERIAL;
+
+       if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
+               return SR_ERR_MALLOC;
+       devc->limit_frames = 0;
+       devc->has_digital = has_digital;
+
+       for (i = 0; i < 2; i++) {
+               channel_name = (i == 0 ? "CH1" : "CH2");
+               if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name)))
+                       return SR_ERR_MALLOC;
+               sdi->probes = g_slist_append(sdi->probes, probe);
+               devc->analog_groups[i].name = channel_name;
+               devc->analog_groups[i].probes = g_slist_append(NULL, probe);
+               sdi->probe_groups = g_slist_append(sdi->probe_groups,
+                               &devc->analog_groups[i]);
+       }
+
+       if (devc->has_digital) {
+               for (i = 0; i < 16; i++) {
+                       if (!(channel_name = g_strdup_printf("D%d", i)))
+                               return SR_ERR_MALLOC;
+                       probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
+                       g_free(channel_name);
+                       if (!probe)
+                               return SR_ERR_MALLOC;
+                       sdi->probes = g_slist_append(sdi->probes, probe);
+                       devc->digital_group.probes = g_slist_append(
+                                       devc->digital_group.probes, probe);
+                       devc->digital_group.name = "LA";
+                       sdi->probe_groups = g_slist_append(sdi->probe_groups,
+                                       &devc->digital_group);
+               }
+       }
+       sdi->priv = devc;
+
+       *devices = g_slist_append(NULL, sdi);
+
+       return SR_OK;
+}
+
+static GSList *scan(GSList *options)
+{
+       struct drv_context *drvc;
+       struct sr_config *src;
+       GSList *l, *devices;
+       GDir *dir;
+       int ret;
+       const gchar *dev_name;
+       gchar *port = NULL;
+
+       drvc = di->priv;
+
+       for (l = options; l; l = l->next) {
+               src = l->data;
+               if (src->key == SR_CONF_CONN) {
+                       port = (char *)g_variant_get_string(src->data, NULL);
+                       break;
+               }
+       }
+
+       devices = NULL;
+       if (port) {
+               if (probe_port(port, &devices) == SR_ERR_MALLOC)
+                       return NULL;
+       } else {
+               if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
+                       if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
+                               return NULL;
+               while ((dev_name = g_dir_read_name(dir))) {
+                       if (strncmp(dev_name, "usbtmc", 6))
+                               continue;
+                       port = g_strconcat("/dev/", dev_name, NULL);
+                       ret = probe_port(port, &devices);
+                       g_free(port);
+                       if (ret == SR_ERR_MALLOC) {
+                               g_dir_close(dir);
+                               return NULL;
+                       }
+               }
+               g_dir_close(dir);
+       }
+
+       /* Tack a copy of the newly found devices onto the driver list. */
+       l = g_slist_copy(devices);
+       drvc->instances = g_slist_concat(drvc->instances, l);
+
+       return devices;
+}
+
+static GSList *dev_list(void)
+{
+       return ((struct drv_context *)(di->priv))->instances;
+}
+
+static int dev_open(struct sr_dev_inst *sdi)
+{
+
+       if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
+               return SR_ERR;
+
+       if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
+               return SR_ERR;
+
+       sdi->status = SR_ST_ACTIVE;
+
+       return SR_OK;
+}
+
+static int dev_close(struct sr_dev_inst *sdi)
+{
+       struct sr_serial_dev_inst *serial;
+
+       serial = sdi->conn;
+       if (serial && serial->fd != -1) {
+               serial_close(serial);
+               sdi->status = SR_ST_INACTIVE;
+       }
+
+       return SR_OK;
+}
+
+static int cleanup(void)
+{
+       return dev_clear();
+}
+
+static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
+               const struct sr_probe_group *probe_group)
+{
+       struct dev_context *devc;
+       unsigned int i;
+
+       if (!sdi || !(devc = sdi->priv))
+               return SR_ERR_ARG;
+
+       /* If a probe group is specified, it must be a valid one. */
+       if (probe_group) {
+               if (probe_group != &devc->analog_groups[0]
+                               && probe_group != &devc->analog_groups[1]) {
+                       sr_err("Invalid probe group specified.");
+                       return SR_ERR;
+               }
+       }
+
+       switch (id) {
+       case SR_CONF_NUM_TIMEBASE:
+               *data = g_variant_new_int32(NUM_TIMEBASE);
+               break;
+       case SR_CONF_NUM_VDIV:
+               if (!probe_group) {
+                       sr_err("No probe group specified.");
+                       return SR_ERR_PROBE_GROUP;
+               }
+               for (i = 0; i < 2; i++) {
+                       if (probe_group == &devc->analog_groups[i]) {
+                               *data = g_variant_new_int32(NUM_VDIV);
+                               return SR_OK;
+                       }
+               }
+               return SR_ERR_NA;
+       default:
+               return SR_ERR_NA;
+       }
+
+       return SR_OK;
+}
+
+static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
+               const struct sr_probe_group *probe_group)
+{
+       struct dev_context *devc;
+       uint64_t tmp_u64, p, q;
+       double t_dbl;
+       unsigned int i, j;
+       int ret;
+       const char *tmp_str;
+
+       if (!(devc = sdi->priv))
+               return SR_ERR_ARG;
+
+       if (sdi->status != SR_ST_ACTIVE)
+               return SR_ERR_DEV_CLOSED;
+
+       /* If a probe group is specified, it must be a valid one. */
+       if (probe_group) {
+               if (probe_group != &devc->analog_groups[0]
+                               && probe_group != &devc->analog_groups[1]) {
+                       sr_err("Invalid probe group specified.");
+                       return SR_ERR;
+               }
+       }
+
+       ret = SR_OK;
+       switch (id) {
+       case SR_CONF_LIMIT_FRAMES:
+               devc->limit_frames = g_variant_get_uint64(data);
+               break;
+       case SR_CONF_TRIGGER_SLOPE:
+               tmp_u64 = g_variant_get_uint64(data);
+               if (tmp_u64 != 0 && tmp_u64 != 1)
+                       return SR_ERR;
+               g_free(devc->trigger_slope);
+               devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
+               ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
+               break;
+       case SR_CONF_HORIZ_TRIGGERPOS:
+               t_dbl = g_variant_get_double(data);
+               if (t_dbl < 0.0 || t_dbl > 1.0)
+                       return SR_ERR;
+               devc->horiz_triggerpos = t_dbl;
+               /* We have the trigger offset as a percentage of the frame, but
+                * need to express this in seconds. */
+               t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
+               ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
+               break;
+       case SR_CONF_TIMEBASE:
+               g_variant_get(data, "(tt)", &p, &q);
+               for (i = 0; i < ARRAY_SIZE(timebases); i++) {
+                       if (timebases[i][0] == p && timebases[i][1] == q) {
+                               devc->timebase = (float)p / q;
+                               ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
+                               break;
+                       }
+               }
+               if (i == ARRAY_SIZE(timebases))
+                       ret = SR_ERR_ARG;
+               break;
+       case SR_CONF_TRIGGER_SOURCE:
+               tmp_str = g_variant_get_string(data, NULL);
+               for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
+                       if (!strcmp(trigger_sources[i], tmp_str)) {
+                               g_free(devc->trigger_source);
+                               devc->trigger_source = g_strdup(trigger_sources[i]);
+                               if (!strcmp(devc->trigger_source, "AC Line"))
+                                       tmp_str = "ACL";
+                               else if (!strcmp(devc->trigger_source, "CH1"))
+                                       tmp_str = "CHAN1";
+                               else if (!strcmp(devc->trigger_source, "CH2"))
+                                       tmp_str = "CHAN2";
+                               else
+                                       tmp_str = (char *)devc->trigger_source;
+                               ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
+                               break;
+                       }
+               }
+               if (i == ARRAY_SIZE(trigger_sources))
+                       ret = SR_ERR_ARG;
+               break;
+       case SR_CONF_VDIV:
+               if (!probe_group) {
+                       sr_err("No probe group specified.");
+                       return SR_ERR_PROBE_GROUP;
+               }
+               g_variant_get(data, "(tt)", &p, &q);
+               for (i = 0; i < 2; i++) {
+                       if (probe_group == &devc->analog_groups[i]) {
+                               for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
+                                       if (vdivs[j][0] != p || vdivs[j][1] != q)
+                                               continue;
+                                       devc->vdiv[i] = (float)p / q;
+                                       return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
+                                                       devc->vdiv[i]);
+                               }
+                               return SR_ERR_ARG;
+                       }
+               }
+               return SR_ERR_NA;
+       case SR_CONF_COUPLING:
+               if (!probe_group) {
+                       sr_err("No probe group specified.");
+                       return SR_ERR_PROBE_GROUP;
+               }
+               tmp_str = g_variant_get_string(data, NULL);
+               for (i = 0; i < 2; i++) {
+                       if (probe_group == &devc->analog_groups[i]) {
+                               for (j = 0; j < ARRAY_SIZE(coupling); j++) {
+                                       if (!strcmp(tmp_str, coupling[j])) {
+                                               g_free(devc->coupling[i]);
+                                               devc->coupling[i] = g_strdup(coupling[j]);
+                                               return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
+                                                               devc->coupling[i]);
+                                       }
+                               }
+                               return SR_ERR_ARG;
+                       }
+               }
+               return SR_ERR_NA;
+       default:
+               ret = SR_ERR_NA;
+               break;
+       }
+
+       return ret;
+}
+
+static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
+               const struct sr_probe_group *probe_group)
+{
+       GVariant *tuple, *rational[2];
+       GVariantBuilder gvb;
+       unsigned int i;
+       struct dev_context *devc;
+
+       if (key == SR_CONF_SCAN_OPTIONS) {
+               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
+                               hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
+               return SR_OK;
+       } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
+               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
+                       hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
+               return SR_OK;
+       }
+
+       /* Every other option requires a valid device instance. */
+       if (!sdi || !(devc = sdi->priv))
+               return SR_ERR_ARG;
+
+       /* If a probe group is specified, it must be a valid one. */
+       if (probe_group) {
+               if (probe_group != &devc->analog_groups[0]
+                               && probe_group != &devc->analog_groups[1]) {
+                       sr_err("Invalid probe group specified.");
+                       return SR_ERR;
+               }
+       }
+
+       switch (key) {
+               break;
+       case SR_CONF_DEVICE_OPTIONS:
+               if (!probe_group) {
+                       sr_err("No probe group specified.");
+                       return SR_ERR_PROBE_GROUP;
+               }
+               if (probe_group == &devc->digital_group) {
+                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
+                               NULL, 0, sizeof(int32_t));
+                       return SR_OK;
+               } else {
+                       for (i = 0; i < 2; i++) {
+                               if (probe_group == &devc->analog_groups[i]) {
+                                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
+                                               analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
+                                       return SR_OK;
+                               }
+                       }
+                       return SR_ERR_NA;
+               }
+               break;
+       case SR_CONF_COUPLING:
+               if (!probe_group) {
+                       sr_err("No probe group specified.");
+                       return SR_ERR_PROBE_GROUP;
+               }
+               *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
+               break;
+       case SR_CONF_VDIV:
+               if (!probe_group) {
+                       sr_err("No probe group specified.");
+                       return SR_ERR_PROBE_GROUP;
+               }
+               g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
+               for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
+                       rational[0] = g_variant_new_uint64(vdivs[i][0]);
+                       rational[1] = g_variant_new_uint64(vdivs[i][1]);
+                       tuple = g_variant_new_tuple(rational, 2);
+                       g_variant_builder_add_value(&gvb, tuple);
+               }
+               *data = g_variant_builder_end(&gvb);
+               break;
+       case SR_CONF_TIMEBASE:
+               g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
+               for (i = 0; i < ARRAY_SIZE(timebases); i++) {
+                       rational[0] = g_variant_new_uint64(timebases[i][0]);
+                       rational[1] = g_variant_new_uint64(timebases[i][1]);
+                       tuple = g_variant_new_tuple(rational, 2);
+                       g_variant_builder_add_value(&gvb, tuple);
+               }
+               *data = g_variant_builder_end(&gvb);
+               break;
+       case SR_CONF_TRIGGER_SOURCE:
+               *data = g_variant_new_strv(trigger_sources,
+                               devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
+               break;
+       default:
+               return SR_ERR_NA;
+       }
+
+       return SR_OK;
+}
+
+static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
+{
+       struct sr_serial_dev_inst *serial;
+       struct dev_context *devc;
+       struct sr_probe *probe;
+       GSList *l;
+       char cmd[256];
+
+       if (sdi->status != SR_ST_ACTIVE)
+               return SR_ERR_DEV_CLOSED;
+
+       serial = sdi->conn;
+       devc = sdi->priv;
+
+       for (l = sdi->probes; l; l = l->next) {
+               probe = l->data;
+               sr_dbg("handling probe %s", probe->name);
+               if (probe->type == SR_PROBE_ANALOG) {
+                       if (probe->enabled)
+                               devc->enabled_analog_probes = g_slist_append(
+                                               devc->enabled_analog_probes, probe);
+                       if (probe->enabled != devc->analog_channels[probe->index]) {
+                               /* Enabled channel is currently disabled, or vice versa. */
+                               sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
+                                               probe->enabled ? "ON" : "OFF");
+                               if (rigol_ds_send(sdi, cmd) != SR_OK)
+                                       return SR_ERR;
+                       }
+               } else if (probe->type == SR_PROBE_LOGIC) {
+                       if (probe->enabled)
+                               devc->enabled_digital_probes = g_slist_append(
+                                               devc->enabled_digital_probes, probe);
+                       if (probe->enabled != devc->digital_channels[probe->index]) {
+                               /* Enabled channel is currently disabled, or vice versa. */
+                               sprintf(cmd, ":DIG%d:TURN %s", probe->index,
+                                               probe->enabled ? "ON" : "OFF");
+                               if (rigol_ds_send(sdi, cmd) != SR_OK)
+                                       return SR_ERR;
+                       }
+               }
+       }
+       if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
+               return SR_ERR;
+
+       sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
+
+       /* Send header packet to the session bus. */
+       std_session_send_df_header(cb_data, LOG_PREFIX);
+
+       /* Fetch the first frame. */
+       if (devc->enabled_analog_probes) {
+               devc->channel_frame = devc->enabled_analog_probes->data;
+               if (rigol_ds_send(sdi, ":WAV:DATA? CHAN%d",
+                               devc->channel_frame->index + 1) != SR_OK)
+                       return SR_ERR;
+       } else {
+               devc->channel_frame = devc->enabled_digital_probes->data;
+               if (rigol_ds_send(sdi, ":WAV:DATA? DIG") != SR_OK)
+                       return SR_ERR;
+       }
+
+       devc->num_frame_bytes = 0;
+
+       return SR_OK;
+}
+
+static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
+{
+       struct dev_context *devc;
+       struct sr_serial_dev_inst *serial;
+
+       (void)cb_data;
+
+       devc = sdi->priv;
+
+       if (sdi->status != SR_ST_ACTIVE) {
+               sr_err("Device inactive, can't stop acquisition.");
+               return SR_ERR;
+       }
+
+       g_slist_free(devc->enabled_analog_probes);
+       g_slist_free(devc->enabled_digital_probes);
+       devc->enabled_analog_probes = NULL;
+       devc->enabled_digital_probes = NULL;
+       serial = sdi->conn;
+       sr_source_remove(serial->fd);
+
+       return SR_OK;
+}
+
+SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
+       .name = "rigol-ds",
+       .longname = "Rigol DS",
+       .api_version = 1,
+       .init = init,
+       .cleanup = cleanup,
+       .scan = scan,
+       .dev_list = dev_list,
+       .dev_clear = dev_clear,
+       .config_get = config_get,
+       .config_set = config_set,
+       .config_list = config_list,
+       .dev_open = dev_open,
+       .dev_close = dev_close,
+       .dev_acquisition_start = dev_acquisition_start,
+       .dev_acquisition_stop = dev_acquisition_stop,
+       .priv = NULL,
+};
diff --git a/hardware/rigol-ds/protocol.c b/hardware/rigol-ds/protocol.c
new file mode 100644 (file)
index 0000000..19e660d
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
+ * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <math.h>
+#include <glib.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+#include "protocol.h"
+
+SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data)
+{
+       struct sr_dev_inst *sdi;
+       struct sr_serial_dev_inst *serial;
+       struct dev_context *devc;
+       struct sr_datafeed_packet packet;
+       struct sr_datafeed_analog analog;
+       struct sr_datafeed_logic logic;
+       unsigned char buf[DIGITAL_WAVEFORM_SIZE];
+       double vdiv, offset;
+       float data[ANALOG_WAVEFORM_SIZE];
+       int len, i, waveform_size;
+       struct sr_probe *probe;
+
+       (void)fd;
+
+       if (!(sdi = cb_data))
+               return TRUE;
+
+       if (!(devc = sdi->priv))
+               return TRUE;
+
+       serial = sdi->conn;
+
+       if (revents == G_IO_IN) {
+               probe = devc->channel_frame;
+               waveform_size = probe->type == SR_PROBE_ANALOG ?
+                               ANALOG_WAVEFORM_SIZE : DIGITAL_WAVEFORM_SIZE;
+               len = serial_read(serial, buf, waveform_size - devc->num_frame_bytes);
+               sr_dbg("Received %d bytes.", len);
+               if (len == -1)
+                       return TRUE;
+
+               if (devc->num_frame_bytes == 0) {
+                       /* Start of a new frame. */
+                       packet.type = SR_DF_FRAME_BEGIN;
+                       sr_session_send(sdi, &packet);
+               }
+
+               if (probe->type == SR_PROBE_ANALOG) {
+                       for (i = 0; i < len; i++) {
+                               vdiv = devc->vdiv[probe->index];
+                               offset = devc->vert_offset[probe->index];
+                               data[i] = vdiv / 25.6 * (128 - buf[i]) - offset;
+                       }
+                       analog.probes = g_slist_append(NULL, probe);
+                       analog.num_samples = len;
+                       analog.data = data;
+                       analog.mq = SR_MQ_VOLTAGE;
+                       analog.unit = SR_UNIT_VOLT;
+                       analog.mqflags = 0;
+                       packet.type = SR_DF_ANALOG;
+                       packet.payload = &analog;
+                       sr_session_send(cb_data, &packet);
+                       g_slist_free(analog.probes);
+
+                       if (len != ANALOG_WAVEFORM_SIZE)
+                               /* Don't have the whole frame yet. */
+                               return TRUE;
+               } else {
+                       logic.length = len - 10;
+                       logic.unitsize = 2;
+                       logic.data = buf + 10;
+                       packet.type = SR_DF_LOGIC;
+                       packet.payload = &logic;
+                       sr_session_send(cb_data, &packet);
+
+                       if (len != DIGITAL_WAVEFORM_SIZE)
+                               /* Don't have the whole frame yet. */
+                               return TRUE;
+               }
+
+               /* End of the frame. */
+               packet.type = SR_DF_FRAME_END;
+               sr_session_send(sdi, &packet);
+               devc->num_frame_bytes = 0;
+
+               if (devc->enabled_analog_probes
+                               && devc->channel_frame == devc->enabled_analog_probes->data
+                               && devc->enabled_analog_probes->next != NULL) {
+                       /* We got the frame for the first analog channel, but
+                        * there's a second analog channel. */
+                       devc->channel_frame = devc->enabled_analog_probes->next->data;
+                       rigol_ds_send(sdi, ":WAV:DATA? CHAN%c",
+                                       devc->channel_frame->name[2]);
+               } else {
+                       /* Done with both analog channels in this frame. */
+                       if (devc->enabled_digital_probes
+                                       && devc->channel_frame != devc->enabled_digital_probes->data) {
+                               /* Now we need to get the digital data. */
+                               devc->channel_frame = devc->enabled_digital_probes->data;
+                               rigol_ds_send(sdi, ":WAV:DATA? DIG");
+                       } else if (++devc->num_frames == devc->limit_frames) {
+                               /* End of last frame. */
+                               packet.type = SR_DF_END;
+                               sr_session_send(sdi, &packet);
+                               sdi->driver->dev_acquisition_stop(sdi, cb_data);
+                       } else {
+                               /* Get the next frame, starting with the first analog channel. */
+                               if (devc->enabled_analog_probes) {
+                                       devc->channel_frame = devc->enabled_analog_probes->data;
+                                       rigol_ds_send(sdi, ":WAV:DATA? CHAN%c",
+                                                       devc->channel_frame->name[2]);
+                               } else {
+                                       devc->channel_frame = devc->enabled_digital_probes->data;
+                                       rigol_ds_send(sdi, ":WAV:DATA? DIG");
+                               }
+                       }
+               }
+       }
+
+       return TRUE;
+}
+
+SR_PRIV int rigol_ds_send(const struct sr_dev_inst *sdi, const char *format, ...)
+{
+       va_list args;
+       char buf[256];
+       int len, out, ret;
+
+       va_start(args, format);
+       len = vsnprintf(buf, 255, format, args);
+       va_end(args);
+       strcat(buf, "\n");
+       len++;
+       out = serial_write(sdi->conn, buf, len);
+       buf[len - 1] = '\0';
+       if (out != len) {
+               sr_dbg("Only sent %d/%d bytes of '%s'.", out, len, buf);
+               ret = SR_ERR;
+       } else {
+               sr_spew("Sent '%s'.", buf);
+               ret = SR_OK;
+       }
+
+       return ret;
+}
+
+static int get_cfg(const struct sr_dev_inst *sdi, char *cmd, char *reply)
+{
+       int len;
+
+       if (rigol_ds_send(sdi, cmd) != SR_OK)
+               return SR_ERR;
+
+       if ((len = serial_read(sdi->conn, reply, 255)) < 0)
+               return SR_ERR;
+       reply[len] = '\0';
+       sr_spew("Received '%s'.", reply);
+
+       return SR_OK;
+}
+
+static int get_cfg_float(const struct sr_dev_inst *sdi, char *cmd, float *f)
+{
+       char buf[256], *e;
+
+       if (get_cfg(sdi, cmd, buf) != SR_OK)
+               return SR_ERR;
+       *f = strtof(buf, &e);
+       if (e == buf || (fpclassify(*f) & (FP_ZERO | FP_NORMAL)) == 0) {
+               sr_dbg("failed to parse response to '%s': '%s'", cmd, buf);
+               return SR_ERR;
+       }
+
+       return SR_OK;
+}
+
+static int get_cfg_string(const struct sr_dev_inst *sdi, char *cmd, char **buf)
+{
+
+       if (!(*buf = g_try_malloc0(256)))
+               return SR_ERR_MALLOC;
+
+       if (get_cfg(sdi, cmd, *buf) != SR_OK)
+               return SR_ERR;
+
+       return SR_OK;
+}
+
+SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi)
+{
+       struct dev_context *devc;
+       char *t_s, *cmd;
+       int i, res;
+
+       devc = sdi->priv;
+
+       /* Analog channel state. */
+       if (get_cfg_string(sdi, ":CHAN1:DISP?", &t_s) != SR_OK)
+               return SR_ERR;
+       devc->analog_channels[0] = !strcmp(t_s, "ON") ? TRUE : FALSE;
+       g_free(t_s);
+       if (get_cfg_string(sdi, ":CHAN2:DISP?", &t_s) != SR_OK)
+               return SR_ERR;
+       devc->analog_channels[1] = !strcmp(t_s, "ON") ? TRUE : FALSE;
+       g_free(t_s);
+       sr_dbg("Current analog channel state CH1 %s CH2 %s",
+                       devc->analog_channels[0] ? "on" : "off",
+                       devc->analog_channels[1] ? "on" : "off");
+
+       /* Digital channel state. */
+       if (devc->has_digital) {
+               sr_dbg("Current digital channel state:");
+               for (i = 0; i < 16; i++) {
+                       cmd = g_strdup_printf(":DIG%d:TURN?", i);
+                       res = get_cfg_string(sdi, cmd, &t_s);
+                       g_free(cmd);
+                       if (res != SR_OK)
+                               return SR_ERR;
+                       devc->digital_channels[i] = !strcmp(t_s, "ON") ? TRUE : FALSE;
+                       g_free(t_s);
+                       sr_dbg("D%d: %s", i, devc->digital_channels[i] ? "on" : "off");
+               }
+       }
+
+       /* Timebase. */
+       if (get_cfg_float(sdi, ":TIM:SCAL?", &devc->timebase) != SR_OK)
+               return SR_ERR;
+       sr_dbg("Current timebase %f", devc->timebase);
+
+       /* Vertical gain. */
+       if (get_cfg_float(sdi, ":CHAN1:SCAL?", &devc->vdiv[0]) != SR_OK)
+               return SR_ERR;
+       if (get_cfg_float(sdi, ":CHAN2:SCAL?", &devc->vdiv[1]) != SR_OK)
+               return SR_ERR;
+       sr_dbg("Current vertical gain CH1 %f CH2 %f", devc->vdiv[0], devc->vdiv[1]);
+
+       /* Vertical offset. */
+       if (get_cfg_float(sdi, ":CHAN1:OFFS?", &devc->vert_offset[0]) != SR_OK)
+               return SR_ERR;
+       if (get_cfg_float(sdi, ":CHAN2:OFFS?", &devc->vert_offset[1]) != SR_OK)
+               return SR_ERR;
+       sr_dbg("Current vertical offset CH1 %f CH2 %f", devc->vert_offset[0],
+                       devc->vert_offset[1]);
+
+       /* Coupling. */
+       if (get_cfg_string(sdi, ":CHAN1:COUP?", &devc->coupling[0]) != SR_OK)
+               return SR_ERR;
+       if (get_cfg_string(sdi, ":CHAN2:COUP?", &devc->coupling[1]) != SR_OK)
+               return SR_ERR;
+       sr_dbg("Current coupling CH1 %s CH2 %s", devc->coupling[0],
+                       devc->coupling[1]);
+
+       /* Trigger source. */
+       if (get_cfg_string(sdi, ":TRIG:EDGE:SOUR?", &devc->trigger_source) != SR_OK)
+               return SR_ERR;
+       sr_dbg("Current trigger source %s", devc->trigger_source);
+
+       /* Horizontal trigger position. */
+       if (get_cfg_float(sdi, ":TIM:OFFS?", &devc->horiz_triggerpos) != SR_OK)
+               return SR_ERR;
+       sr_dbg("Current horizontal trigger position %f", devc->horiz_triggerpos);
+
+       /* Trigger slope. */
+       if (get_cfg_string(sdi, ":TRIG:EDGE:SLOP?", &devc->trigger_slope) != SR_OK)
+               return SR_ERR;
+       sr_dbg("Current trigger slope %s", devc->trigger_slope);
+
+       return SR_OK;
+}
diff --git a/hardware/rigol-ds/protocol.h b/hardware/rigol-ds/protocol.h
new file mode 100644 (file)
index 0000000..cce22b2
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
+ * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBSIGROK_HARDWARE_RIGOL_DS_PROTOCOL_H
+#define LIBSIGROK_HARDWARE_RIGOL_DS_PROTOCOL_H
+
+#include <stdint.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "rigol-ds: "
+#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
+#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
+#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
+#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
+#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
+#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
+
+#define ANALOG_WAVEFORM_SIZE 600
+#define DIGITAL_WAVEFORM_SIZE 1210
+
+/** Private, per-device-instance driver context. */
+struct dev_context {
+       /* Device features */
+       gboolean has_digital;
+
+       /* Probe groups */
+       struct sr_probe_group analog_groups[2];
+       struct sr_probe_group digital_group;
+
+       /* Acquisition settings */
+       GSList *enabled_analog_probes;
+       GSList *enabled_digital_probes;
+       uint64_t limit_frames;
+       void *cb_data;
+
+       /* Device settings */
+       gboolean analog_channels[2];
+       gboolean digital_channels[16];
+       float timebase;
+       float vdiv[2];
+       float vert_offset[2];
+       char *trigger_source;
+       float horiz_triggerpos;
+       char *trigger_slope;
+       char *coupling[2];
+
+       /* Operational state */
+       uint64_t num_frames;
+       uint64_t num_frame_bytes;
+       struct sr_probe *channel_frame;
+};
+
+SR_PRIV int rigol_ds_receive(int fd, int revents, void *cb_data);
+SR_PRIV int rigol_ds_send(const struct sr_dev_inst *sdi, const char *format, ...);
+SR_PRIV int rigol_ds_get_dev_cfg(const struct sr_dev_inst *sdi);
+
+#endif
diff --git a/hardware/rigol-ds1xx2/Makefile.am b/hardware/rigol-ds1xx2/Makefile.am
deleted file mode 100644 (file)
index a538df0..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-##
-## This file is part of the libsigrok project.
-##
-## Copyright (C) 2012 Martin Ling <martin-git@earth.li>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program.  If not, see <http://www.gnu.org/licenses/>.
-##
-
-if HW_RIGOL_DS1XX2
-
-# Local lib, this is NOT meant to be installed!
-noinst_LTLIBRARIES = libsigrok_hw_rigol_ds1xx2.la
-
-libsigrok_hw_rigol_ds1xx2_la_SOURCES = \
-       api.c \
-       protocol.c \
-       protocol.h
-
-libsigrok_hw_rigol_ds1xx2_la_CFLAGS = \
-       -I$(top_srcdir)
-
-endif
diff --git a/hardware/rigol-ds1xx2/api.c b/hardware/rigol-ds1xx2/api.c
deleted file mode 100644 (file)
index d6f055e..0000000
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
- * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include "libsigrok.h"
-#include "libsigrok-internal.h"
-#include "protocol.h"
-
-#define NUM_TIMEBASE  12
-#define NUM_VDIV      8
-
-static const int32_t hwopts[] = {
-       SR_CONF_CONN,
-};
-
-static const int32_t hwcaps[] = {
-       SR_CONF_OSCILLOSCOPE,
-       SR_CONF_TIMEBASE,
-       SR_CONF_TRIGGER_SOURCE,
-       SR_CONF_TRIGGER_SLOPE,
-       SR_CONF_HORIZ_TRIGGERPOS,
-       SR_CONF_NUM_TIMEBASE,
-};
-
-static const int32_t analog_hwcaps[] = {
-       SR_CONF_NUM_VDIV,
-       SR_CONF_VDIV,
-       SR_CONF_COUPLING,
-};
-
-static const uint64_t timebases[][2] = {
-       /* nanoseconds */
-       { 2, 1000000000 },
-       { 5, 1000000000 },
-       { 10, 1000000000 },
-       { 20, 1000000000 },
-       { 50, 1000000000 },
-       { 100, 1000000000 },
-       { 500, 1000000000 },
-       /* microseconds */
-       { 1, 1000000 },
-       { 2, 1000000 },
-       { 5, 1000000 },
-       { 10, 1000000 },
-       { 20, 1000000 },
-       { 50, 1000000 },
-       { 100, 1000000 },
-       { 200, 1000000 },
-       { 500, 1000000 },
-       /* milliseconds */
-       { 1, 1000 },
-       { 2, 1000 },
-       { 5, 1000 },
-       { 10, 1000 },
-       { 20, 1000 },
-       { 50, 1000 },
-       { 100, 1000 },
-       { 200, 1000 },
-       { 500, 1000 },
-       /* seconds */
-       { 1, 1 },
-       { 2, 1 },
-       { 5, 1 },
-       { 10, 1 },
-       { 20, 1 },
-       { 50, 1 },
-};
-
-static const uint64_t vdivs[][2] = {
-       /* millivolts */
-       { 2, 1000 },
-       { 5, 1000 },
-       { 10, 1000 },
-       { 20, 1000 },
-       { 50, 1000 },
-       { 100, 1000 },
-       { 200, 1000 },
-       { 500, 1000 },
-       /* volts */
-       { 1, 1 },
-       { 2, 1 },
-       { 5, 1 },
-       { 10, 1 },
-};
-
-static const char *trigger_sources[] = {
-       "CH1",
-       "CH2",
-       "EXT",
-       "AC Line",
-       "D0",
-       "D1",
-       "D2",
-       "D3",
-       "D4",
-       "D5",
-       "D6",
-       "D7",
-       "D8",
-       "D9",
-       "D10",
-       "D11",
-       "D12",
-       "D13",
-       "D14",
-       "D15",
-};
-
-static const char *coupling[] = {
-       "AC",
-       "DC",
-       "GND",
-};
-
-static const char *supported_models[] = {
-       "DS1052E",
-       "DS1102E",
-       "DS1152E",
-       "DS1052D",
-       "DS1102D",
-       "DS1152D",
-};
-
-SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
-static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
-
-static void clear_helper(void *priv)
-{
-       struct dev_context *devc;
-
-       devc = priv;
-       g_free(devc->coupling[0]);
-       g_free(devc->coupling[1]);
-       g_free(devc->trigger_source);
-       g_free(devc->trigger_slope);
-       g_slist_free(devc->analog_groups[0].probes);
-       g_slist_free(devc->analog_groups[1].probes);
-       g_slist_free(devc->digital_group.probes);
-}
-
-static int dev_clear(void)
-{
-       return std_dev_clear(di, clear_helper);
-}
-
-static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
-{
-       va_list args;
-       char buf[256];
-
-       va_start(args, format);
-       vsnprintf(buf, 255, format, args);
-       va_end(args);
-       if (rigol_ds1xx2_send(sdi, buf) != SR_OK)
-               return SR_ERR;
-
-       /* When setting a bunch of parameters in a row, the DS1052E scrambles
-        * some of them unless there is at least 100ms delay in between. */
-       sr_spew("delay %dms", 100);
-       g_usleep(100000);
-
-       return SR_OK;
-}
-
-static int init(struct sr_context *sr_ctx)
-{
-       return std_init(sr_ctx, di, LOG_PREFIX);
-}
-
-static int probe_port(const char *port, GSList **devices)
-{
-       struct dev_context *devc;
-       struct sr_dev_inst *sdi;
-       struct sr_serial_dev_inst *serial;
-       struct sr_probe *probe;
-       unsigned int i;
-       int len, num_tokens;
-       gboolean matched, has_digital;
-       const char *manufacturer, *model, *version;
-       char buf[256];
-       gchar **tokens, *channel_name;
-
-       *devices = NULL;
-       if (!(serial = sr_serial_dev_inst_new(port, NULL)))
-               return SR_ERR_MALLOC;
-
-       if (serial_open(serial, SERIAL_RDWR) != SR_OK)
-               return SR_ERR;
-       len = serial_write(serial, "*IDN?", 5);
-       len = serial_read(serial, buf, sizeof(buf));
-       if (serial_close(serial) != SR_OK)
-               return SR_ERR;
-
-       sr_serial_dev_inst_free(serial);
-
-       if (len == 0)
-               return SR_ERR_NA;
-
-       buf[len] = 0;
-       tokens = g_strsplit(buf, ",", 0);
-       sr_dbg("response: %s [%s]", port, buf);
-
-       for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
-
-       if (num_tokens < 4) {
-               g_strfreev(tokens);
-               return SR_ERR_NA;
-       }
-
-       manufacturer = tokens[0];
-       model = tokens[1];
-       version = tokens[3];
-
-       if (strcmp(manufacturer, "Rigol Technologies")) {
-               g_strfreev(tokens);
-               return SR_ERR_NA;
-       }
-
-       matched = has_digital = FALSE;
-       for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
-               if (!strcmp(model, supported_models[i])) {
-                       matched = TRUE;
-                       has_digital = g_str_has_suffix(model, "D");
-                       break;
-               }
-       }
-
-       if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
-               manufacturer, model, version))) {
-               g_strfreev(tokens);
-               return SR_ERR_NA;
-       }
-
-       g_strfreev(tokens);
-
-       if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
-               return SR_ERR_MALLOC;
-       sdi->driver = di;
-       sdi->inst_type = SR_INST_SERIAL;
-
-       if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
-               return SR_ERR_MALLOC;
-       devc->limit_frames = 0;
-       devc->has_digital = has_digital;
-
-       for (i = 0; i < 2; i++) {
-               channel_name = (i == 0 ? "CH1" : "CH2");
-               if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name)))
-                       return SR_ERR_MALLOC;
-               sdi->probes = g_slist_append(sdi->probes, probe);
-               devc->analog_groups[i].name = channel_name;
-               devc->analog_groups[i].probes = g_slist_append(NULL, probe);
-               sdi->probe_groups = g_slist_append(sdi->probe_groups,
-                               &devc->analog_groups[i]);
-       }
-
-       if (devc->has_digital) {
-               for (i = 0; i < 16; i++) {
-                       if (!(channel_name = g_strdup_printf("D%d", i)))
-                               return SR_ERR_MALLOC;
-                       probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
-                       g_free(channel_name);
-                       if (!probe)
-                               return SR_ERR_MALLOC;
-                       sdi->probes = g_slist_append(sdi->probes, probe);
-                       devc->digital_group.probes = g_slist_append(
-                                       devc->digital_group.probes, probe);
-                       devc->digital_group.name = "LA";
-                       sdi->probe_groups = g_slist_append(sdi->probe_groups,
-                                       &devc->digital_group);
-               }
-       }
-       sdi->priv = devc;
-
-       *devices = g_slist_append(NULL, sdi);
-
-       return SR_OK;
-}
-
-static GSList *scan(GSList *options)
-{
-       struct drv_context *drvc;
-       struct sr_config *src;
-       GSList *l, *devices;
-       GDir *dir;
-       int ret;
-       const gchar *dev_name;
-       gchar *port = NULL;
-
-       drvc = di->priv;
-
-       for (l = options; l; l = l->next) {
-               src = l->data;
-               if (src->key == SR_CONF_CONN) {
-                       port = (char *)g_variant_get_string(src->data, NULL);
-                       break;
-               }
-       }
-
-       devices = NULL;
-       if (port) {
-               if (probe_port(port, &devices) == SR_ERR_MALLOC)
-                       return NULL;
-       } else {
-               if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
-                       if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
-                               return NULL;
-               while ((dev_name = g_dir_read_name(dir))) {
-                       if (strncmp(dev_name, "usbtmc", 6))
-                               continue;
-                       port = g_strconcat("/dev/", dev_name, NULL);
-                       ret = probe_port(port, &devices);
-                       g_free(port);
-                       if (ret == SR_ERR_MALLOC) {
-                               g_dir_close(dir);
-                               return NULL;
-                       }
-               }
-               g_dir_close(dir);
-       }
-
-       /* Tack a copy of the newly found devices onto the driver list. */
-       l = g_slist_copy(devices);
-       drvc->instances = g_slist_concat(drvc->instances, l);
-
-       return devices;
-}
-
-static GSList *dev_list(void)
-{
-       return ((struct drv_context *)(di->priv))->instances;
-}
-
-static int dev_open(struct sr_dev_inst *sdi)
-{
-
-       if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
-               return SR_ERR;
-
-       if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
-               return SR_ERR;
-
-       sdi->status = SR_ST_ACTIVE;
-
-       return SR_OK;
-}
-
-static int dev_close(struct sr_dev_inst *sdi)
-{
-       struct sr_serial_dev_inst *serial;
-
-       serial = sdi->conn;
-       if (serial && serial->fd != -1) {
-               serial_close(serial);
-               sdi->status = SR_ST_INACTIVE;
-       }
-
-       return SR_OK;
-}
-
-static int cleanup(void)
-{
-       return dev_clear();
-}
-
-static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
-               const struct sr_probe_group *probe_group)
-{
-       struct dev_context *devc;
-       unsigned int i;
-
-       if (!sdi || !(devc = sdi->priv))
-               return SR_ERR_ARG;
-
-       /* If a probe group is specified, it must be a valid one. */
-       if (probe_group) {
-               if (probe_group != &devc->analog_groups[0]
-                               && probe_group != &devc->analog_groups[1]) {
-                       sr_err("Invalid probe group specified.");
-                       return SR_ERR;
-               }
-       }
-
-       switch (id) {
-       case SR_CONF_NUM_TIMEBASE:
-               *data = g_variant_new_int32(NUM_TIMEBASE);
-               break;
-       case SR_CONF_NUM_VDIV:
-               if (!probe_group) {
-                       sr_err("No probe group specified.");
-                       return SR_ERR_PROBE_GROUP;
-               }
-               for (i = 0; i < 2; i++) {
-                       if (probe_group == &devc->analog_groups[i]) {
-                               *data = g_variant_new_int32(NUM_VDIV);
-                               return SR_OK;
-                       }
-               }
-               return SR_ERR_NA;
-       default:
-               return SR_ERR_NA;
-       }
-
-       return SR_OK;
-}
-
-static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
-               const struct sr_probe_group *probe_group)
-{
-       struct dev_context *devc;
-       uint64_t tmp_u64, p, q;
-       double t_dbl;
-       unsigned int i, j;
-       int ret;
-       const char *tmp_str;
-
-       if (!(devc = sdi->priv))
-               return SR_ERR_ARG;
-
-       if (sdi->status != SR_ST_ACTIVE)
-               return SR_ERR_DEV_CLOSED;
-
-       /* If a probe group is specified, it must be a valid one. */
-       if (probe_group) {
-               if (probe_group != &devc->analog_groups[0]
-                               && probe_group != &devc->analog_groups[1]) {
-                       sr_err("Invalid probe group specified.");
-                       return SR_ERR;
-               }
-       }
-
-       ret = SR_OK;
-       switch (id) {
-       case SR_CONF_LIMIT_FRAMES:
-               devc->limit_frames = g_variant_get_uint64(data);
-               break;
-       case SR_CONF_TRIGGER_SLOPE:
-               tmp_u64 = g_variant_get_uint64(data);
-               if (tmp_u64 != 0 && tmp_u64 != 1)
-                       return SR_ERR;
-               g_free(devc->trigger_slope);
-               devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
-               ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
-               break;
-       case SR_CONF_HORIZ_TRIGGERPOS:
-               t_dbl = g_variant_get_double(data);
-               if (t_dbl < 0.0 || t_dbl > 1.0)
-                       return SR_ERR;
-               devc->horiz_triggerpos = t_dbl;
-               /* We have the trigger offset as a percentage of the frame, but
-                * need to express this in seconds. */
-               t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
-               ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
-               break;
-       case SR_CONF_TIMEBASE:
-               g_variant_get(data, "(tt)", &p, &q);
-               for (i = 0; i < ARRAY_SIZE(timebases); i++) {
-                       if (timebases[i][0] == p && timebases[i][1] == q) {
-                               devc->timebase = (float)p / q;
-                               ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
-                               break;
-                       }
-               }
-               if (i == ARRAY_SIZE(timebases))
-                       ret = SR_ERR_ARG;
-               break;
-       case SR_CONF_TRIGGER_SOURCE:
-               tmp_str = g_variant_get_string(data, NULL);
-               for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
-                       if (!strcmp(trigger_sources[i], tmp_str)) {
-                               g_free(devc->trigger_source);
-                               devc->trigger_source = g_strdup(trigger_sources[i]);
-                               if (!strcmp(devc->trigger_source, "AC Line"))
-                                       tmp_str = "ACL";
-                               else if (!strcmp(devc->trigger_source, "CH1"))
-                                       tmp_str = "CHAN1";
-                               else if (!strcmp(devc->trigger_source, "CH2"))
-                                       tmp_str = "CHAN2";
-                               else
-                                       tmp_str = (char *)devc->trigger_source;
-                               ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
-                               break;
-                       }
-               }
-               if (i == ARRAY_SIZE(trigger_sources))
-                       ret = SR_ERR_ARG;
-               break;
-       case SR_CONF_VDIV:
-               if (!probe_group) {
-                       sr_err("No probe group specified.");
-                       return SR_ERR_PROBE_GROUP;
-               }
-               g_variant_get(data, "(tt)", &p, &q);
-               for (i = 0; i < 2; i++) {
-                       if (probe_group == &devc->analog_groups[i]) {
-                               for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
-                                       if (vdivs[j][0] != p || vdivs[j][1] != q)
-                                               continue;
-                                       devc->vdiv[i] = (float)p / q;
-                                       return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
-                                                       devc->vdiv[i]);
-                               }
-                               return SR_ERR_ARG;
-                       }
-               }
-               return SR_ERR_NA;
-       case SR_CONF_COUPLING:
-               if (!probe_group) {
-                       sr_err("No probe group specified.");
-                       return SR_ERR_PROBE_GROUP;
-               }
-               tmp_str = g_variant_get_string(data, NULL);
-               for (i = 0; i < 2; i++) {
-                       if (probe_group == &devc->analog_groups[i]) {
-                               for (j = 0; j < ARRAY_SIZE(coupling); j++) {
-                                       if (!strcmp(tmp_str, coupling[j])) {
-                                               g_free(devc->coupling[i]);
-                                               devc->coupling[i] = g_strdup(coupling[j]);
-                                               return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
-                                                               devc->coupling[i]);
-                                       }
-                               }
-                               return SR_ERR_ARG;
-                       }
-               }
-               return SR_ERR_NA;
-       default:
-               ret = SR_ERR_NA;
-               break;
-       }
-
-       return ret;
-}
-
-static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
-               const struct sr_probe_group *probe_group)
-{
-       GVariant *tuple, *rational[2];
-       GVariantBuilder gvb;
-       unsigned int i;
-       struct dev_context *devc;
-
-       if (key == SR_CONF_SCAN_OPTIONS) {
-               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
-                               hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
-               return SR_OK;
-       } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
-               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
-                       hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
-               return SR_OK;
-       }
-
-       /* Every other option requires a valid device instance. */
-       if (!sdi || !(devc = sdi->priv))
-               return SR_ERR_ARG;
-
-       /* If a probe group is specified, it must be a valid one. */
-       if (probe_group) {
-               if (probe_group != &devc->analog_groups[0]
-                               && probe_group != &devc->analog_groups[1]) {
-                       sr_err("Invalid probe group specified.");
-                       return SR_ERR;
-               }
-       }
-
-       switch (key) {
-               break;
-       case SR_CONF_DEVICE_OPTIONS:
-               if (!probe_group) {
-                       sr_err("No probe group specified.");
-                       return SR_ERR_PROBE_GROUP;
-               }
-               if (probe_group == &devc->digital_group) {
-                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
-                               NULL, 0, sizeof(int32_t));
-                       return SR_OK;
-               } else {
-                       for (i = 0; i < 2; i++) {
-                               if (probe_group == &devc->analog_groups[i]) {
-                                       *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
-                                               analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
-                                       return SR_OK;
-                               }
-                       }
-                       return SR_ERR_NA;
-               }
-               break;
-       case SR_CONF_COUPLING:
-               if (!probe_group) {
-                       sr_err("No probe group specified.");
-                       return SR_ERR_PROBE_GROUP;
-               }
-               *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
-               break;
-       case SR_CONF_VDIV:
-               if (!probe_group) {
-                       sr_err("No probe group specified.");
-                       return SR_ERR_PROBE_GROUP;
-               }
-               g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
-               for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
-                       rational[0] = g_variant_new_uint64(vdivs[i][0]);
-                       rational[1] = g_variant_new_uint64(vdivs[i][1]);
-                       tuple = g_variant_new_tuple(rational, 2);
-                       g_variant_builder_add_value(&gvb, tuple);
-               }
-               *data = g_variant_builder_end(&gvb);
-               break;
-       case SR_CONF_TIMEBASE:
-               g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
-               for (i = 0; i < ARRAY_SIZE(timebases); i++) {
-                       rational[0] = g_variant_new_uint64(timebases[i][0]);
-                       rational[1] = g_variant_new_uint64(timebases[i][1]);
-                       tuple = g_variant_new_tuple(rational, 2);
-                       g_variant_builder_add_value(&gvb, tuple);
-               }
-               *data = g_variant_builder_end(&gvb);
-               break;
-       case SR_CONF_TRIGGER_SOURCE:
-               *data = g_variant_new_strv(trigger_sources,
-                               devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
-               break;
-       default:
-               return SR_ERR_NA;
-       }
-
-       return SR_OK;
-}
-
-static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
-{
-       struct sr_serial_dev_inst *serial;
-       struct dev_context *devc;
-       struct sr_probe *probe;
-       GSList *l;
-       char cmd[256];
-
-       if (sdi->status != SR_ST_ACTIVE)
-               return SR_ERR_DEV_CLOSED;
-
-       serial = sdi->conn;
-       devc = sdi->priv;
-
-       for (l = sdi->probes; l; l = l->next) {
-               probe = l->data;
-               sr_dbg("handling probe %s", probe->name);
-               if (probe->type == SR_PROBE_ANALOG) {
-                       if (probe->enabled)
-                               devc->enabled_analog_probes = g_slist_append(
-                                               devc->enabled_analog_probes, probe);
-                       if (probe->enabled != devc->analog_channels[probe->index]) {
-                               /* Enabled channel is currently disabled, or vice versa. */
-                               sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
-                                               probe->enabled ? "ON" : "OFF");
-                               if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
-                                       return SR_ERR;
-                       }
-               } else if (probe->type == SR_PROBE_LOGIC) {
-                       if (probe->enabled)
-                               devc->enabled_digital_probes = g_slist_append(
-                                               devc->enabled_digital_probes, probe);
-                       if (probe->enabled != devc->digital_channels[probe->index]) {
-                               /* Enabled channel is currently disabled, or vice versa. */
-                               sprintf(cmd, ":DIG%d:TURN %s", probe->index,
-                                               probe->enabled ? "ON" : "OFF");
-                               if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
-                                       return SR_ERR;
-                       }
-               }
-       }
-       if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
-               return SR_ERR;
-
-       sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
-
-       /* Send header packet to the session bus. */
-       std_session_send_df_header(cb_data, LOG_PREFIX);
-
-       /* Fetch the first frame. */
-       if (devc->enabled_analog_probes) {
-               devc->channel_frame = devc->enabled_analog_probes->data;
-               if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
-                               devc->channel_frame->index + 1) != SR_OK)
-                       return SR_ERR;
-       } else {
-               devc->channel_frame = devc->enabled_digital_probes->data;
-               if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
-                       return SR_ERR;
-       }
-
-       devc->num_frame_bytes = 0;
-
-       return SR_OK;
-}
-
-static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
-{
-       struct dev_context *devc;
-       struct sr_serial_dev_inst *serial;
-
-       (void)cb_data;
-
-       devc = sdi->priv;
-
-       if (sdi->status != SR_ST_ACTIVE) {
-               sr_err("Device inactive, can't stop acquisition.");
-               return SR_ERR;
-       }
-
-       g_slist_free(devc->enabled_analog_probes);
-       g_slist_free(devc->enabled_digital_probes);
-       devc->enabled_analog_probes = NULL;
-       devc->enabled_digital_probes = NULL;
-       serial = sdi->conn;
-       sr_source_remove(serial->fd);
-
-       return SR_OK;
-}
-
-SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
-       .name = "rigol-ds1xx2",
-       .longname = "Rigol DS1xx2",
-       .api_version = 1,
-       .init = init,
-       .cleanup = cleanup,
-       .scan = scan,
-       .dev_list = dev_list,
-       .dev_clear = dev_clear,
-       .config_get = config_get,
-       .config_set = config_set,
-       .config_list = config_list,
-       .dev_open = dev_open,
-       .dev_close = dev_close,
-       .dev_acquisition_start = dev_acquisition_start,
-       .dev_acquisition_stop = dev_acquisition_stop,
-       .priv = NULL,
-};
diff --git a/hardware/rigol-ds1xx2/protocol.c b/hardware/rigol-ds1xx2/protocol.c
deleted file mode 100644 (file)
index 0efff69..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
- * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <math.h>
-#include <glib.h>
-#include "libsigrok.h"
-#include "libsigrok-internal.h"
-#include "protocol.h"
-
-SR_PRIV int rigol_ds1xx2_receive(int fd, int revents, void *cb_data)
-{
-       struct sr_dev_inst *sdi;
-       struct sr_serial_dev_inst *serial;
-       struct dev_context *devc;
-       struct sr_datafeed_packet packet;
-       struct sr_datafeed_analog analog;
-       struct sr_datafeed_logic logic;
-       unsigned char buf[DIGITAL_WAVEFORM_SIZE];
-       double vdiv, offset;
-       float data[ANALOG_WAVEFORM_SIZE];
-       int len, i, waveform_size;
-       struct sr_probe *probe;
-
-       (void)fd;
-
-       if (!(sdi = cb_data))
-               return TRUE;
-
-       if (!(devc = sdi->priv))
-               return TRUE;
-
-       serial = sdi->conn;
-
-       if (revents == G_IO_IN) {
-               probe = devc->channel_frame;
-               waveform_size = probe->type == SR_PROBE_ANALOG ?
-                               ANALOG_WAVEFORM_SIZE : DIGITAL_WAVEFORM_SIZE;
-               len = serial_read(serial, buf, waveform_size - devc->num_frame_bytes);
-               sr_dbg("Received %d bytes.", len);
-               if (len == -1)
-                       return TRUE;
-
-               if (devc->num_frame_bytes == 0) {
-                       /* Start of a new frame. */
-                       packet.type = SR_DF_FRAME_BEGIN;
-                       sr_session_send(sdi, &packet);
-               }
-
-               if (probe->type == SR_PROBE_ANALOG) {
-                       for (i = 0; i < len; i++) {
-                               vdiv = devc->vdiv[probe->index];
-                               offset = devc->vert_offset[probe->index];
-                               data[i] = vdiv / 25.6 * (128 - buf[i]) - offset;
-                       }
-                       analog.probes = g_slist_append(NULL, probe);
-                       analog.num_samples = len;
-                       analog.data = data;
-                       analog.mq = SR_MQ_VOLTAGE;
-                       analog.unit = SR_UNIT_VOLT;
-                       analog.mqflags = 0;
-                       packet.type = SR_DF_ANALOG;
-                       packet.payload = &analog;
-                       sr_session_send(cb_data, &packet);
-                       g_slist_free(analog.probes);
-
-                       if (len != ANALOG_WAVEFORM_SIZE)
-                               /* Don't have the whole frame yet. */
-                               return TRUE;
-               } else {
-                       logic.length = len - 10;
-                       logic.unitsize = 2;
-                       logic.data = buf + 10;
-                       packet.type = SR_DF_LOGIC;
-                       packet.payload = &logic;
-                       sr_session_send(cb_data, &packet);
-
-                       if (len != DIGITAL_WAVEFORM_SIZE)
-                               /* Don't have the whole frame yet. */
-                               return TRUE;
-               }
-
-               /* End of the frame. */
-               packet.type = SR_DF_FRAME_END;
-               sr_session_send(sdi, &packet);
-               devc->num_frame_bytes = 0;
-
-               if (devc->enabled_analog_probes
-                               && devc->channel_frame == devc->enabled_analog_probes->data
-                               && devc->enabled_analog_probes->next != NULL) {
-                       /* We got the frame for the first analog channel, but
-                        * there's a second analog channel. */
-                       devc->channel_frame = devc->enabled_analog_probes->next->data;
-                       rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%c",
-                                       devc->channel_frame->name[2]);
-               } else {
-                       /* Done with both analog channels in this frame. */
-                       if (devc->enabled_digital_probes
-                                       && devc->channel_frame != devc->enabled_digital_probes->data) {
-                               /* Now we need to get the digital data. */
-                               devc->channel_frame = devc->enabled_digital_probes->data;
-                               rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG");
-                       } else if (++devc->num_frames == devc->limit_frames) {
-                               /* End of last frame. */
-                               packet.type = SR_DF_END;
-                               sr_session_send(sdi, &packet);
-                               sdi->driver->dev_acquisition_stop(sdi, cb_data);
-                       } else {
-                               /* Get the next frame, starting with the first analog channel. */
-                               if (devc->enabled_analog_probes) {
-                                       devc->channel_frame = devc->enabled_analog_probes->data;
-                                       rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%c",
-                                                       devc->channel_frame->name[2]);
-                               } else {
-                                       devc->channel_frame = devc->enabled_digital_probes->data;
-                                       rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG");
-                               }
-                       }
-               }
-       }
-
-       return TRUE;
-}
-
-SR_PRIV int rigol_ds1xx2_send(const struct sr_dev_inst *sdi, const char *format, ...)
-{
-       va_list args;
-       char buf[256];
-       int len, out, ret;
-
-       va_start(args, format);
-       len = vsnprintf(buf, 255, format, args);
-       va_end(args);
-       strcat(buf, "\n");
-       len++;
-       out = serial_write(sdi->conn, buf, len);
-       buf[len - 1] = '\0';
-       if (out != len) {
-               sr_dbg("Only sent %d/%d bytes of '%s'.", out, len, buf);
-               ret = SR_ERR;
-       } else {
-               sr_spew("Sent '%s'.", buf);
-               ret = SR_OK;
-       }
-
-       return ret;
-}
-
-static int get_cfg(const struct sr_dev_inst *sdi, char *cmd, char *reply)
-{
-       int len;
-
-       if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
-               return SR_ERR;
-
-       if ((len = serial_read(sdi->conn, reply, 255)) < 0)
-               return SR_ERR;
-       reply[len] = '\0';
-       sr_spew("Received '%s'.", reply);
-
-       return SR_OK;
-}
-
-static int get_cfg_float(const struct sr_dev_inst *sdi, char *cmd, float *f)
-{
-       char buf[256], *e;
-
-       if (get_cfg(sdi, cmd, buf) != SR_OK)
-               return SR_ERR;
-       *f = strtof(buf, &e);
-       if (e == buf || (fpclassify(*f) & (FP_ZERO | FP_NORMAL)) == 0) {
-               sr_dbg("failed to parse response to '%s': '%s'", cmd, buf);
-               return SR_ERR;
-       }
-
-       return SR_OK;
-}
-
-static int get_cfg_string(const struct sr_dev_inst *sdi, char *cmd, char **buf)
-{
-
-       if (!(*buf = g_try_malloc0(256)))
-               return SR_ERR_MALLOC;
-
-       if (get_cfg(sdi, cmd, *buf) != SR_OK)
-               return SR_ERR;
-
-       return SR_OK;
-}
-
-SR_PRIV int rigol_ds1xx2_get_dev_cfg(const struct sr_dev_inst *sdi)
-{
-       struct dev_context *devc;
-       char *t_s, *cmd;
-       int i, res;
-
-       devc = sdi->priv;
-
-       /* Analog channel state. */
-       if (get_cfg_string(sdi, ":CHAN1:DISP?", &t_s) != SR_OK)
-               return SR_ERR;
-       devc->analog_channels[0] = !strcmp(t_s, "ON") ? TRUE : FALSE;
-       g_free(t_s);
-       if (get_cfg_string(sdi, ":CHAN2:DISP?", &t_s) != SR_OK)
-               return SR_ERR;
-       devc->analog_channels[1] = !strcmp(t_s, "ON") ? TRUE : FALSE;
-       g_free(t_s);
-       sr_dbg("Current analog channel state CH1 %s CH2 %s",
-                       devc->analog_channels[0] ? "on" : "off",
-                       devc->analog_channels[1] ? "on" : "off");
-
-       /* Digital channel state. */
-       if (devc->has_digital) {
-               sr_dbg("Current digital channel state:");
-               for (i = 0; i < 16; i++) {
-                       cmd = g_strdup_printf(":DIG%d:TURN?", i);
-                       res = get_cfg_string(sdi, cmd, &t_s);
-                       g_free(cmd);
-                       if (res != SR_OK)
-                               return SR_ERR;
-                       devc->digital_channels[i] = !strcmp(t_s, "ON") ? TRUE : FALSE;
-                       g_free(t_s);
-                       sr_dbg("D%d: %s", i, devc->digital_channels[i] ? "on" : "off");
-               }
-       }
-
-       /* Timebase. */
-       if (get_cfg_float(sdi, ":TIM:SCAL?", &devc->timebase) != SR_OK)
-               return SR_ERR;
-       sr_dbg("Current timebase %f", devc->timebase);
-
-       /* Vertical gain. */
-       if (get_cfg_float(sdi, ":CHAN1:SCAL?", &devc->vdiv[0]) != SR_OK)
-               return SR_ERR;
-       if (get_cfg_float(sdi, ":CHAN2:SCAL?", &devc->vdiv[1]) != SR_OK)
-               return SR_ERR;
-       sr_dbg("Current vertical gain CH1 %f CH2 %f", devc->vdiv[0], devc->vdiv[1]);
-
-       /* Vertical offset. */
-       if (get_cfg_float(sdi, ":CHAN1:OFFS?", &devc->vert_offset[0]) != SR_OK)
-               return SR_ERR;
-       if (get_cfg_float(sdi, ":CHAN2:OFFS?", &devc->vert_offset[1]) != SR_OK)
-               return SR_ERR;
-       sr_dbg("Current vertical offset CH1 %f CH2 %f", devc->vert_offset[0],
-                       devc->vert_offset[1]);
-
-       /* Coupling. */
-       if (get_cfg_string(sdi, ":CHAN1:COUP?", &devc->coupling[0]) != SR_OK)
-               return SR_ERR;
-       if (get_cfg_string(sdi, ":CHAN2:COUP?", &devc->coupling[1]) != SR_OK)
-               return SR_ERR;
-       sr_dbg("Current coupling CH1 %s CH2 %s", devc->coupling[0],
-                       devc->coupling[1]);
-
-       /* Trigger source. */
-       if (get_cfg_string(sdi, ":TRIG:EDGE:SOUR?", &devc->trigger_source) != SR_OK)
-               return SR_ERR;
-       sr_dbg("Current trigger source %s", devc->trigger_source);
-
-       /* Horizontal trigger position. */
-       if (get_cfg_float(sdi, ":TIM:OFFS?", &devc->horiz_triggerpos) != SR_OK)
-               return SR_ERR;
-       sr_dbg("Current horizontal trigger position %f", devc->horiz_triggerpos);
-
-       /* Trigger slope. */
-       if (get_cfg_string(sdi, ":TRIG:EDGE:SLOP?", &devc->trigger_slope) != SR_OK)
-               return SR_ERR;
-       sr_dbg("Current trigger slope %s", devc->trigger_slope);
-
-       return SR_OK;
-}
diff --git a/hardware/rigol-ds1xx2/protocol.h b/hardware/rigol-ds1xx2/protocol.h
deleted file mode 100644 (file)
index ff345fd..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This file is part of the libsigrok project.
- *
- * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
- * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LIBSIGROK_HARDWARE_RIGOL_DS1XX2_PROTOCOL_H
-#define LIBSIGROK_HARDWARE_RIGOL_DS1XX2_PROTOCOL_H
-
-#include <stdint.h>
-#include "libsigrok.h"
-#include "libsigrok-internal.h"
-
-/* Message logging helpers with subsystem-specific prefix string. */
-#define LOG_PREFIX "rigol-ds1xx2: "
-#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
-#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
-#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
-#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
-#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
-#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
-
-#define ANALOG_WAVEFORM_SIZE 600
-#define DIGITAL_WAVEFORM_SIZE 1210
-
-/** Private, per-device-instance driver context. */
-struct dev_context {
-       /* Device features */
-       gboolean has_digital;
-
-       /* Probe groups */
-       struct sr_probe_group analog_groups[2];
-       struct sr_probe_group digital_group;
-
-       /* Acquisition settings */
-       GSList *enabled_analog_probes;
-       GSList *enabled_digital_probes;
-       uint64_t limit_frames;
-       void *cb_data;
-
-       /* Device settings */
-       gboolean analog_channels[2];
-       gboolean digital_channels[16];
-       float timebase;
-       float vdiv[2];
-       float vert_offset[2];
-       char *trigger_source;
-       float horiz_triggerpos;
-       char *trigger_slope;
-       char *coupling[2];
-
-       /* Operational state */
-       uint64_t num_frames;
-       uint64_t num_frame_bytes;
-       struct sr_probe *channel_frame;
-};
-
-SR_PRIV int rigol_ds1xx2_receive(int fd, int revents, void *cb_data);
-SR_PRIV int rigol_ds1xx2_send(const struct sr_dev_inst *sdi, const char *format, ...);
-SR_PRIV int rigol_ds1xx2_get_dev_cfg(const struct sr_dev_inst *sdi);
-
-#endif
index 5897b63eb823f6509bba1fe98a53731d671698d6..804838c8cc7369a7179ecc377cff9c3bf8399204 100644 (file)
@@ -148,8 +148,8 @@ extern SR_PRIV struct sr_dev_driver norma_dmm_driver_info;
 #ifdef HAVE_HW_OLS
 extern SR_PRIV struct sr_dev_driver ols_driver_info;
 #endif
 #ifdef HAVE_HW_OLS
 extern SR_PRIV struct sr_dev_driver ols_driver_info;
 #endif
-#ifdef HAVE_HW_RIGOL_DS1XX2
-extern SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
+#ifdef HAVE_HW_RIGOL_DS
+extern SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
 #endif
 #ifdef HAVE_HW_SALEAE_LOGIC16
 extern SR_PRIV struct sr_dev_driver saleae_logic16_driver_info;
 #endif
 #ifdef HAVE_HW_SALEAE_LOGIC16
 extern SR_PRIV struct sr_dev_driver saleae_logic16_driver_info;
@@ -274,8 +274,8 @@ static struct sr_dev_driver *drivers_list[] = {
 #ifdef HAVE_HW_OLS
        &ols_driver_info,
 #endif
 #ifdef HAVE_HW_OLS
        &ols_driver_info,
 #endif
-#ifdef HAVE_HW_RIGOL_DS1XX2
-       &rigol_ds1xx2_driver_info,
+#ifdef HAVE_HW_RIGOL_DS
+       &rigol_ds_driver_info,
 #endif
 #ifdef HAVE_HW_SALEAE_LOGIC16
        &saleae_logic16_driver_info,
 #endif
 #ifdef HAVE_HW_SALEAE_LOGIC16
        &saleae_logic16_driver_info,