]> sigrok.org Git - libsigrok.git/commitdiff
Code drop from DreamSourceLabs first source release. dslogic
authorBert Vermeulen <redacted>
Mon, 16 Dec 2013 00:31:46 +0000 (01:31 +0100)
committerBert Vermeulen <redacted>
Mon, 16 Dec 2013 00:31:46 +0000 (01:31 +0100)
31 files changed:
Makefile.am
README
autogen.sh [changed mode: 0755->0644]
configure.ac
device.c
hardware/Makefile.am
hardware/demo/Makefile.am
hardware/demo/demo.c
hwdriver.c
input/Makefile.am
input/in_binary.c [new file with mode: 0644]
input/in_vcd.c [new file with mode: 0644]
input/in_wav.c [new file with mode: 0644]
input/input.c
libsigrok-internal.h
libsigrok.h
libsigrok4DSLogic.pc.in [new file with mode: 0644]
libusbhp.c [new file with mode: 0644]
output/Makefile.am
output/out_analog.c [new file with mode: 0644]
output/out_binary.c [new file with mode: 0644]
output/out_csv.c [new file with mode: 0644]
output/out_vcd.c [new file with mode: 0644]
output/output.c
output/text/Makefile.am
proto.h
session.c
session_driver.c
session_file.c
tests/Makefile.am
trigger.c [new file with mode: 0644]

index 68dbed5370c896d8a297527548ad362f3135594b..52c9f0e482b7ec276c201e88680eee5fe2cc3b8d 100644 (file)
@@ -1,5 +1,5 @@
 ##
-## This file is part of the libsigrok project.
+## This file is part of the libsigrok4DSLogic project.
 ##
 ## Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
 ## Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
@@ -22,11 +22,11 @@ ACLOCAL_AMFLAGS = -I autostuff
 
 AM_CPPFLAGS = -I$(top_srcdir)
 
-SUBDIRS = contrib hardware input output tests
+SUBDIRS = hardware input output tests
 
-lib_LTLIBRARIES = libsigrok.la
+lib_LTLIBRARIES = libsigrok4DSLogic.la
 
-libsigrok_la_SOURCES = \
+libsigrok4DSLogic_la_SOURCES = \
        backend.c \
        device.c \
        session.c \
@@ -36,24 +36,25 @@ libsigrok_la_SOURCES = \
        filter.c \
        strutil.c \
        log.c \
+        trigger.c \
        version.c \
        error.c \
        std.c
 
-libsigrok_la_LIBADD = \
+libsigrok4DSLogic_la_LIBADD = \
        $(LIBOBJS) \
-       hardware/libsigrokhardware.la \
-       input/libsigrokinput.la \
-       output/libsigrokoutput.la
+       hardware/libsigrok4DSLogichardware.la \
+       input/libsigrok4DSLogicinput.la \
+       output/libsigrok4DSLogicoutput.la
 
-libsigrok_la_LDFLAGS = $(SR_LIB_LDFLAGS)
+libsigrok4DSLogic_la_LDFLAGS = $(SR_LIB_LDFLAGS)
 
-library_includedir = $(includedir)/libsigrok
+library_includedir = $(includedir)/libsigrok4DSLogic
 library_include_HEADERS = libsigrok.h proto.h version.h
 noinst_HEADERS = libsigrok-internal.h
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libsigrok.pc
+pkgconfig_DATA = libsigrok4DSLogic.pc
 
 EXTRA_DIST = Doxyfile README.devices
 
diff --git a/README b/README
index 0e74f7b001b13bc341507a7e6aebe5ce4bac5760..437294c40b09b8fb34539f1e2af50a99c862fc29 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,9 @@
 -------------------------------------------------------------------------------
 README
 -------------------------------------------------------------------------------
+libsigrok4DSLogic is a shared library which provides the basic API
+for DSLogic hardware.
+libsigrok4DSLogic is based on libsigrok, a shared library from the sigrok project.
 
 The sigrok project aims at creating a portable, cross-platform,
 Free/Libre/Open-Source signal analysis software suite that supports various
@@ -38,23 +41,21 @@ Requirements
  - libzip >= 0.8
  - libusb-1.0 >= 1.0.9 (optional, used by most drivers)
  - libftdi >= 0.16 (optional, used by some drivers)
- - libudev >= 151 (optional, used by some drivers)
  - libasound / alsa-lib >= 1.0 (optional, only used by the alsa driver)
  - check >= 0.9.4 (optional, only needed to run unit tests)
 
 
 Building and installing
 -----------------------
+Get the libsigrok4DSLogic source code from: www.dreamsourcelab.com/download.html
+In order to build it, run:
 
-In order to get the libsigrok source code and build it, run:
-
- $ git clone git://sigrok.org/libsigrok
  $ cd libsigrok
  $ ./autogen.sh
  $ ./configure
  $ make
 
-For installing libsigrok:
+For installing libsigrok4DSLogic:
 
  $ make install
 
@@ -63,24 +64,10 @@ See INSTALL or the following wiki page for more (OS-specific) instructions:
  http://sigrok.org/wiki/Building
 
 
-Device-specific issues
-----------------------
-
-Please check README.devices for some notes and hints about device- or
-driver-specific issues to be aware of.
-
-
-Firmware
---------
-
-Some devices supported by libsigrok need a firmware to be uploaded before the
-device can be used. See README.devices for details.
-
-
 Copyright and license
 ---------------------
 
-libsigrok is licensed under the terms of the GNU General Public License
+libsigrok4DSLogic is licensed under the terms of the GNU General Public License
 (GPL), version 3 or later.
 
 While some individual source code files are licensed under the GPLv2+, and
@@ -109,4 +96,5 @@ Website
 -------
 
  http://sigrok.org/wiki/Libsigrok
+ http://dreamsourcelab.com
 
old mode 100755 (executable)
new mode 100644 (file)
index e475f6fd23b4ecc8be4c79e2dc6dc7da0f025bee..a54b23a4913ec3716acc321585cb4cf5810563d4 100644 (file)
@@ -27,8 +27,8 @@ m4_define([sr_package_version_minor], [2])
 m4_define([sr_package_version_micro], [0])
 m4_define([sr_package_version], [sr_package_version_major.sr_package_version_minor.sr_package_version_micro])
 
-AC_INIT([libsigrok], [sr_package_version], [sigrok-devel@lists.sourceforge.net],
-       [libsigrok], [http://www.sigrok.org])
+AC_INIT([libsigrok4DSLogic], [sr_package_version], [support@dreamsourcelab.com],
+       [libsigrok4DSLogic], [http://www.dreamsourcelab.com])
 AC_CONFIG_HEADER([config.h])
 AC_CONFIG_MACRO_DIR([autostuff])
 AC_CONFIG_AUX_DIR([autostuff])
@@ -67,7 +67,7 @@ PKG_PROG_PKG_CONFIG([0.22])
 # The algorithm for determining which number to change (and how) is nontrivial!
 # http://www.gnu.org/software/libtool/manual/libtool.html#Updating-version-info
 SR_LIB_VERSION_CURRENT=1
-SR_LIB_VERSION_REVISION=0
+SR_LIB_VERSION_REVISION=2
 SR_LIB_VERSION_AGE=0
 SR_LIB_VERSION="$SR_LIB_VERSION_CURRENT:$SR_LIB_VERSION_REVISION:$SR_LIB_VERSION_AGE"
 SR_LIB_LDFLAGS="-version-info $SR_LIB_VERSION"
@@ -77,126 +77,31 @@ AC_SUBST(SR_LIB_VERSION_AGE)
 AC_SUBST(SR_LIB_VERSION)
 AC_SUBST(SR_LIB_LDFLAGS)
 
-# Hardware support '--enable' options.
-
 AC_ARG_ENABLE(all-drivers, AC_HELP_STRING([--enable-all-drivers],
-       [enable all drivers by default [default=yes]]),
-       [HW_ENABLED_DEFAULT="$enableval"],
-       [HW_ENABLED_DEFAULT="yes"])
-
-AC_ARG_ENABLE(agilent-dmm, AC_HELP_STRING([--enable-agilent-dmm],
-       [enable Agilent DMM support [default=yes]]),
-       [HW_AGILENT_DMM="$enableval"],
-       [HW_AGILENT_DMM=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(alsa, AC_HELP_STRING([--enable-alsa],
-       [enable ALSA driver support [default=yes]]),
-       [HW_ALSA="$enableval"],
-       [HW_ALSA=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(asix-sigma, AC_HELP_STRING([--enable-asix-sigma],
-       [enable ASIX SIGMA/SIGMA2 support [default=yes]]),
-       [LA_ASIX_SIGMA="$enableval"],
-       [LA_ASIX_SIGMA=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(brymen-dmm, AC_HELP_STRING([--enable-brymen-dmm],
-       [enable Brymen DMM support [default=yes]]),
-       [HW_BRYMEN_DMM="$enableval"],
-       [HW_BRYMEN_DMM=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(chronovu-la8, AC_HELP_STRING([--enable-chronovu-la8],
-       [enable ChronoVu LA8 support [default=yes]]),
-       [LA_CHRONOVU_LA8="$enableval"],
-       [LA_CHRONOVU_LA8=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(colead-slm, AC_HELP_STRING([--enable-colead-slm],
-       [enable Colead SLM support [default=yes]]),
-       [HW_COLEAD_SLM="$enableval"],
-       [HW_COLEAD_SLM=$HW_ENABLED_DEFAULT])
+        [enable all drivers by default [default=yes]]),
+        [HW_ENABLED_DEFAULT="$enableval"],
+        [HW_ENABLED_DEFAULT="yes"])
 
 AC_ARG_ENABLE(demo, AC_HELP_STRING([--enable-demo],
        [enable demo driver support [default=yes]]),
-       [LA_DEMO="$enableval"],
-       [LA_DEMO=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(fluke-dmm, AC_HELP_STRING([--enable-fluke-dmm],
-       [enable Fluke DMM support [default=yes]]),
-       [HW_FLUKE_DMM="$enableval"],
-       [HW_FLUKE_DMM=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(fx2lafw, AC_HELP_STRING([--enable-fx2lafw],
-       [enable fx2lafw support (for FX2 LAs). [default=yes]]),
-       [LA_FX2LAFW="$enableval"],
-       [LA_FX2LAFW=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(hantek-dso, AC_HELP_STRING([--enable-hantek-dso],
-       [enable Hantek DSO support [default=yes]]),
-       [HW_HANTEK_DSO="$enableval"],
-       [HW_HANTEK_DSO=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(lascar-el-usb, AC_HELP_STRING([--enable-lascar-el-usb],
-       [enable Lascar EL-USB support [default=yes]]),
-       [HW_LASCAR_EL_USB="$enableval"],
-       [HW_LASCAR_EL_USB=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(link-mso19, AC_HELP_STRING([--enable-link-mso19],
-       [enable Link Instruments MSO-19 support [default=yes]]),
-       [LA_LINK_MSO19="$enableval"],
-       [LA_LINK_MSO19=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(mic-985xx, AC_HELP_STRING([--enable-mic-985xx],
-       [enable MIC 985xx support [default=yes]]),
-       [HW_MIC_985XX="$enableval"],
-       [HW_MIC_985XX=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(nexus-osciprime, AC_HELP_STRING([--enable-nexus-osciprime],
-       [enable Nexus Osciprime support [default=yes]]),
-       [HW_NEXUS_OSCIPRIME="$enableval"],
-       [HW_NEXUS_OSCIPRIME=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(ols, AC_HELP_STRING([--enable-ols],
-       [enable OpenBench Logic Sniffer (OLS) support [default=yes]]),
-       [LA_OLS="$enableval"],
-       [LA_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(serial-dmm, AC_HELP_STRING([--enable-serial-dmm],
-       [enable serial DMM support [default=yes]]),
-       [HW_SERIAL_DMM="$enableval"],
-       [HW_SERIAL_DMM=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(tondaj-sl-814, AC_HELP_STRING([--enable-tondaj-sl-814],
-       [enable Tondaj SL-814 support [default=yes]]),
-       [HW_TONDAJ_SL_814="$enableval"],
-       [HW_TONDAJ_SL_814=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(uni-t-dmm, AC_HELP_STRING([--enable-uni-t-dmm],
-       [enable UNI-T DMM support [default=yes]]),
-       [HW_UNI_T_DMM="$enableval"],
-       [HW_UNI_T_DMM=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(victor-dmm, AC_HELP_STRING([--enable-victor-dmm],
-       [enable victor-dmm support [default=yes]]),
-       [HW_VICTOR_DMM="$enableval"],
-       [HW_VICTOR_DMM=$HW_ENABLED_DEFAULT])
-
-AC_ARG_ENABLE(zeroplus-logic-cube,
-       AC_HELP_STRING([--enable-zeroplus-logic-cube],
-       [enable ZEROPLUS Logic Cube support [default=yes]]),
-       [LA_ZEROPLUS_LOGIC_CUBE="$enableval"],
-       [LA_ZEROPLUS_LOGIC_CUBE=$HW_ENABLED_DEFAULT])
-
+       [HW_DEMO="$enableval"],
+       [HW_DEMO=$HW_ENABLED_DEFAULT])
 # Checks for libraries.
 
+case "$host" in
+*mingw*)
+       # We need to link against the Winsock2 library for SCPI over TCP.
+       LIBS="$LIBS -lws2_32";;
+esac
+
 # This variable collects the pkg-config names of all detected libs.
 # It is then used to construct the "Requires.private:" field in the
-# libsigrok.pc file.
+# libsigrok4DSLogic.pc file.
 SR_PKGLIBS=""
 
+# libm (the standard math library) is always needed.
+AC_SEARCH_LIBS([pow], [m])
+
 # libglib-2.0 is always needed. Abort if it's not found.
 # Note: glib-2.0 is part of the libsigrok API (hard pkg-config requirement).
 # We require at least 2.32.0 due to e.g. g_variant_new_fixed_array().
@@ -204,10 +109,27 @@ AM_PATH_GLIB_2_0([2.32.0],
        [CFLAGS="$CFLAGS $GLIB_CFLAGS"; LIBS="$LIBS $GLIB_LIBS"])
 
 # libzip is always needed. Abort if it's not found.
-PKG_CHECK_MODULES([libzip], [libzip >= 0.8],
+PKG_CHECK_MODULES([libzip], [libzip >= 0.10],
        [CFLAGS="$CFLAGS $libzip_CFLAGS"; LIBS="$LIBS $libzip_LIBS";
        SR_PKGLIBS="$SR_PKGLIBS libzip"])
 
+# libserialport is only needed for some hardware drivers. Disable the
+# respective drivers if it is not found.
+PKG_CHECK_MODULES([libserialport], [libserialport >= 0.1.0],
+       [have_libserialport="yes"; CFLAGS="$CFLAGS $libserialport_CFLAGS";
+       LIBS="$LIBS $libserialport_LIBS";
+       SR_PKGLIBS="$SR_PKGLIBS libserialport"],
+       [have_libserialport="no"])
+
+# Define HAVE_LIBSERIALPORT in config.h if we found libserialport.
+if test "x$have_libserialport" != "xno"; then
+       AC_DEFINE_UNQUOTED(HAVE_LIBSERIALPORT, [1],
+               [Specifies whether we have libserialport.])
+fi
+
+# Serial port helper code is only compiled in if libserialport was found.
+AM_CONDITIONAL(NEED_SERIAL, test "x$have_libserialport" != xno)
+
 # libusb-1.0 is only needed for some hardware drivers. Disable the respective
 # drivers if it is not found.
 case "$host" in
@@ -223,10 +145,7 @@ case "$host" in
                [have_libusb1_0="yes"; CFLAGS="$CFLAGS $libusb_CFLAGS";
                LIBS="$LIBS $libusb_LIBS";
                SR_PKGLIBS="$SR_PKGLIBS libusb-1.0"],
-               [have_libusb1_0="no"; LA_FX2LAFW="no"; HW_HANTEK_DSO="no";
-               HW_LASCAR_EL_USB="no"; HW_NEXUS_OSCIPRIME="no";
-               HW_UNI_T_DMM="no"; HW_VICTOR_DMM="no";
-               LA_ZEROPLUS_LOGIC_CUBE="no"])
+               [have_libusb1_0="no"])
 
        # Define HAVE_LIBUSB_1_0 in config.h if we found libusb-1.0.
        if test "x$have_libusb1_0" != "xno"; then
@@ -236,27 +155,7 @@ case "$host" in
        ;;
 esac
 
-# USB + FX2 firmware helper code is only compiled in if libusb-1.0 was found.
-AM_CONDITIONAL(NEED_USB, test "x$have_libusb1_0" != xno)
-
-# libftdi is only needed for some hardware drivers. Disable them if not found.
-PKG_CHECK_MODULES([libftdi], [libftdi >= 0.16],
-       [CFLAGS="$CFLAGS $libftdi_CFLAGS";
-       LIBS="$LIBS $libftdi_LIBS";
-       SR_PKGLIBS="$SR_PKGLIBS libftdi"],
-       [LA_ASIX_SIGMA="no"; LA_CHRONOVU_LA8="no"])
 
-# libudev is only needed for some hardware drivers. Disable them if not found.
-PKG_CHECK_MODULES([libudev], [libudev >= 151],
-       [CFLAGS="$CFLAGS $libudev_CFLAGS"; LIBS="$LIBS $libudev_LIBS";
-       SR_PKGLIBS="$SR_PKGLIBS libudev"],
-       [LA_LINK_MSO19="no"])
-
-# ALSA is only needed for some hardware drivers. Disable them if not found.
-PKG_CHECK_MODULES([alsa], [alsa >= 1.0],
-       [CFLAGS="$CFLAGS $alsa_CFLAGS"; LIBS="$LIBS $alsa_LIBS";
-       SR_PKGLIBS="$SR_PKGLIBS alsa"],
-       [HW_ALSA="no"])
 
 # The Check unit testing framework is optional. Disable if not found.
 PKG_CHECK_MODULES([check], [check >= 0.9.4],
@@ -264,135 +163,29 @@ PKG_CHECK_MODULES([check], [check >= 0.9.4],
        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
-# (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.
-       ;;
-*)
-       # Disable the driver for builds that don't target Linux.
-       HW_RIGOL_DS1XX2="no"
-       ;;
-esac
+# The OLS driver uses serial port file descriptors directly, and therefore
+# will not currently work on Windows.
+
 
 AC_SUBST(SR_PKGLIBS)
 
 # Now set AM_CONDITIONALs and AC_DEFINEs for the enabled/disabled drivers.
 
-AM_CONDITIONAL(HW_AGILENT_DMM, test x$HW_AGILENT_DMM = xyes)
-if test "x$HW_AGILENT_DMM" = "xyes"; then
-       AC_DEFINE(HAVE_HW_AGILENT_DMM, 1, [Agilent DMM support])
-fi
-
-AM_CONDITIONAL(HW_ALSA, test x$HW_ALSA = xyes)
-if test "x$HW_ALSA" = "xyes"; then
-       AC_DEFINE(HAVE_HW_ALSA, 1, [ALSA driver support])
-fi
-
-AM_CONDITIONAL(LA_ASIX_SIGMA, test x$LA_ASIX_SIGMA = xyes)
-if test "x$LA_ASIX_SIGMA" = "xyes"; then
-       AC_DEFINE(HAVE_LA_ASIX_SIGMA, 1, [ASIX SIGMA/SIGMA2 support])
-fi
-
-AM_CONDITIONAL(HW_BRYMEN_DMM, test x$HW_BRYMEN_DMM = xyes)
-if test "x$HW_BRYMEN_DMM" = "xyes"; then
-       AC_DEFINE(HAVE_HW_BRYMEN_DMM, 1, [Brymen DMM support])
-fi
-
-AM_CONDITIONAL(LA_CHRONOVU_LA8, test x$LA_CHRONOVU_LA8 = xyes)
-if test "x$LA_CHRONOVU_LA8" = "xyes"; then
-       AC_DEFINE(HAVE_LA_CHRONOVU_LA8, 1, [ChronoVu LA8 support])
-fi
 
-AM_CONDITIONAL(HW_COLEAD_SLM, test x$HW_COLEAD_SLM = xyes)
-if test "x$HW_COLEAD_SLM" = "xyes"; then
-       AC_DEFINE(HAVE_HW_COLEAD_SLM, 1, [Colead SLM support])
-fi
 
-AM_CONDITIONAL(LA_DEMO, test x$LA_DEMO = xyes)
-if test "x$LA_DEMO" = "xyes"; then
+AM_CONDITIONAL(HW_DEMO, test x$HW_DEMO = xyes)
+if test "x$HW_DEMO" = "xyes"; then
        AC_DEFINE(HAVE_LA_DEMO, 1, [Demo driver support])
 fi
 
-AM_CONDITIONAL(HW_FLUKE_DMM, test x$HW_FLUKE_DMM = xyes)
-if test "x$HW_FLUKE_DMM" = "xyes"; then
-       AC_DEFINE(HAVE_HW_FLUKE_DMM, 1, [Fluke DMM support])
-fi
-
-AM_CONDITIONAL(LA_FX2LAFW, test x$LA_FX2LAFW = xyes)
-if test "x$LA_FX2LAFW" = "xyes"; then
-       AC_DEFINE(HAVE_LA_FX2LAFW, 1, [fx2lafw support])
-fi
-
-AM_CONDITIONAL(HW_HANTEK_DSO, test x$HW_HANTEK_DSO = xyes)
-if test "x$HW_HANTEK_DSO" = "xyes"; then
-       AC_DEFINE(HAVE_HW_HANTEK_DSO, 1, [Hantek DSO support])
-fi
-
-AM_CONDITIONAL(HW_LASCAR_EL_USB, test x$HW_LASCAR_EL_USB = xyes)
-if test "x$HW_LASCAR_EL_USB" = "xyes"; then
-       AC_DEFINE(HAVE_HW_LASCAR_EL_USB, 1, [Lascar EL-USB support])
-fi
-
-AM_CONDITIONAL(LA_LINK_MSO19, test x$LA_LINK_MSO19 = xyes)
-if test "x$LA_LINK_MSO19" = "xyes"; then
-       AC_DEFINE(HAVE_LA_LINK_MSO19, 1, [Link Instruments MSO-19 support])
-fi
-
-AM_CONDITIONAL(HW_MIC_985XX, test x$HW_MIC_985XX = xyes)
-if test "x$HW_MIC_985XX" = "xyes"; then
-       AC_DEFINE(HAVE_HW_MIC_985XX, 1, [MIC 985xx support])
-fi
-
-AM_CONDITIONAL(HW_NEXUS_OSCIPRIME, test x$HW_NEXUS_OSCIPRIME = xyes)
-if test "x$HW_NEXUS_OSCIPRIME" = "xyes"; then
-       AC_DEFINE(HAVE_HW_NEXUS_OSCIPRIME, 1, [Nexus Osciprime support])
-fi
 
-AM_CONDITIONAL(LA_OLS, test x$LA_OLS = xyes)
-if test "x$LA_OLS" = "xyes"; then
-       AC_DEFINE(HAVE_LA_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])
-fi
-
-AM_CONDITIONAL(HW_SERIAL_DMM, test x$HW_SERIAL_DMM = xyes)
-if test "x$HW_SERIAL_DMM" = "xyes"; then
-       AC_DEFINE(HAVE_HW_SERIAL_DMM, 1, [Serial DMM support])
-fi
-
-AM_CONDITIONAL(HW_TONDAJ_SL_814, test x$HW_TONDAJ_SL_814 = xyes)
-if test "x$HW_TONDAJ_SL_814" = "xyes"; then
-       AC_DEFINE(HAVE_HW_TONDAJ_SL_814, 1, [Tondaj SL-814 support])
-fi
-
-AM_CONDITIONAL(HW_UNI_T_DMM, test x$HW_UNI_T_DMM = xyes)
-if test "x$HW_UNI_T_DMM" = "xyes"; then
-       AC_DEFINE(HAVE_HW_UNI_T_DMM, 1, [UNI-T DMM support])
-fi
-
-AM_CONDITIONAL(HW_VICTOR_DMM, test x$HW_VICTOR_DMM = xyes)
-if test "x$HW_VICTOR_DMM" = "xyes"; then
-       AC_DEFINE(HAVE_HW_VICTOR_DMM, 1, [Victor DMM support])
-fi
-
-AM_CONDITIONAL(LA_ZEROPLUS_LOGIC_CUBE, test x$LA_ZEROPLUS_LOGIC_CUBE = xyes)
-if test "x$LA_ZEROPLUS_LOGIC_CUBE" = "xyes"; then
-       AC_DEFINE(HAVE_LA_ZEROPLUS_LOGIC_CUBE, 1, [ZEROPLUS Logic Cube support])
-fi
 
 # Checks for header files.
 # These are already checked: inttypes.h stdint.h stdlib.h string.h unistd.h.
 AC_CHECK_HEADERS([fcntl.h sys/time.h termios.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
+AC_C_BIGENDIAN
 AC_C_INLINE
 AC_TYPE_INT8_T
 AC_TYPE_INT16_T
@@ -422,34 +215,11 @@ AC_SUBST(SR_PACKAGE_VERSION_MICRO)
 AC_SUBST(SR_PACKAGE_VERSION)
 
 AC_CONFIG_FILES([Makefile version.h hardware/Makefile
-                hardware/agilent-dmm/Makefile
-                hardware/alsa/Makefile
-                hardware/asix-sigma/Makefile
-                hardware/brymen-dmm/Makefile
-                hardware/chronovu-la8/Makefile
-                hardware/colead-slm/Makefile
-                hardware/common/Makefile
-                hardware/lascar-el-usb/Makefile
-                hardware/mic-985xx/Makefile
-                hardware/nexus-osciprime/Makefile
-                hardware/rigol-ds1xx2/Makefile
-                hardware/tondaj-sl-814/Makefile
-                hardware/victor-dmm/Makefile
-                hardware/common/dmm/Makefile
                 hardware/demo/Makefile
-                hardware/fluke-dmm/Makefile
-                hardware/fx2lafw/Makefile
-                hardware/hantek-dso/Makefile
-                hardware/link-mso19/Makefile
-                hardware/openbench-logic-sniffer/Makefile
-                hardware/serial-dmm/Makefile
-                hardware/uni-t-dmm/Makefile
-                hardware/zeroplus-logic-cube/Makefile
                 input/Makefile
                 output/Makefile
                 output/text/Makefile
-                libsigrok.pc
-                contrib/Makefile
+                libsigrok4DSLogic.pc
                 tests/Makefile
                ])
 
@@ -468,7 +238,7 @@ echo "Detected libraries:"
 echo
 
 # Note: This only works for libs with pkg-config integration.
-for lib in "glib-2.0 >= 2.32.0" "libzip >= 0.8" "libusb-1.0 >= 1.0.9" "libftdi >= 0.16" "libudev >= 151" "alsa >= 1.0" "check >= 0.9.4"; do
+for lib in "glib-2.0 >= 2.32.0" "libzip >= 0.10" "libserialport >= 0.1.0" "libusb-1.0 >= 1.0.9" "libftdi >= 0.16" "libudev >= 151" "alsa >= 1.0" "check >= 0.9.4"; do
        if `$PKG_CONFIG --exists $lib`; then
                ver=`$PKG_CONFIG --modversion $lib`
                answer="yes ($ver)"
@@ -479,26 +249,6 @@ for lib in "glib-2.0 >= 2.32.0" "libzip >= 0.8" "libusb-1.0 >= 1.0.9" "libftdi >
 done
 
 echo -e "\nEnabled hardware drivers:\n"
-echo "  - agilent-dmm..................... $HW_AGILENT_DMM"
-echo "  - alsa............................ $HW_ALSA"
-echo "  - asix-sigma...................... $LA_ASIX_SIGMA"
-echo "  - brymen-dmm...................... $HW_BRYMEN_DMM"
-echo "  - chronovu-la8.................... $LA_CHRONOVU_LA8"
-echo "  - colead-slm...................... $HW_COLEAD_SLM"
-echo "  - demo............................ $LA_DEMO"
-echo "  - fluke-dmm....................... $HW_FLUKE_DMM"
-echo "  - fx2lafw......................... $LA_FX2LAFW"
-echo "  - hantek-dso...................... $HW_HANTEK_DSO"
-echo "  - lascar-el-usb................... $HW_LASCAR_EL_USB"
-echo "  - link-mso19...................... $LA_LINK_MSO19"
-echo "  - mic-985xx....................... $HW_MIC_985XX"
-echo "  - nexus-osciprime................. $HW_NEXUS_OSCIPRIME"
-echo "  - openbench-logic-sniffer......... $LA_OLS"
-echo "  - rigol-ds1xx2.................... $HW_RIGOL_DS1XX2"
-echo "  - serial-dmm...................... $HW_SERIAL_DMM"
-echo "  - tondaj-sl-814................... $HW_TONDAJ_SL_814"
-echo "  - uni-t-dmm....................... $HW_UNI_T_DMM"
-echo "  - victor-dmm...................... $HW_VICTOR_DMM"
-echo "  - zeroplus-logic-cube............. $LA_ZEROPLUS_LOGIC_CUBE"
+echo "  - demo............................ $HW_DEMO"
 echo
 
index a49faa8d595df9c05743adb9ec5fbce6b79898e2..cca0bcd33d5e99b8c9790a90bf7d0f9d2d323667 100644 (file)
--- a/device.c
+++ b/device.c
@@ -225,7 +225,7 @@ SR_API gboolean sr_dev_has_option(const struct sr_dev_inst *sdi, int key)
 }
 
 /** @private */
-SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int index, int status,
+SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status,
                const char *vendor, const char *model, const char *version)
 {
        struct sr_dev_inst *sdi;
@@ -236,6 +236,7 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int index, int status,
        }
 
        sdi->driver = NULL;
+    sdi->mode = mode;
        sdi->index = index;
        sdi->status = status;
        sdi->inst_type = -1;
@@ -250,6 +251,20 @@ SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int index, int status,
 }
 
 /** @private */
+SR_PRIV void sr_dev_probes_free(struct sr_dev_inst *sdi)
+{
+    struct sr_probe *probe;
+    GSList *l;
+
+    for (l = sdi->probes; l; l = l->next) {
+        probe = l->data;
+        g_free(probe->name);
+        g_free(probe);
+    }
+
+    sdi->probes = NULL;
+}
+
 SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi)
 {
        struct sr_probe *probe;
index 3c093b76cc0b278b2a8fa7c8ad7e9a5b67f7da09..4f5d0a7bc314989991be349104af2b4af481eb94 100644 (file)
 ##
 
 SUBDIRS = \
-       agilent-dmm \
-       alsa \
-       asix-sigma \
-       brymen-dmm \
-       chronovu-la8 \
-       colead-slm \
-       common \
-       demo \
-       fluke-dmm \
-       fx2lafw \
-       hantek-dso \
-       lascar-el-usb \
-       link-mso19 \
-       mic-985xx \
-       nexus-osciprime \
-       openbench-logic-sniffer \
-       rigol-ds1xx2 \
-       serial-dmm \
-       tondaj-sl-814 \
-       uni-t-dmm \
-       victor-dmm \
-       zeroplus-logic-cube
+       demo
 
-noinst_LTLIBRARIES = libsigrokhardware.la
+noinst_LTLIBRARIES = libsigrok4DSLogichardware.la
 
-libsigrokhardware_la_SOURCES =
+libsigrok4DSLogichardware_la_SOURCES =
 
-libsigrokhardware_la_LIBADD = \
-       common/libsigrokhwcommon.la
+libsigrok4DSLogichardware_la_LIBADD = 
 
-if HW_AGILENT_DMM
-libsigrokhardware_la_LIBADD += agilent-dmm/libsigrokhwagilentdmm.la
+if HW_DEMO
+libsigrok4DSLogichardware_la_LIBADD += demo/libsigrok4DSLogic_hw_demo.la
 endif
-
-if HW_ALSA
-libsigrokhardware_la_LIBADD += alsa/libsigrokhwalsa.la
-endif
-
-if LA_ASIX_SIGMA
-libsigrokhardware_la_LIBADD += asix-sigma/libsigrokhwasixsigma.la
-endif
-
-if HW_BRYMEN_DMM
-libsigrokhardware_la_LIBADD += brymen-dmm/libsigrok_hw_brymen_dmm.la
-endif
-
-if LA_CHRONOVU_LA8
-libsigrokhardware_la_LIBADD += chronovu-la8/libsigrokhwchronovula8.la
-endif
-
-if HW_COLEAD_SLM
-libsigrokhardware_la_LIBADD += colead-slm/libsigrok_hw_colead_slm.la
-endif
-
-if LA_DEMO
-libsigrokhardware_la_LIBADD += demo/libsigrokhwdemo.la
-endif
-
-if HW_FLUKE_DMM
-libsigrokhardware_la_LIBADD += fluke-dmm/libsigrokhwflukedmm.la
-endif
-
-if LA_FX2LAFW
-libsigrokhardware_la_LIBADD += fx2lafw/libsigrokhwfx2lafw.la
-endif
-
-if HW_HANTEK_DSO
-libsigrokhardware_la_LIBADD += hantek-dso/libsigrokhw_hantek_dso.la
-endif
-
-if HW_LASCAR_EL_USB
-libsigrokhardware_la_LIBADD += lascar-el-usb/libsigrok_hw_lascar_el_usb.la
-endif
-
-if LA_LINK_MSO19
-libsigrokhardware_la_LIBADD += link-mso19/libsigrokhwlinkmso19.la
-endif
-
-if HW_MIC_985XX
-libsigrokhardware_la_LIBADD += mic-985xx/libsigrok_hw_mic_985xx.la
-endif
-
-if HW_NEXUS_OSCIPRIME
-libsigrokhardware_la_LIBADD += nexus-osciprime/libsigrok_hw_nexus_osciprime.la
-endif
-
-if LA_OLS
-libsigrokhardware_la_LIBADD += openbench-logic-sniffer/libsigrokhwols.la
-endif
-
-if HW_RIGOL_DS1XX2
-libsigrokhardware_la_LIBADD += rigol-ds1xx2/libsigrok_hw_rigol_ds1xx2.la
-endif
-
-if HW_SERIAL_DMM
-libsigrokhardware_la_LIBADD += serial-dmm/libsigrokhwserialdmm.la
-endif
-
-if HW_TONDAJ_SL_814
-libsigrokhardware_la_LIBADD += tondaj-sl-814/libsigrok_hw_tondaj_sl_814.la
-endif
-
-if HW_UNI_T_DMM
-libsigrokhardware_la_LIBADD += uni-t-dmm/libsigrok_hw_uni_t_dmm.la
-endif
-
-if HW_VICTOR_DMM
-libsigrokhardware_la_LIBADD += victor-dmm/libsigrok_hw_victor_dmm.la
-endif
-
-if LA_ZEROPLUS_LOGIC_CUBE
-libsigrokhardware_la_LIBADD += zeroplus-logic-cube/libsigrokhwzeroplus.la
-endif
-
index d1759914dea965c8cb7dd1f64cea79bc32bb6f5b..9bb85dd72f660bb528fbf679d3b38a18199ba20d 100644 (file)
 ## along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ##
 
-if LA_DEMO
+if HW_DEMO
 
 # Local lib, this is NOT meant to be installed!
-noinst_LTLIBRARIES = libsigrokhwdemo.la
+noinst_LTLIBRARIES = libsigrok4DSLogic_hw_demo.la
 
-libsigrokhwdemo_la_SOURCES = \
+libsigrok4DSLogic_hw_demo_la_SOURCES = \
        demo.c
 
-libsigrokhwdemo_la_CFLAGS = \
+libsigrok4DSLogic_hw_demo_la_CFLAGS = \
        -I$(top_srcdir)
 
 endif
index 98c95457ce49259b827e6607bc1f8b9d1c127502..67df85e4acd8a4e103efe0e47f208ddfbae1c4ab 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <math.h>
 #ifdef _WIN32
 #include <io.h>
 #include <fcntl.h>
 #define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
 
 /* TODO: Number of probes should be configurable. */
-#define NUM_PROBES             8
+#define NUM_PROBES             16
 
 #define DEMONAME               "Demo device"
 
 /* The size of chunks to send through the session bus. */
 /* TODO: Should be configurable. */
-#define BUFSIZE                4096
+#define BUFSIZE                1024*1024
 
-#define STR_PATTERN_SIGROK   "sigrok"
-#define STR_PATTERN_RANDOM   "random"
-#define STR_PATTERN_INC      "incremental"
-#define STR_PATTERN_ALL_LOW  "all-low"
-#define STR_PATTERN_ALL_HIGH "all-high"
+#define PERIOD                  4000
 
-/* Supported patterns which we can generate */
-enum {
-       /**
-        * Pattern which spells "sigrok" using '0's (with '1's as "background")
-        * when displayed using the 'bits' output format.
-        */
-       PATTERN_SIGROK,
-
-       /** Pattern which consists of (pseudo-)random values on all probes. */
-       PATTERN_RANDOM,
-
-       /**
-        * Pattern which consists of incrementing numbers.
-        * TODO: Better description.
-        */
-       PATTERN_INC,
+#define PI 3.14159265
 
-       /** Pattern where all probes have a low logic state. */
-       PATTERN_ALL_LOW,
+#define CONST_LEN               50
 
-       /** Pattern where all probes have a high logic state. */
-       PATTERN_ALL_HIGH,
+/* Supported patterns which we can generate */
+enum {
+    PATTERN_SINE = 0,
+    PATTERN_SQUARE = 1,
+    PATTERN_TRIANGLE = 2,
+    PATTERN_SAWTOOTH = 3,
+    PATTERN_RANDOM = 4,
+};
+static const char *pattern_strings[] = {
+    "Sine",
+    "Square",
+    "Triangle",
+    "Sawtooth",
+    "Random",
 };
 
 /* Private, per-device-instance driver context. */
@@ -91,6 +84,12 @@ struct dev_context {
        uint64_t samples_counter;
        void *cb_data;
        int64_t starttime;
+    int stop;
+
+    int trigger_stage;
+    uint16_t trigger_mask;
+    uint16_t trigger_value;
+    uint16_t trigger_edge;
 };
 
 static const int hwcaps[] = {
@@ -103,37 +102,38 @@ static const int hwcaps[] = {
        SR_CONF_CONTINUOUS,
 };
 
-static const uint64_t samplerates[] = {
-       SR_HZ(1),
-       SR_GHZ(1),
-       SR_HZ(1),
+static const int hwoptions[] = {
+    SR_CONF_PATTERN_MODE,
 };
 
-static const char *pattern_strings[] = {
-       "sigrok",
-       "random",
-       "incremental",
-       "all-low",
-       "all-high",
+static const uint64_t samplerates[] = {
+    SR_KHZ(10),
+    SR_KHZ(20),
+    SR_KHZ(50),
+    SR_KHZ(100),
+    SR_KHZ(200),
+    SR_KHZ(500),
+    SR_MHZ(1),
+    SR_MHZ(2),
+    SR_MHZ(5),
+    SR_MHZ(10),
+    SR_MHZ(20),
+    SR_MHZ(50),
+    SR_MHZ(100),
+    SR_MHZ(200),
 };
 
+
+
 /* We name the probes 0-7 on our demo driver. */
 static const char *probe_names[NUM_PROBES + 1] = {
-       "0", "1", "2", "3", "4", "5", "6", "7",
+    "Channel 0", "Channel 1", "Channel 2", "Channel 3",
+    "Channel 4", "Channel 5", "Channel 6", "Channel 7",
+    "Channel 8", "Channel 9", "Channel 10", "Channel 11",
+    "Channel 12", "Channel 13", "Channel 14", "Channel 15",
        NULL,
 };
 
-static uint8_t pattern_sigrok[] = {
-       0x4c, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00,
-       0x82, 0xfe, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00,
-       0x7c, 0x82, 0x82, 0x92, 0x74, 0x00, 0x00, 0x00,
-       0xfe, 0x12, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00,
-       0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00,
-       0xfe, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xbe, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
 /* Private, per-device-instance driver context. */
 /* TODO: struct context as with the other drivers. */
 
@@ -141,6 +141,8 @@ static uint8_t pattern_sigrok[] = {
 SR_PRIV struct sr_dev_driver demo_driver_info;
 static struct sr_dev_driver *di = &demo_driver_info;
 
+extern struct ds_trigger *trigger;
+
 static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
 
 static int clear_instances(void)
@@ -170,20 +172,13 @@ static GSList *hw_scan(GSList *options)
 
        devices = NULL;
 
-       sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
+    sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
        if (!sdi) {
-               sr_err("Device instance creation failed.");
+        sr_err("Device instance creation failed.");
                return NULL;
        }
        sdi->driver = di;
 
-       for (i = 0; probe_names[i]; i++) {
-               if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
-                               probe_names[i])))
-                       return NULL;
-               sdi->probes = g_slist_append(sdi->probes, probe);
-       }
-
        devices = g_slist_append(devices, sdi);
        drvc->instances = g_slist_append(drvc->instances, sdi);
 
@@ -193,13 +188,29 @@ static GSList *hw_scan(GSList *options)
        }
 
        devc->sdi = sdi;
-       devc->cur_samplerate = SR_KHZ(200);
+    devc->cur_samplerate = SR_MHZ(200);
        devc->limit_samples = 0;
        devc->limit_msec = 0;
-       devc->sample_generator = PATTERN_SIGROK;
+    devc->sample_generator = PATTERN_SINE;
 
        sdi->priv = devc;
 
+    if (sdi->mode == LOGIC) {
+        for (i = 0; probe_names[i]; i++) {
+            if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
+                    probe_names[i])))
+                return NULL;
+            sdi->probes = g_slist_append(sdi->probes, probe);
+        }
+    } else if (sdi->mode == ANALOG) {
+        for (i = 0; i < DS_MAX_ANALOG_PROBES_NUM; i++) {
+            if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
+                    probe_names[i])))
+                return NULL;
+            sdi->probes = g_slist_append(sdi->probes, probe);
+        }
+    }
+
        return devices;
 }
 
@@ -266,24 +277,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
        case SR_CONF_LIMIT_MSEC:
                *data = g_variant_new_uint64(devc->limit_msec);
                break;
-       case SR_CONF_PATTERN_MODE:
-               switch (devc->sample_generator) {
-               case PATTERN_SIGROK:
-                       *data = g_variant_new_string(STR_PATTERN_SIGROK);
-                       break;
-               case PATTERN_RANDOM:
-                       *data = g_variant_new_string(STR_PATTERN_RANDOM);
-                       break;
-               case PATTERN_INC:
-                       *data = g_variant_new_string(STR_PATTERN_INC);
-                       break;
-               case PATTERN_ALL_LOW:
-                       *data = g_variant_new_string(STR_PATTERN_ALL_LOW);
-                       break;
-               case PATTERN_ALL_HIGH:
-                       *data = g_variant_new_string(STR_PATTERN_ALL_HIGH);
-                       break;
-               }
+    case SR_CONF_DEVICE_MODE:
+        *data = g_variant_new_string(mode_strings[sdi->mode]);
+        break;
+    case SR_CONF_PATTERN_MODE:
+        *data = g_variant_new_string(pattern_strings[devc->sample_generator]);
                break;
        default:
                return SR_ERR_NA;
@@ -292,10 +290,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
        return SR_OK;
 }
 
-static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
+static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi)
 {
-       int ret;
+    int i, ret;
        const char *stropt;
+    struct sr_probe *probe;
 
        struct dev_context *const devc = sdi->priv;
 
@@ -318,27 +317,54 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
                devc->limit_samples = 0;
                sr_dbg("%s: setting limit_msec to %" PRIu64, __func__,
                       devc->limit_msec);
-               ret = SR_OK;
-       } else if (id == SR_CONF_PATTERN_MODE) {
+        ret = SR_OK;
+    } else if (id == SR_CONF_DEVICE_MODE) {
+        stropt = g_variant_get_string(data, NULL);
+        ret = SR_OK;
+        if (!strcmp(stropt, mode_strings[LOGIC])) {
+            sdi->mode = LOGIC;
+            sr_dev_probes_free(sdi);
+            for (i = 0; probe_names[i]; i++) {
+                if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE,
+                        probe_names[i])))
+                    ret = SR_ERR;
+                else
+                    sdi->probes = g_slist_append(sdi->probes, probe);
+            }
+        } else if (!strcmp(stropt, mode_strings[ANALOG])) {
+            sdi->mode = ANALOG;
+            sr_dev_probes_free(sdi);
+            for (i = 0; i < DS_MAX_ANALOG_PROBES_NUM; i++) {
+                if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
+                        probe_names[i])))
+                    ret = SR_ERR;
+                else
+                    sdi->probes = g_slist_append(sdi->probes, probe);
+            }
+        } else {
+            ret = SR_ERR;
+        }
+        sr_dbg("%s: setting mode to %d", __func__, sdi->mode);
+    }else if (id == SR_CONF_PATTERN_MODE) {
                stropt = g_variant_get_string(data, NULL);
-               ret = SR_OK;
-               if (!strcmp(stropt, STR_PATTERN_SIGROK)) {
-                       devc->sample_generator = PATTERN_SIGROK;
-               } else if (!strcmp(stropt, STR_PATTERN_RANDOM)) {
-                       devc->sample_generator = PATTERN_RANDOM;
-               } else if (!strcmp(stropt, STR_PATTERN_INC)) {
-                       devc->sample_generator = PATTERN_INC;
-               } else if (!strcmp(stropt, STR_PATTERN_ALL_LOW)) {
-                       devc->sample_generator = PATTERN_ALL_LOW;
-               } else if (!strcmp(stropt, STR_PATTERN_ALL_HIGH)) {
-                       devc->sample_generator = PATTERN_ALL_HIGH;
+        ret = SR_OK;
+        if (!strcmp(stropt, pattern_strings[PATTERN_SINE])) {
+            devc->sample_generator = PATTERN_SINE;
+        } else if (!strcmp(stropt, pattern_strings[PATTERN_SQUARE])) {
+            devc->sample_generator = PATTERN_SQUARE;
+        } else if (!strcmp(stropt, pattern_strings[PATTERN_TRIANGLE])) {
+            devc->sample_generator = PATTERN_TRIANGLE;
+        } else if (!strcmp(stropt, pattern_strings[PATTERN_SAWTOOTH])) {
+            devc->sample_generator = PATTERN_SAWTOOTH;
+        } else if (!strcmp(stropt, pattern_strings[PATTERN_RANDOM])) {
+            devc->sample_generator = PATTERN_RANDOM;
                } else {
-                       ret = SR_ERR;
+            ret = SR_ERR;
                }
-               sr_dbg("%s: setting pattern to %d",
+        sr_dbg("%s: setting pattern to %d",
                        __func__, devc->sample_generator);
        } else {
-               ret = SR_ERR_NA;
+        ret = SR_ERR_NA;
        }
 
        return ret;
@@ -352,108 +378,213 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
        (void)sdi;
 
        switch (key) {
-       case SR_CONF_DEVICE_OPTIONS:
-               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
-                               hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
+    case SR_CONF_DEVICE_OPTIONS:
+//             *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
+//                             hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
+               *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"),
+                hwcaps, ARRAY_SIZE(hwcaps)*sizeof(int32_t), TRUE, NULL, NULL);
                break;
-       case SR_CONF_SAMPLERATE:
+    case SR_CONF_DEVICE_CONFIGS:
+//             *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
+//                             hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
+        *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"),
+                hwoptions, ARRAY_SIZE(hwoptions)*sizeof(int32_t), TRUE, NULL, NULL);
+        break;
+    case SR_CONF_SAMPLERATE:
                g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}"));
-               gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
-                               ARRAY_SIZE(samplerates), sizeof(uint64_t));
-               g_variant_builder_add(&gvb, "{sv}", "samplerate-steps", gvar);
+//             gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates,
+//                             ARRAY_SIZE(samplerates), sizeof(uint64_t));
+               gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"),
+                               samplerates, ARRAY_SIZE(samplerates)*sizeof(uint64_t), TRUE, NULL, NULL);
+        g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar);
                *data = g_variant_builder_end(&gvb);
                break;
-       case SR_CONF_PATTERN_MODE:
+    case SR_CONF_DEVICE_MODE:
+        *data = g_variant_new_strv(mode_strings, ARRAY_SIZE(mode_strings));
+        break;
+    case SR_CONF_PATTERN_MODE:
                *data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings));
                break;
        default:
-               return SR_ERR_NA;
+        return SR_ERR_NA;
        }
 
-       return SR_OK;
+    return SR_OK;
 }
 
-static void samples_generator(uint8_t *buf, uint64_t size,
+static void samples_generator(uint16_t *buf, uint64_t size,
                              struct dev_context *devc)
 {
-       static uint64_t p = 0;
+    static uint16_t p = 0;
        uint64_t i;
-
-       /* TODO: Needed? */
-       memset(buf, 0, size);
+    uint16_t demo_data;
 
        switch (devc->sample_generator) {
-       case PATTERN_SIGROK: /* sigrok pattern */
-               for (i = 0; i < size; i++) {
-                       *(buf + i) = ~(pattern_sigrok[
-                               p++ % sizeof(pattern_sigrok)] >> 1);
-               }
+    case PATTERN_SINE: /* Sine */
+        for (i = 0; i < size; i++) {
+            if (i%CONST_LEN == 0) {
+                demo_data = 0x8000 * sin(2 * PI * p / 0xffff) + 0x8000;
+                p += CONST_LEN;
+            }
+            *(buf + i) = demo_data;
+        }
                break;
+    case PATTERN_SQUARE:
+        for (i = 0; i < size; i++) {
+            if (i%CONST_LEN == 0) {
+                demo_data = p > 0x7fff ? 0xf000 : 0x1000;
+                p += CONST_LEN;
+            }
+            *(buf + i) = demo_data;
+        }
+        break;
+    case PATTERN_TRIANGLE:
+        for (i = 0; i < size; i++) {
+            if (i%CONST_LEN == 0) {
+                demo_data = p > 0x7fff ? 0xffff * (2.0f * (0x10000 - p) / 0x10000) :
+                                         0xffff * (2.0f * p / 0x10000);
+                p += CONST_LEN;
+            }
+            *(buf + i) = demo_data;
+        }
+        break;
+    case PATTERN_SAWTOOTH:
+        for (i = 0; i < size; i++) {
+            if (i%CONST_LEN == 0) {
+                demo_data = p;
+                p += CONST_LEN;
+            }
+            *(buf + i) = demo_data;
+        }
+        break;
        case PATTERN_RANDOM: /* Random */
-               for (i = 0; i < size; i++)
-                       *(buf + i) = (uint8_t)(rand() & 0xff);
-               break;
-       case PATTERN_INC: /* Simple increment */
-               for (i = 0; i < size; i++)
-                       *(buf + i) = p++;
-               break;
-       case PATTERN_ALL_LOW: /* All probes are low */
-               memset(buf, 0x00, size);
-               break;
-       case PATTERN_ALL_HIGH: /* All probes are high */
-               memset(buf, 0xff, size);
+        for (i = 0; i < size; i++) {
+            if (i%CONST_LEN == 0)
+                demo_data = (uint16_t)(rand() * (0x10000 * 1.0f / RAND_MAX));
+            *(buf + i) = demo_data;
+        }
                break;
        default:
-               sr_err("Unknown pattern: %d.", devc->sample_generator);
+        sr_err("Unknown pattern: %d.", devc->sample_generator);
                break;
        }
 }
 
 /* Callback handling data */
-static int receive_data(int fd, int revents, void *cb_data)
+static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi)
 {
-       struct dev_context *devc = cb_data;
-       struct sr_datafeed_packet packet;
-       struct sr_datafeed_logic logic;
-       uint8_t buf[BUFSIZE];
+    struct dev_context *devc = sdi->priv;
+    struct sr_datafeed_packet packet;
+    struct sr_datafeed_logic logic;
+    struct sr_datafeed_analog analog;
+    //uint16_t buf[BUFSIZE];
+    uint16_t *buf;
        static uint64_t samples_to_send, expected_samplenum, sending_now;
        int64_t time, elapsed;
+    static uint16_t last_sample = 0;
+    uint16_t cur_sample;
+    int i;
 
        (void)fd;
        (void)revents;
 
+    if (!(buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) {
+        sr_err("buf for receive_data malloc failed.");
+        return FALSE;
+    }
+
        /* How many "virtual" samples should we have collected by now? */
        time = g_get_monotonic_time();
        elapsed = time - devc->starttime;
+    devc->starttime = time;
        expected_samplenum = elapsed * devc->cur_samplerate / 1000000;
        /* Of those, how many do we still have to send? */
-       samples_to_send = expected_samplenum - devc->samples_counter;
-
-       if (devc->limit_samples) {
-               samples_to_send = MIN(samples_to_send,
-                                devc->limit_samples - devc->samples_counter);
-       }
-
-       while (samples_to_send > 0) {
-               sending_now = MIN(samples_to_send, sizeof(buf));
-               samples_to_send -= sending_now;
+    //samples_to_send = (expected_samplenum - devc->samples_counter) / CONST_LEN * CONST_LEN;
+    samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN;
+
+    if (devc->limit_samples) {
+        if (sdi->mode == LOGIC)
+            samples_to_send = MIN(samples_to_send,
+                     devc->limit_samples - devc->samples_counter);
+        else if (sdi->mode == ANALOG)
+            samples_to_send = MIN(samples_to_send,
+                     devc->limit_samples);
+    }
+
+    while (samples_to_send > 0) {
+        sending_now = MIN(samples_to_send, BUFSIZE);
                samples_generator(buf, sending_now, devc);
 
-               packet.type = SR_DF_LOGIC;
-               packet.payload = &logic;
-               logic.length = sending_now;
-               logic.unitsize = 1;
-               logic.data = buf;
-               sr_session_send(devc->cb_data, &packet);
-               devc->samples_counter += sending_now;
+        if (devc->trigger_stage != 0) {
+            for (i = 0; i < sending_now; i++) {
+                if (devc->trigger_edge == 0) {
+                    if ((*(buf + i) | devc->trigger_mask) ==
+                            (devc->trigger_value | devc->trigger_mask)) {
+                        devc->trigger_stage = 0;
+                        break;
+                    }
+                } else {
+                    cur_sample = *(buf + i);
+                    if (((last_sample & devc->trigger_edge) ==
+                         (~devc->trigger_value & devc->trigger_edge)) &&
+                        ((cur_sample | devc->trigger_mask) ==
+                         (devc->trigger_value | devc->trigger_mask)) &&
+                        ((cur_sample & devc->trigger_edge) ==
+                         (devc->trigger_value & devc->trigger_edge))) {
+                        devc->trigger_stage = 0;
+                        break;
+                    }
+                    last_sample = cur_sample;
+                }
+            }
+            if (devc->trigger_stage == 0) {
+                struct ds_trigger_pos demo_trigger_pos;
+                demo_trigger_pos.real_pos = i;
+                packet.type = SR_DF_TRIGGER;
+                packet.payload = &demo_trigger_pos;
+                sr_session_send(sdi, &packet);
+            }
+        }
+
+        if (devc->trigger_stage == 0){
+            samples_to_send -= sending_now;
+            if (sdi->mode == LOGIC) {
+                packet.type = SR_DF_LOGIC;
+                packet.payload = &logic;
+                logic.length = sending_now * (NUM_PROBES >> 3);
+                logic.unitsize = (NUM_PROBES >> 3);
+                logic.data = buf;
+            } else if (sdi->mode == ANALOG) {
+                packet.type = SR_DF_ANALOG;
+                packet.payload = &analog;
+                analog.probes = sdi->probes;
+                analog.num_samples = sending_now;
+                analog.mq = SR_MQ_VOLTAGE;
+                analog.unit = SR_UNIT_VOLT;
+                analog.mqflags = SR_MQFLAG_AC;
+                analog.data = buf;
+            }
+
+            sr_session_send(sdi, &packet);
+            if (sdi->mode == LOGIC)
+                devc->samples_counter += sending_now;
+            else if (sdi->mode == ANALOG)
+                devc->samples_counter = (devc->samples_counter + sending_now) % devc->limit_samples;
+        } else {
+            break;
+        }
        }
 
-       if (devc->limit_samples &&
-               devc->samples_counter >= devc->limit_samples) {
-               sr_info("Requested number of samples reached.");
-               hw_dev_acquisition_stop(devc->sdi, cb_data);
-               return TRUE;
-       }
+    if (sdi->mode == LOGIC &&
+        devc->limit_samples &&
+        devc->samples_counter >= devc->limit_samples) {
+        sr_info("Requested number of samples reached.");
+        hw_dev_acquisition_stop(sdi, NULL);
+        g_free(buf);
+        return TRUE;
+    }
+
+    g_free(buf);
 
        return TRUE;
 }
@@ -463,11 +594,29 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
 {
        struct dev_context *const devc = sdi->priv;
 
-       if (sdi->status != SR_ST_ACTIVE)
-               return SR_ERR_DEV_CLOSED;
+    (void)cb_data;
+
+    if (sdi->status != SR_ST_ACTIVE)
+        return SR_ERR_DEV_CLOSED;
 
-       devc->cb_data = cb_data;
+    //devc->cb_data = cb_data;
        devc->samples_counter = 0;
+    devc->stop = FALSE;
+
+    /*
+     * trigger setting
+     */
+    if (!trigger->trigger_en || sdi->mode == ANALOG) {
+        devc->trigger_stage = 0;
+    } else {
+        devc->trigger_mask = ds_trigger_get_mask0(TriggerStages);
+        devc->trigger_value = ds_trigger_get_value0(TriggerStages);
+        devc->trigger_edge = ds_trigger_get_edge0(TriggerStages);
+        if (devc->trigger_edge != 0)
+            devc->trigger_stage = 2;
+        else
+            devc->trigger_stage = 1;
+    }
 
        /*
         * Setting two channels connected by a pipe is a remnant from when the
@@ -492,11 +641,12 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
        /* Make channels to unbuffered. */
        g_io_channel_set_buffered(devc->channel, FALSE);
 
-       sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
-                   40, receive_data, devc);
+    sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR,
+            100, receive_data, sdi);
 
        /* Send header packet to the session bus. */
-       std_session_send_df_header(cb_data, LOG_PREFIX);
+    //std_session_send_df_header(cb_data, LOG_PREFIX);
+    std_session_send_df_header(sdi, LOG_PREFIX);
 
        /* We use this timestamp to decide how many more samples to send. */
        devc->starttime = g_get_monotonic_time();
@@ -513,18 +663,27 @@ static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
 
        sr_dbg("Stopping aquisition.");
 
-       sr_session_source_remove_channel(devc->channel);
+    devc->stop = TRUE;
+    sr_session_source_remove_channel(devc->channel);
        g_io_channel_shutdown(devc->channel, FALSE, NULL);
        g_io_channel_unref(devc->channel);
        devc->channel = NULL;
 
        /* Send last packet. */
-       packet.type = SR_DF_END;
-       sr_session_send(devc->cb_data, &packet);
+    packet.type = SR_DF_END;
+    sr_session_send(sdi, &packet);
 
        return SR_OK;
 }
 
+static int hw_dev_test(struct sr_dev_inst *sdi)
+{
+    if (sdi)
+        return SR_OK;
+    else
+        return SR_ERR;
+}
+
 SR_PRIV struct sr_dev_driver demo_driver_info = {
        .name = "demo",
        .longname = "Demo driver and pattern generator",
@@ -539,6 +698,7 @@ SR_PRIV struct sr_dev_driver demo_driver_info = {
        .config_list = config_list,
        .dev_open = hw_dev_open,
        .dev_close = hw_dev_close,
+    .dev_test = hw_dev_test,
        .dev_acquisition_start = hw_dev_acquisition_start,
        .dev_acquisition_stop = hw_dev_acquisition_stop,
        .priv = NULL,
index d4ae56057204c23b8e86957dd14cddfe6c2eb2f3..d362f13b76c88083c704d855afc2110a394aa01b 100644 (file)
@@ -57,11 +57,15 @@ static struct sr_config_info sr_config_info_data[] = {
                "Serial communication", NULL},
        {SR_CONF_SAMPLERATE, SR_T_UINT64, "samplerate",
                "Sample rate", NULL},
-       {SR_CONF_CAPTURE_RATIO, SR_T_UINT64, "captureratio",
+    {SR_CONF_CLOCK_TYPE, SR_T_BOOL, "clocktype",
+        "Using External Clock", NULL},
+    {SR_CONF_CAPTURE_RATIO, SR_T_UINT64, "captureratio",
                "Pre-trigger capture ratio", NULL},
-       {SR_CONF_PATTERN_MODE, SR_T_CHAR, "pattern",
-               "Pattern generator mode", NULL},
-       {SR_CONF_TRIGGER_TYPE, SR_T_CHAR, "triggertype",
+    {SR_CONF_DEVICE_MODE, SR_T_CHAR, "device",
+        "Device Mode", NULL},
+    {SR_CONF_PATTERN_MODE, SR_T_CHAR, "pattern",
+        "Pattern mode", NULL},
+    {SR_CONF_TRIGGER_TYPE, SR_T_CHAR, "triggertype",
                "Trigger types", NULL},
        {SR_CONF_RLE, SR_T_BOOL, "rle",
                "Run Length Encoding", NULL},
@@ -87,180 +91,20 @@ static struct sr_config_info sr_config_info_data[] = {
 };
 
 /** @cond PRIVATE */
-#ifdef HAVE_HW_BRYMEN_DMM
-extern SR_PRIV struct sr_dev_driver brymen_bm857_driver_info;
-#endif
-#ifdef HAVE_HW_COLEAD_SLM
-extern SR_PRIV struct sr_dev_driver colead_slm_driver_info;
-#endif
 #ifdef HAVE_LA_DEMO
 extern SR_PRIV struct sr_dev_driver demo_driver_info;
 #endif
-#ifdef HAVE_HW_LASCAR_EL_USB
-extern SR_PRIV struct sr_dev_driver lascar_el_usb_driver_info;
-#endif
-#ifdef HAVE_HW_MIC_985XX
-extern SR_PRIV struct sr_dev_driver mic_98581_driver_info;
-extern SR_PRIV struct sr_dev_driver mic_98583_driver_info;
-#endif
-#ifdef HAVE_HW_NEXUS_OSCIPRIME
-extern SR_PRIV struct sr_dev_driver nexus_osciprime_driver_info;
-#endif
-#ifdef HAVE_LA_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;
-#endif
-#ifdef HAVE_HW_TONDAJ_SL_814
-extern SR_PRIV struct sr_dev_driver tondaj_sl_814_driver_info;
-#endif
-#ifdef HAVE_HW_VICTOR_DMM
-extern SR_PRIV struct sr_dev_driver victor_dmm_driver_info;
-#endif
-#ifdef HAVE_LA_ZEROPLUS_LOGIC_CUBE
-extern SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info;
-#endif
-#ifdef HAVE_LA_ASIX_SIGMA
-extern SR_PRIV struct sr_dev_driver asix_sigma_driver_info;
-#endif
-#ifdef HAVE_LA_CHRONOVU_LA8
-extern SR_PRIV struct sr_dev_driver chronovu_la8_driver_info;
-#endif
-#ifdef HAVE_LA_LINK_MSO19
-extern SR_PRIV struct sr_dev_driver link_mso19_driver_info;
-#endif
-#ifdef HAVE_HW_ALSA
-extern SR_PRIV struct sr_dev_driver alsa_driver_info;
-#endif
-#ifdef HAVE_LA_FX2LAFW
-extern SR_PRIV struct sr_dev_driver fx2lafw_driver_info;
-#endif
-#ifdef HAVE_HW_HANTEK_DSO
-extern SR_PRIV struct sr_dev_driver hantek_dso_driver_info;
-#endif
-#ifdef HAVE_HW_AGILENT_DMM
-extern SR_PRIV struct sr_dev_driver agdmm_driver_info;
-#endif
-#ifdef HAVE_HW_FLUKE_DMM
-extern SR_PRIV struct sr_dev_driver flukedmm_driver_info;
-#endif
-#ifdef HAVE_HW_SERIAL_DMM
-extern SR_PRIV struct sr_dev_driver digitek_dt4000zc_driver_info;
-extern SR_PRIV struct sr_dev_driver tekpower_tp4000zc_driver_info;
-extern SR_PRIV struct sr_dev_driver metex_me31_driver_info;
-extern SR_PRIV struct sr_dev_driver peaktech_3410_driver_info;
-extern SR_PRIV struct sr_dev_driver mastech_mas345_driver_info;
-extern SR_PRIV struct sr_dev_driver va_va18b_driver_info;
-extern SR_PRIV struct sr_dev_driver metex_m3640d_driver_info;
-extern SR_PRIV struct sr_dev_driver peaktech_4370_driver_info;
-extern SR_PRIV struct sr_dev_driver pce_pce_dm32_driver_info;
-extern SR_PRIV struct sr_dev_driver radioshack_22_168_driver_info;
-extern SR_PRIV struct sr_dev_driver radioshack_22_805_driver_info;
-extern SR_PRIV struct sr_dev_driver radioshack_22_812_driver_info;
-extern SR_PRIV struct sr_dev_driver tecpel_dmm_8060_ser_driver_info;
-extern SR_PRIV struct sr_dev_driver tecpel_dmm_8061_ser_driver_info;
-extern SR_PRIV struct sr_dev_driver voltcraft_vc820_ser_driver_info;
-extern SR_PRIV struct sr_dev_driver voltcraft_vc840_ser_driver_info;
-extern SR_PRIV struct sr_dev_driver uni_t_ut61d_ser_driver_info;
-extern SR_PRIV struct sr_dev_driver uni_t_ut61e_ser_driver_info;
-#endif
-#ifdef HAVE_HW_UNI_T_DMM
-extern SR_PRIV struct sr_dev_driver tecpel_dmm_8060_driver_info;
-extern SR_PRIV struct sr_dev_driver tecpel_dmm_8061_driver_info;
-extern SR_PRIV struct sr_dev_driver uni_t_ut61d_driver_info;
-extern SR_PRIV struct sr_dev_driver uni_t_ut61e_driver_info;
-extern SR_PRIV struct sr_dev_driver voltcraft_vc820_driver_info;
-extern SR_PRIV struct sr_dev_driver voltcraft_vc840_driver_info;
+#ifdef HAVE_LA_DSLOGIC
+extern SR_PRIV struct sr_dev_driver DSLogic_driver_info;
 #endif
 /** @endcond */
 
 static struct sr_dev_driver *drivers_list[] = {
-#ifdef HAVE_HW_BRYMEN_DMM
-       &brymen_bm857_driver_info,
-#endif
-#ifdef HAVE_HW_COLEAD_SLM
-       &colead_slm_driver_info,
-#endif
 #ifdef HAVE_LA_DEMO
        &demo_driver_info,
 #endif
-#ifdef HAVE_HW_LASCAR_EL_USB
-       &lascar_el_usb_driver_info,
-#endif
-#ifdef HAVE_HW_MIC_985XX
-       &mic_98581_driver_info,
-       &mic_98583_driver_info,
-#endif
-#ifdef HAVE_HW_NEXUS_OSCIPRIME
-       &nexus_osciprime_driver_info,
-#endif
-#ifdef HAVE_LA_OLS
-       &ols_driver_info,
-#endif
-#ifdef HAVE_HW_RIGOL_DS1XX2
-       &rigol_ds1xx2_driver_info,
-#endif
-#ifdef HAVE_HW_TONDAJ_SL_814
-       &tondaj_sl_814_driver_info,
-#endif
-#ifdef HAVE_HW_VICTOR_DMM
-       &victor_dmm_driver_info,
-#endif
-#ifdef HAVE_LA_ZEROPLUS_LOGIC_CUBE
-       &zeroplus_logic_cube_driver_info,
-#endif
-#ifdef HAVE_LA_ASIX_SIGMA
-       &asix_sigma_driver_info,
-#endif
-#ifdef HAVE_LA_CHRONOVU_LA8
-       &chronovu_la8_driver_info,
-#endif
-#ifdef HAVE_LA_LINK_MSO19
-       &link_mso19_driver_info,
-#endif
-#ifdef HAVE_HW_ALSA
-       &alsa_driver_info,
-#endif
-#ifdef HAVE_LA_FX2LAFW
-       &fx2lafw_driver_info,
-#endif
-#ifdef HAVE_HW_HANTEK_DSO
-       &hantek_dso_driver_info,
-#endif
-#ifdef HAVE_HW_AGILENT_DMM
-       &agdmm_driver_info,
-#endif
-#ifdef HAVE_HW_FLUKE_DMM
-       &flukedmm_driver_info,
-#endif
-#ifdef HAVE_HW_SERIAL_DMM
-       &digitek_dt4000zc_driver_info,
-       &tekpower_tp4000zc_driver_info,
-       &metex_me31_driver_info,
-       &peaktech_3410_driver_info,
-       &mastech_mas345_driver_info,
-       &va_va18b_driver_info,
-       &metex_m3640d_driver_info,
-       &peaktech_4370_driver_info,
-       &pce_pce_dm32_driver_info,
-       &radioshack_22_168_driver_info,
-       &radioshack_22_805_driver_info,
-       &radioshack_22_812_driver_info,
-       &tecpel_dmm_8060_ser_driver_info,
-       &tecpel_dmm_8061_ser_driver_info,
-       &voltcraft_vc820_ser_driver_info,
-       &voltcraft_vc840_ser_driver_info,
-       &uni_t_ut61d_ser_driver_info,
-       &uni_t_ut61e_ser_driver_info,
-#endif
-#ifdef HAVE_HW_UNI_T_DMM
-       &tecpel_dmm_8060_driver_info,
-       &tecpel_dmm_8061_driver_info,
-       &uni_t_ut61d_driver_info,
-       &uni_t_ut61e_driver_info,
-       &voltcraft_vc820_driver_info,
-       &voltcraft_vc840_driver_info,
+#ifdef HAVE_LA_DSLOGIC
+    &DSLogic_driver_info,
 #endif
        NULL,
 };
@@ -553,7 +397,7 @@ SR_PRIV int sr_source_remove(int fd)
 SR_PRIV int sr_source_add(int fd, int events, int timeout,
                          sr_receive_data_callback_t cb, void *cb_data)
 {
-       return sr_session_source_add(fd, events, timeout, cb, cb_data);
+    return sr_session_source_add(fd, events, timeout, cb, cb_data);
 }
 
 /** @} */
index e0fa66eda13b09d93a21ad7c3031c1cf77dfb99a..f878db356b252b67e8ca6178e2a6d76bdab290c7 100644 (file)
 ##
 
 # Local lib, this is NOT meant to be installed!
-noinst_LTLIBRARIES = libsigrokinput.la
+noinst_LTLIBRARIES = libsigrok4DSLogicinput.la
 
-libsigrokinput_la_SOURCES = \
-       binary.c \
-       chronovu_la8.c \
-       input.c \
-       vcd.c \
-       wav.c
+libsigrok4DSLogicinput_la_SOURCES = \
+        in_binary.c \
+        in_vcd.c \
+        in_wav.c \
+       input.c 
 
-libsigrokinput_la_CFLAGS = \
+libsigrok4DSLogicinput_la_CFLAGS = \
        -I$(top_srcdir)
 
diff --git a/input/in_binary.c b/input/in_binary.c
new file mode 100644 (file)
index 0000000..2d52c30
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "input/binary: "
+#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 CHUNKSIZE             (512 * 1024)
+#define DEFAULT_NUM_PROBES    8
+
+struct context {
+       uint64_t samplerate;
+};
+
+static int format_match(const char *filename)
+{
+       (void)filename;
+
+       /* This module will handle anything you throw at it. */
+       return TRUE;
+}
+
+static int init(struct sr_input *in, const char *filename)
+{
+       struct sr_probe *probe;
+       int num_probes, i;
+       char name[SR_MAX_PROBENAME_LEN + 1];
+       char *param;
+       struct context *ctx;
+
+       (void)filename;
+
+       if (!(ctx = g_try_malloc0(sizeof(*ctx)))) {
+               sr_err("Input format context malloc failed.");
+               return SR_ERR_MALLOC;
+       }
+
+       num_probes = DEFAULT_NUM_PROBES;
+       ctx->samplerate = 0;
+
+       if (in->param) {
+               param = g_hash_table_lookup(in->param, "numprobes");
+               if (param) {
+                       num_probes = strtoul(param, NULL, 10);
+                       if (num_probes < 1)
+                               return SR_ERR;
+               }
+
+               param = g_hash_table_lookup(in->param, "samplerate");
+               if (param) {
+                       if (sr_parse_sizestring(param, &ctx->samplerate) != SR_OK)
+                               return SR_ERR;
+               }
+       }
+
+       /* Create a virtual device. */
+       in->sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, NULL, NULL, NULL);
+       in->internal = ctx;
+
+       for (i = 0; i < num_probes; i++) {
+               snprintf(name, SR_MAX_PROBENAME_LEN, "%d", i);
+               /* TODO: Check return value. */
+               if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, name)))
+                       return SR_ERR;
+               in->sdi->probes = g_slist_append(in->sdi->probes, probe);
+       }
+
+       return SR_OK;
+}
+
+static int loadfile(struct sr_input *in, const char *filename)
+{
+       struct sr_datafeed_packet packet;
+       struct sr_datafeed_meta meta;
+       struct sr_datafeed_logic logic;
+       struct sr_config *src;
+       unsigned char buffer[CHUNKSIZE];
+       int fd, size, num_probes;
+       struct context *ctx;
+
+       ctx = in->internal;
+
+       if ((fd = open(filename, O_RDONLY)) == -1)
+               return SR_ERR;
+
+       num_probes = g_slist_length(in->sdi->probes);
+
+       /* Send header packet to the session bus. */
+       std_session_send_df_header(in->sdi, LOG_PREFIX);
+
+       if (ctx->samplerate) {
+               packet.type = SR_DF_META;
+               packet.payload = &meta;
+               src = sr_config_new(SR_CONF_SAMPLERATE,
+                               g_variant_new_uint64(ctx->samplerate));
+               meta.config = g_slist_append(NULL, src);
+               sr_session_send(in->sdi, &packet);
+               sr_config_free(src);
+       }
+
+       /* Chop up the input file into chunks & send it to the session bus. */
+       packet.type = SR_DF_LOGIC;
+       packet.payload = &logic;
+       logic.unitsize = (num_probes + 7) / 8;
+       logic.data = buffer;
+       while ((size = read(fd, buffer, CHUNKSIZE)) > 0) {
+               logic.length = size;
+               sr_session_send(in->sdi, &packet);
+       }
+       close(fd);
+
+       /* Send end packet to the session bus. */
+       packet.type = SR_DF_END;
+       sr_session_send(in->sdi, &packet);
+
+       g_free(ctx);
+       in->internal = NULL;
+
+       return SR_OK;
+}
+
+SR_PRIV struct sr_input_format input_binary = {
+       .id = "binary",
+       .description = "Raw binary",
+       .format_match = format_match,
+       .init = init,
+       .loadfile = loadfile,
+};
diff --git a/input/in_vcd.c b/input/in_vcd.c
new file mode 100644 (file)
index 0000000..a143b1c
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2012 Petteri Aimonen <jpa@sr.mail.kapsi.fi>
+ *
+ * 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/>.
+ */
+
+/* The VCD input module has the following options:
+ *
+ * numprobes:   Maximum number of probes to use. The probes are
+ *              detected in the same order as they are listed
+ *              in the $var sections of the VCD file.
+ *
+ * skip:        Allows skipping until given timestamp in the file.
+ *              This can speed up analyzing of long captures.
+ *            
+ *              Value < 0: Skip until first timestamp listed in
+ *              the file. (default)
+ *
+ *              Value = 0: Do not skip, instead generate samples
+ *              beginning from timestamp 0.
+ *
+ *              Value > 0: Start at the given timestamp.
+ *
+ * downsample:  Divide the samplerate by the given factor.
+ *              This can speed up analyzing of long captures.
+ *
+ * compress:    Compress idle periods longer than this value.
+ *              This can speed up analyzing of long captures.
+ *              Default 0 = don't compress.
+ *
+ * Based on Verilog standard IEEE Std 1364-2001 Version C
+ *
+ * Supported features:
+ * - $var with 'wire' and 'reg' types of scalar variables
+ * - $timescale definition for samplerate
+ * - multiple character variable identifiers
+ *
+ * Most important unsupported features:
+ * - vector variables (bit vectors etc.)
+ * - analog, integer and real number variables
+ * - $dumpvars initial value declaration
+ * - $scope namespaces
+ */
+
+/*  */
+
+#include <stdlib.h>
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "input/vcd: "
+#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 DEFAULT_NUM_PROBES 8
+
+/* Read until specific type of character occurs in file.
+ * Skip input if dest is NULL.
+ * Modes:
+ * 'W' read until whitespace
+ * 'N' read until non-whitespace, and ungetc() the character
+ * '$' read until $end
+ */
+static gboolean read_until(FILE *file, GString *dest, char mode)
+{
+       char prev[4] = "";
+       long startpos = ftell(file);
+       for(;;)
+       {
+               int c = fgetc(file);
+
+               if (c == EOF)
+               {
+                       if (mode == '$')
+                               sr_err("Unexpected EOF, read started at %ld.", startpos);
+                       return FALSE;
+               }
+               
+               if (mode == 'W' && g_ascii_isspace(c))
+                       return TRUE;
+               
+               if (mode == 'N' && !g_ascii_isspace(c))
+               {
+                       ungetc(c, file);
+                       return TRUE;
+               }
+               
+               if (mode == '$')
+               {
+                       prev[0] = prev[1]; prev[1] = prev[2]; prev[2] = prev[3]; prev[3] = c;
+                       if (prev[0] == '$' && prev[1] == 'e' && prev[2] == 'n' && prev[3] == 'd')
+                       {
+                               if (dest != NULL)
+                                       g_string_truncate(dest, dest->len - 3);
+                                       
+                               return TRUE;
+                       }
+               }
+
+               if (dest != NULL)
+                       g_string_append_c(dest, c);
+       }
+}
+
+/* Reads a single VCD section from input file and parses it to structure.
+ * e.g. $timescale 1ps $end  => "timescale" "1ps"
+ */
+static gboolean parse_section(FILE *file, gchar **name, gchar **contents)
+{
+       gboolean status;
+       GString *sname, *scontents;
+       
+       /* Skip any initial white-space */
+       if (!read_until(file, NULL, 'N')) return FALSE;
+       
+       /* Section tag should start with $. */
+       if (fgetc(file) != '$')
+       {
+               sr_err("Expected $ at beginning of section.");
+               return FALSE;
+       }
+       
+       /* Read the section tag */      
+       sname = g_string_sized_new(32);
+       status = read_until(file, sname, 'W');
+       
+       /* Skip whitespace before content */
+       status = status && read_until(file, NULL, 'N');
+       
+       /* Read the content */
+       scontents = g_string_sized_new(128);
+       status = status && read_until(file, scontents, '$');
+       g_strchomp(scontents->str);
+
+       /* Release strings if status is FALSE, return them if status is TRUE */ 
+       *name = g_string_free(sname, !status);
+       *contents = g_string_free(scontents, !status);
+       return status;
+}
+
+struct probe
+{
+       gchar *name;
+       gchar *identifier;
+};
+
+struct context
+{
+       uint64_t samplerate;
+       int maxprobes;
+       int probecount;
+       int downsample;
+       unsigned compress;
+       int64_t skip;
+       GSList *probes;
+};
+
+static void free_probe(void *data)
+{
+       struct probe *probe = data;
+       g_free(probe->name);
+       g_free(probe->identifier);
+       g_free(probe);
+}
+
+static void release_context(struct context *ctx)
+{
+       g_slist_free_full(ctx->probes, free_probe);
+       g_free(ctx);
+}
+
+/* Remove empty parts from an array returned by g_strsplit. */
+static void remove_empty_parts(gchar **parts)
+{
+       gchar **src = parts;
+       gchar **dest = parts;
+       while (*src != NULL)
+       {
+               if (**src != '\0')
+               {
+                       *dest++ = *src;
+               }
+               
+               src++;
+       }
+       
+       *dest = NULL;
+}
+
+/* Parse VCD header to get values for context structure.
+ * The context structure should be zeroed before calling this.
+ */
+static gboolean parse_header(FILE *file, struct context *ctx)
+{
+       uint64_t p, q;
+       gchar *name = NULL, *contents = NULL;
+       gboolean status = FALSE;
+       struct probe *probe;
+
+       while (parse_section(file, &name, &contents))
+       {
+               sr_dbg("Section '%s', contents '%s'.", name, contents);
+       
+               if (g_strcmp0(name, "enddefinitions") == 0)
+               {
+                       status = TRUE;
+                       break;
+               }
+               else if (g_strcmp0(name, "timescale") == 0)
+               {
+                       /* The standard allows for values 1, 10 or 100
+                        * and units s, ms, us, ns, ps and fs. */
+                       if (sr_parse_period(contents, &p, &q) == SR_OK)
+                       {
+                               ctx->samplerate = q / p;
+                               if (q % p != 0)
+                               {
+                                       /* Does not happen unless time value is non-standard */
+                                       sr_warn("Inexact rounding of samplerate, %" PRIu64 " / %" PRIu64 " to %" PRIu64 " Hz.",
+                                               q, p, ctx->samplerate);
+                               }
+                               
+                               sr_dbg("Samplerate: %" PRIu64, ctx->samplerate);
+                       }
+                       else
+                       {
+                               sr_err("Parsing timescale failed.");
+                       }
+               }
+               else if (g_strcmp0(name, "var") == 0)
+               {
+                       /* Format: $var type size identifier reference $end */
+                       gchar **parts = g_strsplit_set(contents, " \r\n\t", 0);
+                       remove_empty_parts(parts);
+                       
+                       if (g_strv_length(parts) != 4)
+                       {
+                               sr_warn("$var section should have 4 items");
+                       }
+                       else if (g_strcmp0(parts[0], "reg") != 0 && g_strcmp0(parts[0], "wire") != 0)
+                       {
+                               sr_info("Unsupported signal type: '%s'", parts[0]);
+                       }
+                       else if (strtol(parts[1], NULL, 10) != 1)
+                       {
+                               sr_info("Unsupported signal size: '%s'", parts[1]);
+                       }
+                       else if (ctx->probecount >= ctx->maxprobes)
+                       {
+                               sr_warn("Skipping '%s' because only %d probes requested.", parts[3], ctx->maxprobes);
+                       }
+                       else
+                       {
+                               sr_info("Probe %d is '%s' identified by '%s'.", ctx->probecount, parts[3], parts[2]);
+                               probe = g_malloc(sizeof(struct probe));
+                               probe->identifier = g_strdup(parts[2]);
+                               probe->name = g_strdup(parts[3]);
+                               ctx->probes = g_slist_append(ctx->probes, probe);
+                               ctx->probecount++;
+                       }
+                       
+                       g_strfreev(parts);
+               }
+               
+               g_free(name); name = NULL;
+               g_free(contents); contents = NULL;
+       }
+       
+       g_free(name);
+       g_free(contents);
+       
+       return status;
+}
+
+static int format_match(const char *filename)
+{
+       FILE *file;
+       gchar *name = NULL, *contents = NULL;
+       gboolean status;
+       
+       file = fopen(filename, "r");
+       if (file == NULL)
+               return FALSE;
+
+       /* If we can parse the first section correctly,
+        * then it is assumed to be a VCD file.
+        */
+       status = parse_section(file, &name, &contents);
+       status = status && (*name != '\0');
+       
+       g_free(name);
+       g_free(contents);
+       fclose(file);
+       
+       return status;
+}
+
+static int init(struct sr_input *in, const char *filename)
+{
+       struct sr_probe *probe;
+       int num_probes, i;
+       char name[SR_MAX_PROBENAME_LEN + 1];
+       char *param;
+       struct context *ctx;
+
+       (void)filename;
+
+       if (!(ctx = g_try_malloc0(sizeof(*ctx)))) {
+               sr_err("Input format context malloc failed.");
+               return SR_ERR_MALLOC;
+       }
+
+       num_probes = DEFAULT_NUM_PROBES;
+       ctx->samplerate = 0;
+       ctx->downsample = 1;
+       ctx->skip = -1;
+
+       if (in->param) {
+               param = g_hash_table_lookup(in->param, "numprobes");
+               if (param) {
+                       num_probes = strtoul(param, NULL, 10);
+                       if (num_probes < 1)
+                       {
+                               release_context(ctx);
+                               return SR_ERR;
+                       }
+               }
+               
+               param = g_hash_table_lookup(in->param, "downsample");
+               if (param) {
+                       ctx->downsample = strtoul(param, NULL, 10);
+                       if (ctx->downsample < 1)
+                       {
+                               ctx->downsample = 1;
+                       }
+               }
+               
+               param = g_hash_table_lookup(in->param, "compress");
+               if (param) {
+                       ctx->compress = strtoul(param, NULL, 10);
+               }
+               
+               param = g_hash_table_lookup(in->param, "skip");
+               if (param) {
+                       ctx->skip = strtoul(param, NULL, 10) / ctx->downsample;
+               }
+       }
+       
+       /* Maximum number of probes to parse from the VCD */
+       ctx->maxprobes = num_probes;
+
+       /* Create a virtual device. */
+       in->sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, NULL, NULL, NULL);
+       in->internal = ctx;
+
+       for (i = 0; i < num_probes; i++) {
+               snprintf(name, SR_MAX_PROBENAME_LEN, "%d", i);
+               
+               if (!(probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, name)))
+               {
+                       release_context(ctx);
+                       return SR_ERR;
+               }
+                       
+               in->sdi->probes = g_slist_append(in->sdi->probes, probe);
+       }
+
+       return SR_OK;
+}
+
+#define CHUNKSIZE 1024
+
+/* Send N samples of the given value. */
+static void send_samples(const struct sr_dev_inst *sdi, uint64_t sample, uint64_t count)
+{
+       struct sr_datafeed_packet packet;
+       struct sr_datafeed_logic logic;
+       uint64_t buffer[CHUNKSIZE];
+       uint64_t i;
+       unsigned chunksize = CHUNKSIZE;
+               
+       if (count < chunksize)
+               chunksize = count;
+
+       for (i = 0; i < chunksize; i++)
+       {
+               buffer[i] = sample;
+       }
+       
+       packet.type = SR_DF_LOGIC;
+       packet.payload = &logic;        
+       logic.unitsize = sizeof(uint64_t);
+       logic.data = buffer;
+       
+       while (count)
+       {
+               if (count < chunksize)
+                       chunksize = count;
+       
+               logic.length = sizeof(uint64_t) * chunksize;
+       
+               sr_session_send(sdi, &packet);
+               count -= chunksize;
+       }
+}
+
+/* Parse the data section of VCD */
+static void parse_contents(FILE *file, const struct sr_dev_inst *sdi, struct context *ctx)
+{
+       GString *token = g_string_sized_new(32);
+       
+       uint64_t prev_timestamp = 0;
+       uint64_t prev_values = 0;
+       
+       /* Read one space-delimited token at a time. */
+       while (read_until(file, NULL, 'N') && read_until(file, token, 'W'))
+       {
+               if (token->str[0] == '#' && g_ascii_isdigit(token->str[1]))
+               {
+                       /* Numeric value beginning with # is a new timestamp value */
+                       uint64_t timestamp;
+                       timestamp = strtoull(token->str + 1, NULL, 10);
+                       
+                       if (ctx->downsample > 1)
+                               timestamp /= ctx->downsample;
+                       
+                       /* Skip < 0 => skip until first timestamp.
+                        * Skip = 0 => don't skip
+                        * Skip > 0 => skip until timestamp >= skip.
+                        */
+                       if (ctx->skip < 0)
+                       {
+                               ctx->skip = timestamp;
+                               prev_timestamp = timestamp;
+                       }
+                       else if (ctx->skip > 0 && timestamp < (uint64_t)ctx->skip)
+                       {
+                               prev_timestamp = ctx->skip;
+                       }
+                       else if (timestamp == prev_timestamp)
+                       {
+                               /* Ignore repeated timestamps (e.g. sigrok outputs these) */
+                       }
+                       else
+                       {
+                               if (ctx->compress != 0 && timestamp - prev_timestamp > ctx->compress)
+                               {
+                                       /* Compress long idle periods */
+                                       prev_timestamp = timestamp - ctx->compress;
+                               }
+                       
+                               sr_dbg("New timestamp: %" PRIu64, timestamp);
+                       
+                               /* Generate samples from prev_timestamp up to timestamp - 1. */
+                               send_samples(sdi, prev_values, timestamp - prev_timestamp);
+                               prev_timestamp = timestamp;
+                       }
+               }
+               else if (token->str[0] == '$' && token->len > 1)
+               {
+                       /* This is probably a $dumpvars, $comment or similar.
+                        * $dump* contain useful data, but other tags will be skipped until $end. */
+                       if (g_strcmp0(token->str, "$dumpvars") == 0 ||
+                           g_strcmp0(token->str, "$dumpon") == 0 ||
+                           g_strcmp0(token->str, "$dumpoff") == 0 ||
+                           g_strcmp0(token->str, "$end") == 0)
+                       {
+                               /* Ignore, parse contents as normally. */
+                       }
+                       else
+                       {
+                               /* Skip until $end */
+                               read_until(file, NULL, '$');
+                       }
+               }
+               else if (strchr("bBrR", token->str[0]) != NULL)
+               {
+                       /* A vector value. Skip it and also the following identifier. */
+                       read_until(file, NULL, 'N');
+                       read_until(file, NULL, 'W');
+               }
+               else if (strchr("01xXzZ", token->str[0]) != NULL)
+               {
+                       /* A new 1-bit sample value */
+                       int i, bit;
+                       GSList *l;
+                       struct probe *probe;
+
+                       bit = (token->str[0] == '1');
+               
+                       g_string_erase(token, 0, 1);
+                       if (token->len == 0)
+                       {
+                               /* There was a space between value and identifier.
+                                * Read in the rest.
+                                */
+                               read_until(file, NULL, 'N');
+                               read_until(file, token, 'W');
+                       }
+                       
+                       for (i = 0, l = ctx->probes; i < ctx->probecount && l; i++, l = l->next)
+                       {
+                               probe = l->data;
+
+                               if (g_strcmp0(token->str, probe->identifier) == 0)
+                               {
+                                       sr_dbg("Probe %d new value %d.", i, bit);
+                               
+                                       /* Found our probe */
+                                       if (bit)
+                                               prev_values |= (1 << i);
+                                       else
+                                               prev_values &= ~(1 << i);
+                                       
+                                       break;
+                               }
+                       }
+                       
+                       if (i == ctx->probecount)
+                       {
+                               sr_dbg("Did not find probe for identifier '%s'.", token->str);
+                       }
+               }
+               else
+               {
+                       sr_warn("Skipping unknown token '%s'.", token->str);
+               }
+               
+               g_string_truncate(token, 0);
+       }
+       
+       g_string_free(token, TRUE);
+}
+
+static int loadfile(struct sr_input *in, const char *filename)
+{
+       struct sr_datafeed_packet packet;
+       struct sr_datafeed_meta meta;
+       struct sr_config *src;
+       FILE *file;
+       struct context *ctx;
+       uint64_t samplerate;
+
+       ctx = in->internal;
+
+       if ((file = fopen(filename, "r")) == NULL)
+               return SR_ERR;
+
+       if (!parse_header(file, ctx))
+       {
+               sr_err("VCD parsing failed");
+               fclose(file);
+               return SR_ERR;
+       }
+
+       /* Send header packet to the session bus. */
+       std_session_send_df_header(in->sdi, LOG_PREFIX);
+
+       /* Send metadata about the SR_DF_LOGIC packets to come. */
+       packet.type = SR_DF_META;
+       packet.payload = &meta;
+       samplerate = ctx->samplerate / ctx->downsample;
+       src = sr_config_new(SR_CONF_SAMPLERATE, g_variant_new_uint64(samplerate));
+       meta.config = g_slist_append(NULL, src);
+       sr_session_send(in->sdi, &packet);
+       sr_config_free(src);
+
+       /* Parse the contents of the VCD file */
+       parse_contents(file, in->sdi, ctx);
+       
+       /* Send end packet to the session bus. */
+       packet.type = SR_DF_END;
+       sr_session_send(in->sdi, &packet);
+
+       fclose(file);
+       release_context(ctx);
+       in->internal = NULL;
+
+       return SR_OK;
+}
+
+SR_PRIV struct sr_input_format input_vcd = {
+       .id = "vcd",
+       .description = "Value Change Dump",
+       .format_match = format_match,
+       .init = init,
+       .loadfile = loadfile,
+};
diff --git a/input/in_wav.c b/input/in_wav.c
new file mode 100644 (file)
index 0000000..773b6b8
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "input/wav: "
+#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 CHUNK_SIZE 4096
+
+struct context {
+       uint64_t samplerate;
+       int samplesize;
+       int num_channels;
+};
+
+static int get_wav_header(const char *filename, char *buf)
+{
+       struct stat st;
+       int fd, l;
+
+       l = strlen(filename);
+       if (l <= 4 || strcasecmp(filename + l - 4, ".wav"))
+               return SR_ERR;
+
+       if (stat(filename, &st) == -1)
+               return SR_ERR;
+       if (st.st_size <= 45)
+               /* Minimum size of header + 1 8-bit mono PCM sample. */
+               return SR_ERR;
+
+       if ((fd = open(filename, O_RDONLY)) == -1)
+               return SR_ERR;
+
+       l = read(fd, buf, 40);
+       close(fd);
+       if (l != 40)
+               return SR_ERR;
+
+       return SR_OK;
+}
+
+static int format_match(const char *filename)
+{
+       char buf[40];
+
+       if (get_wav_header(filename, buf) != SR_OK)
+               return FALSE;
+
+       if (strncmp(buf, "RIFF", 4))
+               return FALSE;
+       if (strncmp(buf + 8, "WAVE", 4))
+               return FALSE;
+       if (strncmp(buf + 12, "fmt ", 4))
+               return FALSE;
+       if (GUINT16_FROM_LE(*(uint16_t *)(buf + 20)) != 1)
+               /* Not PCM. */
+               return FALSE;
+       if (strncmp(buf + 36, "data", 4))
+               return FALSE;
+
+       return TRUE;
+}
+
+static int init(struct sr_input *in, const char *filename)
+{
+       struct sr_probe *probe;
+       struct context *ctx;
+       char buf[40], probename[8];
+       int i;
+
+       if (get_wav_header(filename, buf) != SR_OK)
+               return SR_ERR;
+
+       if (!(ctx = g_try_malloc0(sizeof(struct context))))
+               return SR_ERR_MALLOC;
+
+       /* Create a virtual device. */
+       in->sdi = sr_dev_inst_new(LOGIC, 0, SR_ST_ACTIVE, NULL, NULL, NULL);
+       in->sdi->priv = ctx;
+
+       ctx->samplerate = GUINT32_FROM_LE(*(uint32_t *)(buf + 24));
+       ctx->samplesize = GUINT16_FROM_LE(*(uint16_t *)(buf + 34)) / 8;
+       if (ctx->samplesize != 1 && ctx->samplesize != 2 && ctx->samplesize != 4) {
+               sr_err("only 8, 16 or 32 bits per sample supported.");
+               return SR_ERR;
+       }
+
+       if ((ctx->num_channels = GUINT16_FROM_LE(*(uint16_t *)(buf + 22))) > 20) {
+               sr_err("%d channels seems crazy.", ctx->num_channels);
+               return SR_ERR;
+       }
+
+       for (i = 0; i < ctx->num_channels; i++) {
+               snprintf(probename, 8, "CH%d", i + 1);
+               if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, probename)))
+                       return SR_ERR;
+               in->sdi->probes = g_slist_append(in->sdi->probes, probe);
+       }
+
+       return SR_OK;
+}
+
+static int loadfile(struct sr_input *in, const char *filename)
+{
+       struct sr_datafeed_packet packet;
+       struct sr_datafeed_meta meta;
+       struct sr_datafeed_analog analog;
+       struct sr_config *src;
+       struct context *ctx;
+       float fdata[CHUNK_SIZE];
+       uint64_t sample;
+       int num_samples, chunk_samples, s, c, fd, l;
+       char buf[CHUNK_SIZE];
+
+       ctx = in->sdi->priv;
+
+       /* Send header packet to the session bus. */
+       std_session_send_df_header(in->sdi, LOG_PREFIX);
+
+       packet.type = SR_DF_META;
+       packet.payload = &meta;
+       src = sr_config_new(SR_CONF_SAMPLERATE,
+                       g_variant_new_uint64(ctx->samplerate));
+       meta.config = g_slist_append(NULL, src);
+       sr_session_send(in->sdi, &packet);
+       sr_config_free(src);
+
+       if ((fd = open(filename, O_RDONLY)) == -1)
+               return SR_ERR;
+
+       lseek(fd, 40, SEEK_SET);
+       l = read(fd, buf, 4);
+       num_samples = GUINT32_FROM_LE((uint32_t)*(buf));
+       num_samples /= ctx->samplesize / ctx->num_channels;
+       while (TRUE) {
+               if ((l = read(fd, buf, CHUNK_SIZE)) < 1)
+                       break;
+               chunk_samples = l / ctx->samplesize / ctx->num_channels;
+               for (s = 0; s < chunk_samples; s++) {
+                       for (c = 0; c < ctx->num_channels; c++) {
+                               sample = 0;
+                               memcpy(&sample, buf + s * ctx->samplesize + c, ctx->samplesize);
+                               switch (ctx->samplesize) {
+                               case 1:
+                                       /* 8-bit PCM samples are unsigned. */
+                                       fdata[s + c] = (uint8_t)sample / 255.0;
+                                       break;
+                               case 2:
+                                       fdata[s + c] = GINT16_FROM_LE(sample) / 32767.0;
+                                       break;
+                               case 4:
+                                       fdata[s + c] = GINT32_FROM_LE(sample) / 65535.0;
+                                       break;
+                               }
+                       }
+               }
+               packet.type = SR_DF_ANALOG;
+               packet.payload = &analog;
+               analog.probes = in->sdi->probes;
+               analog.num_samples = chunk_samples;
+               analog.mq = 0;
+               analog.unit = 0;
+               analog.data = fdata;
+               sr_session_send(in->sdi, &packet);
+       }
+
+       close(fd);
+       packet.type = SR_DF_END;
+       sr_session_send(in->sdi, &packet);
+
+       return SR_OK;
+}
+
+
+SR_PRIV struct sr_input_format input_wav = {
+       .id = "wav",
+       .description = "WAV file",
+       .format_match = format_match,
+       .init = init,
+       .loadfile = loadfile,
+};
+
index fa0bf438195a933b8860b5e5560ce37aaf26ef94..68ae49e46a8ecf84cbc5915a46d0921e3495c5c8 100644 (file)
@@ -50,7 +50,7 @@
  */
 
 /** @cond PRIVATE */
-extern SR_PRIV struct sr_input_format input_chronovu_la8;
+
 extern SR_PRIV struct sr_input_format input_binary;
 extern SR_PRIV struct sr_input_format input_vcd;
 extern SR_PRIV struct sr_input_format input_wav;
@@ -58,7 +58,6 @@ extern SR_PRIV struct sr_input_format input_wav;
 
 static struct sr_input_format *input_module_list[] = {
        &input_vcd,
-       &input_chronovu_la8,
        &input_wav,
        /* This one has to be last, because it will take any input. */
        &input_binary,
index 57005cd2d04fa1b39bb622ca4bc32d5d33f42ee5..aa8086ea0d922e8d286eb4ea1a4b8110d98243e2 100644 (file)
@@ -84,11 +84,12 @@ SR_PRIV int sr_err(const char *format, ...);
 /*--- device.c --------------------------------------------------------------*/
 
 SR_PRIV struct sr_probe *sr_probe_new(int index, int type,
-               gboolean enabled, const char *name);
+                                      gboolean enabled, const char *name);
+SR_PRIV void sr_dev_probes_free(struct sr_dev_inst *sdi);
 
 /* Generic device instances */
-SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int index, int status,
-               const char *vendor, const char *model, const char *version);
+SR_PRIV struct sr_dev_inst *sr_dev_inst_new(int mode, int index, int status,
+                                            const char *vendor, const char *model, const char *version);
 SR_PRIV void sr_dev_inst_free(struct sr_dev_inst *sdi);
 
 #ifdef HAVE_LIBUSB_1_0
@@ -112,7 +113,7 @@ SR_PRIV struct sr_config *sr_config_new(int key, GVariant *data);
 SR_PRIV void sr_config_free(struct sr_config *src);
 SR_PRIV int sr_source_remove(int fd);
 SR_PRIV int sr_source_add(int fd, int events, int timeout,
-               sr_receive_data_callback_t cb, void *cb_data);
+        sr_receive_data_callback_t cb, void *cb_data);
 
 /*--- session.c -------------------------------------------------------------*/
 
@@ -135,6 +136,14 @@ SR_PRIV int std_session_send_df_header(const struct sr_dev_inst *sdi,
 SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver,
                std_dev_clear_t clear_private);
 
+/*--- trigger.c -------------------------------------------------*/
+SR_PRIV uint64_t sr_trigger_get_mask0(uint16_t stage);
+SR_PRIV uint64_t sr_trigger_get_mask1(uint16_t stage);
+SR_PRIV uint64_t sr_trigger_get_value0(uint16_t stage);
+SR_PRIV uint64_t sr_trigger_get_value1(uint16_t stage);
+SR_PRIV uint64_t sr_trigger_get_edge0(uint16_t stage);
+SR_PRIV uint64_t sr_trigger_get_edge1(uint16_t stage);
+
 /*--- hardware/common/serial.c ----------------------------------------------*/
 
 enum {
@@ -180,84 +189,6 @@ SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn);
 SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb);
 #endif
 
-/*--- hardware/common/dmm/es51922.c -----------------------------------------*/
-
-#define ES51922_PACKET_SIZE 14
-
-struct es51922_info {
-       gboolean is_judge, is_vbar, is_voltage, is_auto, is_micro, is_current;
-       gboolean is_milli, is_resistance, is_continuity, is_diode, is_lpf;
-       gboolean is_frequency, is_duty_cycle, is_capacitance, is_temperature;
-       gboolean is_celsius, is_fahrenheit, is_adp, is_sign, is_batt, is_ol;
-       gboolean is_max, is_min, is_rel, is_rmr, is_ul, is_pmax, is_pmin;
-       gboolean is_dc, is_ac, is_vahz, is_hold, is_nano, is_kilo, is_mega;
-};
-
-SR_PRIV gboolean sr_es51922_packet_valid(const uint8_t *buf);
-SR_PRIV int sr_es51922_parse(const uint8_t *buf, float *floatval,
-                            struct sr_datafeed_analog *analog, void *info);
-
-/*--- hardware/common/dmm/fs9922.c ------------------------------------------*/
-
-#define FS9922_PACKET_SIZE 14
-
-struct fs9922_info {
-       gboolean is_auto, is_dc, is_ac, is_rel, is_hold, is_bpn, is_z1, is_z2;
-       gboolean is_max, is_min, is_apo, is_bat, is_nano, is_z3, is_micro;
-       gboolean is_milli, is_kilo, is_mega, is_beep, is_diode, is_percent;
-       gboolean is_z4, is_volt, is_ampere, is_ohm, is_hfe, is_hertz, is_farad;
-       gboolean is_celsius, is_fahrenheit;
-       int bargraph_sign, bargraph_value;
-};
-
-SR_PRIV gboolean sr_fs9922_packet_valid(const uint8_t *buf);
-SR_PRIV int sr_fs9922_parse(const uint8_t *buf, float *floatval,
-                           struct sr_datafeed_analog *analog, void *info);
-
-/*--- hardware/common/dmm/fs9721.c ------------------------------------------*/
-
-#define FS9721_PACKET_SIZE 14
-
-struct fs9721_info {
-       gboolean is_ac, is_dc, is_auto, is_rs232, is_micro, is_nano, is_kilo;
-       gboolean is_diode, is_milli, is_percent, is_mega, is_beep, is_farad;
-       gboolean is_ohm, is_rel, is_hold, is_ampere, is_volt, is_hz, is_bat;
-       gboolean is_c2c1_11, is_c2c1_10, is_c2c1_01, is_c2c1_00, is_sign;
-};
-
-SR_PRIV gboolean sr_fs9721_packet_valid(const uint8_t *buf);
-SR_PRIV int sr_fs9721_parse(const uint8_t *buf, float *floatval,
-                           struct sr_datafeed_analog *analog, void *info);
-SR_PRIV void sr_fs9721_00_temp_c(struct sr_datafeed_analog *analog, void *info);
-SR_PRIV void sr_fs9721_01_temp_c(struct sr_datafeed_analog *analog, void *info);
-SR_PRIV void sr_fs9721_10_temp_c(struct sr_datafeed_analog *analog, void *info);
-SR_PRIV void sr_fs9721_01_10_temp_f_c(struct sr_datafeed_analog *analog, void *info);
-
-/*--- hardware/common/dmm/metex14.c -----------------------------------------*/
-
-#define METEX14_PACKET_SIZE 14
-
-struct metex14_info {
-       gboolean is_ac, is_dc, is_resistance, is_capacity, is_temperature;
-       gboolean is_diode, is_frequency, is_ampere, is_volt, is_farad;
-       gboolean is_hertz, is_ohm, is_celsius, is_nano, is_micro, is_milli;
-       gboolean is_kilo, is_mega, is_gain, is_decibel, is_hfe, is_unitless;
-};
-
-SR_PRIV int sr_metex14_packet_request(struct sr_serial_dev_inst *serial);
-SR_PRIV gboolean sr_metex14_packet_valid(const uint8_t *buf);
-SR_PRIV int sr_metex14_parse(const uint8_t *buf, float *floatval,
-                            struct sr_datafeed_analog *analog, void *info);
-
-/*--- hardware/common/dmm/rs9lcd.c ------------------------------------------*/
-
-#define RS9LCD_PACKET_SIZE 9
-
-/* Dummy info struct. The parser does not use it. */
-struct rs9lcd_info { int dummy; };
 
-SR_PRIV gboolean sr_rs9lcd_packet_valid(const uint8_t *buf);
-SR_PRIV int sr_rs9lcd_parse(const uint8_t *buf, float *floatval,
-                           struct sr_datafeed_analog *analog, void *info);
 
 #endif
index 6cda5543223d17cfceb225c0dce40ded25899feb..523aabcb6f329451a5bd1ad5377cc4d6526a7e1e 100644 (file)
 #include <inttypes.h>
 #include <glib.h>
 
+#ifdef WIN32
+#define WINVER 0x0500
+#define _WIN32_WINNT WINVER
+#include <Winsock2.h>
+#else
+#include <sys/time.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -80,6 +88,10 @@ enum {
 };
 
 #define SR_MAX_PROBENAME_LEN 32
+#define DS_MAX_ANALOG_PROBES_NUM 8
+#define TriggerStages 16
+#define TriggerProbes 16
+#define TriggerCountBits 16
 
 /* Handy little macros */
 #define SR_HZ(n)  (n)
@@ -129,7 +141,7 @@ enum {
 #define SR_PRIV
 #endif
 
-typedef int (*sr_receive_data_callback_t)(int fd, int revents, void *cb_data);
+typedef int (*sr_receive_data_callback_t)(int fd, int revents, const struct sr_dev_inst *sdi);
 
 /** Data types used by sr_config_info(). */
 enum {
@@ -280,9 +292,14 @@ struct sr_datafeed_meta {
 struct sr_datafeed_logic {
        uint64_t length;
        uint16_t unitsize;
+    uint16_t data_error;
        void *data;
 };
 
+struct sr_datafeed_trigger {
+
+};
+
 struct sr_datafeed_analog {
        /** The probes for which data is included in this packet. */
        GSList *probes;
@@ -533,6 +550,16 @@ enum {
        SR_PROBE_ANALOG,
 };
 
+enum {
+    LOGIC = 0,
+    ANALOG = 1,
+};
+
+static const char *mode_strings[] = {
+    "Logic Analyzer",
+    "Oscilloscope",
+};
+
 struct sr_probe {
        /* The index field will go: use g_slist_length(sdi->probes) instead. */
        int index;
@@ -622,6 +649,9 @@ enum {
        /** The device supports setting a pre/post-trigger capture ratio. */
        SR_CONF_CAPTURE_RATIO,
 
+    /** */
+    SR_CONF_DEVICE_MODE,
+
        /** The device supports setting a pattern (pattern generator mode). */
        SR_CONF_PATTERN_MODE,
 
@@ -664,6 +694,9 @@ enum {
        /** Number of vertical divisions, as related to SR_CONF_VDIV.  */
        SR_CONF_NUM_VDIV,
 
+    /** clock type (internal/external) */
+    SR_CONF_CLOCK_TYPE,
+
        /*--- Special stuff -------------------------------------------------*/
 
        /** Scan options supported by the driver. */
@@ -671,6 +704,7 @@ enum {
 
        /** Device options for a particular device. */
        SR_CONF_DEVICE_OPTIONS,
+    SR_CONF_DEVICE_CONFIGS,
 
        /** Session filename. */
        SR_CONF_SESSIONFILE,
@@ -721,6 +755,7 @@ struct sr_dev_inst {
        int index;
        int status;
        int inst_type;
+    int mode;
        char *vendor;
        char *model;
        char *version;
@@ -771,6 +806,7 @@ struct sr_dev_driver {
        /* Device-specific */
        int (*dev_open) (struct sr_dev_inst *sdi);
        int (*dev_close) (struct sr_dev_inst *sdi);
+    int (*dev_test) (struct sr_dev_inst *sdi);
        int (*dev_acquisition_start) (const struct sr_dev_inst *sdi,
                        void *cb_data);
        int (*dev_acquisition_stop) (struct sr_dev_inst *sdi,
@@ -804,10 +840,70 @@ struct sr_session {
         * an async fashion. We need to make sure the session is stopped from
         * within the session thread itself.
         */
-       GMutex stop_mutex;
+//     GMutex stop_mutex;
        gboolean abort_session;
 };
 
+enum {
+    SIMPLE_TRIGGER = 0,
+    ADV_TRIGGER,
+};
+
+struct ds_trigger {
+    uint16_t trigger_en;
+    uint16_t trigger_mode;
+    uint16_t trigger_pos;
+    uint16_t trigger_stages;
+    unsigned char trigger_logic[TriggerStages+1];
+    unsigned char trigger0_inv[TriggerStages+1];
+    unsigned char trigger1_inv[TriggerStages+1];
+    char trigger0[TriggerStages+1][TriggerProbes];
+    char trigger1[TriggerStages+1][TriggerProbes];
+    uint16_t trigger0_count[TriggerStages+1];
+    uint16_t trigger1_count[TriggerStages+1];
+};
+
+struct ds_trigger_pos {
+    uint32_t real_pos;
+    uint32_t ram_saddr;
+    unsigned char first_block[504];
+};
+
+//struct libusbhp_t;
+typedef void (*libusbhp_hotplug_cb_fn)(struct libusbhp_device_t *device,
+                                     void *user_data);
+#ifdef __linux__
+#include <libudev.h>
+
+struct dev_list_t {
+  char *path;
+  unsigned short vid;
+  unsigned short pid;
+  struct dev_list_t *next;
+};
+#endif/*__linux__*/
+
+struct libusbhp_t {
+#ifdef __linux__
+  struct udev* hotplug;
+  struct udev_monitor* hotplug_monitor;
+  struct dev_list_t *devlist;
+#endif/*__linux__*/
+#ifdef _WIN32
+  HWND hwnd;
+  HDEVNOTIFY hDeviceNotify;
+  WNDCLASSEX wcex;
+#endif/*_WIN32*/
+  libusbhp_hotplug_cb_fn attach;
+  libusbhp_hotplug_cb_fn detach;
+  void *user_data;
+};
+
+struct libusbhp_device_t {
+    unsigned short idVendor;
+    unsigned short idProduct;
+};
+
 #include "proto.h"
 #include "version.h"
 
diff --git a/libsigrok4DSLogic.pc.in b/libsigrok4DSLogic.pc.in
new file mode 100644 (file)
index 0000000..92a2361
--- /dev/null
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libsigrok4DSLogic
+Description: Backend library of DSLogic software based on libsigrok
+URL: http://www.dreamsourcelab.com
+Requires: glib-2.0
+Requires.private: @SR_PKGLIBS@
+Version: @VERSION@
+Libs: -L${libdir} -lsigrok4DSLogic
+Libs.private: -lm
+Cflags: -I${includedir}
+
diff --git a/libusbhp.c b/libusbhp.c
new file mode 100644 (file)
index 0000000..c93f079
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * This file is part of the DSLogic project.
+ */
+
+#include "libsigrok.h"
+#include "hardware/DSLogic/dslogic.h"
+
+#ifdef __linux__
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#endif/*__linux__*/
+
+#ifdef _WIN32
+#include <windows.h>
+
+#include <initguid.h>
+#include <ddk/usbiodef.h>
+#include <Setupapi.h>
+
+#include <tchar.h>
+#include <conio.h>
+#include <dbt.h>
+#include <stdio.h>
+#include <winuser.h>
+
+#endif/*_WIN32*/
+
+
+
+#ifdef __linux__
+static void dev_list_add(struct libusbhp_t *h, const char *path,
+                         unsigned short vid, unsigned short pid)
+{
+  struct dev_list_t *dev =
+    (struct dev_list_t*)malloc(sizeof(struct dev_list_t));
+  dev->path = strdup(path);
+  dev->vid = vid;
+  dev->pid = pid;
+  dev->next = NULL;
+
+  struct dev_list_t *p = h->devlist;
+  if(!p) {
+    h->devlist = dev;
+    return;
+  }
+
+  while(p->next) {
+    p = p->next;
+  }
+
+  p->next = dev;
+}
+
+static int dev_list_remove(struct libusbhp_t *h, const char *path)
+{
+  struct dev_list_t *p = h->devlist;
+  if(!p) return 1;
+
+  if(!strcmp(p->path, path)) {
+    h->devlist = p->next;
+    free(p->path);
+    free(p);
+    return 0;
+  }
+
+  while(p->next) {
+    if(!strcmp(p->next->path, path)) {
+      struct dev_list_t *pp = p->next;
+      p->next = pp->next;
+      free(pp->path);
+      free(pp->next);
+      free(pp);
+      return 0;
+    }
+    p = p->next;
+  }
+
+  // Not found
+  return 1;
+}
+
+static int dev_list_find(struct libusbhp_t *h, const char *path,
+                         unsigned short *vid, unsigned short *pid)
+{
+  struct dev_list_t *p = h->devlist;
+  while(p) {
+    if(!strcmp(p->path, path)) {
+      *vid = p->vid;
+      *pid = p->pid;
+      return 0;
+    }
+    p = p->next;
+  }
+
+  // Not found
+  return 1;
+}
+#endif/*__linux__*/
+
+#ifdef _WIN32
+SR_PRIV LRESULT CALLBACK WinProcCallback(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+  struct libusbhp_t *h = (struct libusbhp_t*)GetWindowLong(hwnd, GWL_USERDATA);
+
+  switch(msg) {
+  case WM_DEVICECHANGE:
+    {
+      PDEV_BROADCAST_HDR phdr = (PDEV_BROADCAST_HDR)lp;
+
+      if(!phdr || phdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE) break;
+
+      PDEV_BROADCAST_DEVICEINTERFACE devif =
+        (PDEV_BROADCAST_DEVICEINTERFACE)lp;
+
+      HDEVINFO devinfolist = SetupDiCreateDeviceInfoList(NULL, NULL);
+      
+      SP_DEVICE_INTERFACE_DATA devifdata;
+      memset(&devifdata, 0, sizeof(devifdata));
+      devifdata.cbSize = sizeof(devifdata);
+      BOOL b = SetupDiOpenDeviceInterface(devinfolist, devif->dbcc_name, 0,
+                                          &devifdata);
+      
+      DWORD required;
+      SP_DEVICE_INTERFACE_DETAIL_DATA devdetaildata;
+      memset(&devdetaildata, 0, sizeof(devdetaildata));
+      devdetaildata.cbSize = sizeof(devdetaildata);
+
+      SP_DEVINFO_DATA devinfodata;
+      memset(&devinfodata, 0, sizeof(devinfodata));
+      devinfodata.cbSize = sizeof(devinfodata);
+      b = SetupDiGetDeviceInterfaceDetail(devinfolist, &devifdata,
+                                          &devdetaildata,
+                                          sizeof(devdetaildata),
+                                          &required, &devinfodata);
+     
+      TCHAR deviceidw[1024];
+      b = SetupDiGetDeviceInstanceIdW(devinfolist, &devinfodata, deviceidw,
+                                      sizeof(deviceidw), NULL);
+
+      char deviceid[1024];
+      //size_t sz;
+      //wcstombs_s(&sz, deviceid, deviceidw, sizeof(deviceid) - 1);
+      wcstombs(deviceid, deviceidw, sizeof(deviceid) - 1);
+
+      char *vid = strstr(deviceid, "VID_");
+      if(vid != NULL) vid += 4;
+
+      char *pid = strstr(deviceid, "PID_");
+      if(pid != NULL)  pid += 4;
+
+      struct libusbhp_device_t *device = NULL;
+
+      if(pid || vid) {
+        device =
+          (struct libusbhp_device_t*)malloc(sizeof(struct libusbhp_device_t));
+      }
+
+      if(pid) {
+        pid[4] = '\0';
+        device->idProduct = (unsigned short)strtol(pid, NULL, 16); 
+      }
+
+      if(vid) {
+        vid[4] = '\0';
+        device->idVendor = (unsigned short)strtol(vid, NULL, 16);
+      }
+
+      if ((device->idVendor == supported_fx2[0].vid) &&
+          (device->idProduct == supported_fx2[0].pid)) {
+          switch(wp) {
+          case DBT_DEVICEARRIVAL:
+            if(h->attach) h->attach(device, h->user_data);
+            break;
+          case DBT_DEVICEREMOVECOMPLETE:
+            if(h->detach) h->detach(device, h->user_data);
+            break;
+          case DBT_DEVNODES_CHANGED:
+          default:
+            break;
+          }
+      }
+
+      if(device) free(device);
+    }
+    break;
+  default:
+    break;
+  }
+  
+  return DefWindowProc(hwnd, msg, wp, lp);
+}
+#endif/*OS_WINDOWS*/
+
+SR_API int libusbhp_init(struct libusbhp_t **handle)
+{
+  struct libusbhp_t *h = (struct libusbhp_t *)malloc(sizeof(struct libusbhp_t));
+
+  h->attach = NULL;
+  h->detach = NULL;
+  h->user_data = NULL;
+
+#ifdef __linux__
+  h->devlist = NULL;
+
+  // create the udev object
+  h->hotplug = udev_new();
+  if(!h->hotplug)
+  {
+    printf("Cannot create udev object\n");
+    free(h);
+    return 1;
+  }
+
+  // create the udev monitor
+  h->hotplug_monitor = udev_monitor_new_from_netlink(h->hotplug, "udev");
+
+  // start receiving hotplug events
+  udev_monitor_filter_add_match_subsystem_devtype(h->hotplug_monitor,
+                                                  "usb", "usb_device");
+  udev_monitor_enable_receiving(h->hotplug_monitor);
+
+  struct udev_enumerate *de = udev_enumerate_new (h->hotplug);
+  udev_enumerate_add_match_subsystem(de, "usb");
+  udev_enumerate_scan_devices(de);
+
+  struct udev_list_entry *lst = udev_enumerate_get_list_entry(de);
+  while(lst) {
+    struct udev_device *dev =
+      udev_device_new_from_syspath(h->hotplug,
+                                   udev_list_entry_get_name(lst));
+
+    if(udev_device_get_devnode(dev)) {
+      unsigned short idVendor =
+        strtol(udev_device_get_sysattr_value(dev, "idVendor"), NULL, 16); 
+      unsigned short idProduct =
+        strtol(udev_device_get_sysattr_value(dev, "idProduct"), NULL, 16); 
+
+      dev_list_add(h, udev_device_get_devnode(dev), idVendor, idProduct);
+    }
+
+    udev_device_unref(dev);
+
+    lst = udev_list_entry_get_next(lst);
+  }
+
+  udev_enumerate_unref(de);
+
+#endif/*__linux__*/
+
+#ifdef _WIN32
+  memset(&h->wcex, 0, sizeof(h->wcex));
+  h->wcex.cbSize = sizeof(WNDCLASSEX);
+  h->wcex.lpfnWndProc = WinProcCallback;
+  h->wcex.hInstance = GetModuleHandle(NULL);  
+  h->wcex.lpszClassName = TEXT("UsbHotplugClass");
+  h->wcex.cbWndExtra = sizeof(struct libusbhp_t*); // Size of data.
+
+  RegisterClassEx(&h->wcex);
+
+  h->hwnd =
+    CreateWindowEx(0, h->wcex.lpszClassName, TEXT("UsbHotplug"), 0, 0, 0, 0,
+                   0, 0, NULL, GetModuleHandle(NULL), NULL);
+
+  SetWindowLong(h->hwnd, GWL_USERDATA, (LONG)h);
+
+
+  DEV_BROADCAST_DEVICEINTERFACE *filter =
+  (DEV_BROADCAST_DEVICEINTERFACE*)malloc(sizeof(DEV_BROADCAST_DEVICEINTERFACE));
+
+  memset(filter, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
+  filter->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
+  filter->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+  filter->dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
+
+  h->hDeviceNotify =
+    RegisterDeviceNotification(h->hwnd, filter, DEVICE_NOTIFY_WINDOW_HANDLE);
+  
+  if(h->hDeviceNotify == 0) {
+    //printf("RegisterDeviceNotification error\n");
+    free(h);
+    return 1;
+  }
+#endif/*_WIN32*/
+
+  *handle = h;
+  return 0;
+}
+
+SR_API void libusbhp_exit(struct libusbhp_t *h)
+{
+#ifdef __linux__
+  // destroy the udev monitor
+  udev_monitor_unref(h->hotplug_monitor);
+
+  // destroy the udev object
+  udev_unref(h->hotplug);
+#endif/*__linux__*/
+
+#ifdef _WIN32
+  UnregisterDeviceNotification(h->hDeviceNotify);
+  DestroyWindow(h->hwnd);
+  UnregisterClass(h->wcex.lpszClassName, h->wcex.hInstance);
+#endif/*_WIN32*/
+
+  free(h);
+}
+
+SR_API int libusbhp_handle_events_timeout(struct libusbhp_t *h, struct timeval *tv)
+{
+  int ms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+
+#ifdef __linux__
+  // create the poll item
+  struct pollfd items[1];
+  items[0].fd = udev_monitor_get_fd(h->hotplug_monitor);
+  items[0].events = POLLIN;
+  items[0].revents = 0;
+
+  // while there are hotplug events to process
+  while(poll(items, 1, ms) > 0) {    
+    // receive the relevant device
+    struct udev_device* dev = udev_monitor_receive_device(h->hotplug_monitor);
+    if(!dev) {
+      // error receiving device, skip it
+      continue;
+    }
+
+    if(!strcmp(udev_device_get_action(dev), "add")) {
+      struct libusbhp_device_t device;
+
+      device.idVendor =
+        strtol(udev_device_get_sysattr_value(dev, "idVendor"), NULL, 16); 
+      device.idProduct =
+        strtol(udev_device_get_sysattr_value(dev, "idProduct"), NULL, 16); 
+
+      dev_list_add(h, udev_device_get_devnode(dev),
+                   device.idVendor, device.idProduct);
+
+      if(h->attach) h->attach(&device, h->user_data);
+    }
+
+    if(!strcmp(udev_device_get_action(dev), "remove")) {
+      struct libusbhp_device_t device;
+
+      int res = dev_list_find(h, udev_device_get_devnode(dev),
+                              &device.idVendor, &device.idProduct);
+
+      if(res) {
+        if(h->detach) h->detach(NULL, h->user_data);
+      } else {
+       dev_list_remove(h, udev_device_get_devnode(dev));
+        if(h->detach) h->detach(&device, h->user_data);
+      }
+    }
+
+    // destroy the relevant device
+    udev_device_unref(dev);
+
+    // clear the revents
+    items[0].revents = 0;
+  }
+#endif/*__linux__*/
+
+#ifdef _WIN32
+  UINT_PTR timer = SetTimer(h->hwnd, 0, ms, NULL);
+
+  MSG msg; 
+  int ret = GetMessage(&msg, NULL, 0, 0);
+
+  if(ret <= 0) return 0;
+  
+  TranslateMessage(&msg);
+  DispatchMessage(&msg);
+
+  KillTimer(h->hwnd, timer);
+#endif/*_WIN32*/
+
+  return 0;
+}
+
+SR_API void libusbhp_register_hotplug_listeners(struct libusbhp_t *handle,
+                                         libusbhp_hotplug_cb_fn connected_cb,
+                                         libusbhp_hotplug_cb_fn disconnected_cb,
+                                         void *user_data)
+{
+  handle->attach = connected_cb;
+  handle->detach = disconnected_cb;
+  handle->user_data = user_data;
+}
index 62f9842c2987034e22a90cb90b6062c23a09c78f..2bbe59c8c493ae75204a51c595e5aa3e7a37d846 100644 (file)
 SUBDIRS = text
 
 # Local lib, this is NOT meant to be installed!
-noinst_LTLIBRARIES = libsigrokoutput.la
+noinst_LTLIBRARIES = libsigrok4DSLogicoutput.la
 
-libsigrokoutput_la_SOURCES = \
-       binary.c \
-       vcd.c \
-       ols.c \
-       gnuplot.c \
-       chronovu_la8.c \
-       csv.c \
-       analog.c \
+libsigrok4DSLogicoutput_la_SOURCES = \
+        out_binary.c \
+        out_vcd.c \
+        out_csv.c \
+        out_analog.c \
        output.c
 
-libsigrokoutput_la_CFLAGS = \
+libsigrok4DSLogicoutput_la_CFLAGS = \
        -I$(top_srcdir)
 
-libsigrokoutput_la_LIBADD = \
-       text/libsigrokoutputtext.la
+libsigrok4DSLogicoutput_la_LIBADD = \
+       text/libsigrok4DSLogicoutputtext.la
 
diff --git a/output/out_analog.c b/output/out_analog.c
new file mode 100644 (file)
index 0000000..684f882
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2012 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 <string.h>
+#include <math.h>
+#include <glib.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "output/analog: "
+#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)
+
+struct context {
+       int num_enabled_probes;
+       GPtrArray *probelist;
+};
+
+static int init(struct sr_output *o)
+{
+       struct context *ctx;
+       struct sr_probe *probe;
+       GSList *l;
+
+       sr_spew("Initializing output module.");
+
+       if (!o || !o->sdi)
+               return SR_ERR_ARG;
+
+       if (!(ctx = g_try_malloc0(sizeof(struct context)))) {
+               sr_err("Output module context malloc failed.");
+               return SR_ERR_MALLOC;
+       }
+       o->internal = ctx;
+
+       /* Get the number of probes and their names. */
+       ctx->probelist = g_ptr_array_new();
+       for (l = o->sdi->probes; l; l = l->next) {
+               probe = l->data;
+               if (!probe || !probe->enabled)
+                       continue;
+               g_ptr_array_add(ctx->probelist, probe->name);
+               ctx->num_enabled_probes++;
+       }
+
+       return SR_OK;
+}
+
+static void si_printf(float value, GString *out, char *unitstr)
+{
+       float v;
+
+       if (signbit(value))
+               v = -(value);
+       else
+               v = value;
+
+       if (v < 1e-12 || v > 1e+12)
+               g_string_append_printf(out, "%f %s", value, unitstr);
+       else if (v > 1e+9)
+               g_string_append_printf(out, "%f G%s", value / 1e+9, unitstr);
+       else if (v > 1e+6)
+               g_string_append_printf(out, "%f M%s", value / 1e+6, unitstr);
+       else if (v > 1e+3)
+               g_string_append_printf(out, "%f k%s", value / 1e+3, unitstr);
+       else if (v < 1e-9)
+               g_string_append_printf(out, "%f n%s", value * 1e+9, unitstr);
+       else if (v < 1e-6)
+               g_string_append_printf(out, "%f u%s", value * 1e+6, unitstr);
+       else if (v < 1e-3)
+               g_string_append_printf(out, "%f m%s", value * 1e+3, unitstr);
+       else
+               g_string_append_printf(out, "%f %s", value, unitstr);
+
+}
+
+static void fancyprint(int unit, int mqflags, float value, GString *out)
+{
+       switch (unit) {
+       case SR_UNIT_VOLT:
+               si_printf(value, out, "V");
+               break;
+       case SR_UNIT_AMPERE:
+               si_printf(value, out, "A");
+               break;
+       case SR_UNIT_OHM:
+               si_printf(value, out, "");
+               g_string_append_unichar(out, 0x2126);
+               break;
+       case SR_UNIT_FARAD:
+               si_printf(value, out, "F");
+               break;
+       case SR_UNIT_KELVIN:
+               si_printf(value, out, "K");
+               break;
+       case SR_UNIT_CELSIUS:
+               si_printf(value, out, "");
+               g_string_append_unichar(out, 0x00b0);
+               g_string_append_c(out, 'C');
+               break;
+       case SR_UNIT_FAHRENHEIT:
+               si_printf(value, out, "");
+               g_string_append_unichar(out, 0x00b0);
+               g_string_append_c(out, 'F');
+               break;
+       case SR_UNIT_HERTZ:
+               si_printf(value, out, "Hz");
+               break;
+       case SR_UNIT_PERCENTAGE:
+               g_string_append_printf(out, "%f%%", value);
+               break;
+       case SR_UNIT_BOOLEAN:
+               if (value > 0)
+                       g_string_append_printf(out, "TRUE");
+               else
+                       g_string_append_printf(out, "FALSE");
+               break;
+       case SR_UNIT_SECOND:
+               si_printf(value, out, "s");
+               break;
+       case SR_UNIT_SIEMENS:
+               si_printf(value, out, "S");
+               break;
+       case SR_UNIT_DECIBEL_MW:
+               si_printf(value, out, "dBu");
+               break;
+       case SR_UNIT_DECIBEL_VOLT:
+               si_printf(value, out, "dBV");
+               break;
+       case SR_UNIT_DECIBEL_SPL:
+               if (mqflags & SR_MQFLAG_SPL_FREQ_WEIGHT_A)
+                       si_printf(value, out, "dB(A)");
+               else if (mqflags & SR_MQFLAG_SPL_FREQ_WEIGHT_C)
+                       si_printf(value, out, "dB(C)");
+               else if (mqflags & SR_MQFLAG_SPL_FREQ_WEIGHT_Z)
+                       si_printf(value, out, "dB(Z)");
+               else
+                       /* No frequency weighting, or non-standard "flat" */
+                       si_printf(value, out, "dB(SPL)");
+               if (mqflags & SR_MQFLAG_SPL_TIME_WEIGHT_S)
+                       g_string_append(out, " S");
+               else if (mqflags & SR_MQFLAG_SPL_TIME_WEIGHT_F)
+                       g_string_append(out, " F");
+               if (mqflags & SR_MQFLAG_SPL_LAT)
+                       g_string_append(out, " LAT");
+               else if (mqflags & SR_MQFLAG_SPL_PCT_OVER_ALARM)
+                       /* Not a standard function for SLMs, so this is
+                        * a made-up notation. */
+                       g_string_append(out, " %oA");
+               break;
+       case SR_UNIT_CONCENTRATION:
+               g_string_append_printf(out, "%f ppm", value * 1000000);
+               break;
+       default:
+               si_printf(value, out, "");
+               break;
+       }
+       if ((mqflags & (SR_MQFLAG_AC | SR_MQFLAG_DC)) == (SR_MQFLAG_AC | SR_MQFLAG_DC))
+               g_string_append_printf(out, " AC+DC");
+       else if (mqflags & SR_MQFLAG_AC)
+               g_string_append_printf(out, " AC");
+       else if (mqflags & SR_MQFLAG_DC)
+               g_string_append_printf(out, " DC");
+       g_string_append_c(out, '\n');
+}
+
+static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
+               const struct sr_datafeed_packet *packet, GString **out)
+{
+       const struct sr_datafeed_analog *analog;
+       struct sr_probe *probe;
+       GSList *l;
+       const float *fdata;
+       int i, p;
+
+       (void)sdi;
+
+       *out = NULL;
+       if (!o || !o->sdi)
+               return SR_ERR_ARG;
+
+       switch (packet->type) {
+       case SR_DF_FRAME_BEGIN:
+               *out = g_string_new("FRAME-BEGIN\n");
+               break;
+       case SR_DF_FRAME_END:
+               *out = g_string_new("FRAME-END\n");
+               break;
+       case SR_DF_ANALOG:
+               analog = packet->payload;
+               fdata = (const float *)analog->data;
+               *out = g_string_sized_new(512);
+               for (i = 0; i < analog->num_samples; i++) {
+                       for (l = analog->probes, p = 0; l; l = l->next, p++) {
+                               probe = l->data;
+                               g_string_append_printf(*out, "%s: ", probe->name);
+                               fancyprint(analog->unit, analog->mqflags,
+                                               fdata[i + p], *out);
+                       }
+               }
+               break;
+       }
+
+       return SR_OK;
+}
+
+static int cleanup(struct sr_output *o)
+{
+       struct context *ctx;
+
+       if (!o || !o->sdi)
+               return SR_ERR_ARG;
+       ctx = o->internal;
+
+       g_ptr_array_free(ctx->probelist, 1);
+       g_free(ctx);
+       o->internal = NULL;
+
+       return SR_OK;
+}
+
+SR_PRIV struct sr_output_format output_analog = {
+       .id = "analog",
+       .description = "Analog data",
+       .df_type = SR_DF_ANALOG,
+       .init = init,
+       .receive = receive,
+       .cleanup = cleanup
+};
diff --git a/output/out_binary.c b/output/out_binary.c
new file mode 100644 (file)
index 0000000..2fd858e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "output/binary: "
+#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)
+
+static int data(struct sr_output *o, const uint8_t *data_in,
+               uint64_t length_in, uint8_t **data_out, uint64_t *length_out)
+{
+       uint8_t *outbuf;
+
+       (void)o;
+
+       if (!data_in) {
+               sr_err("%s: data_in was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!length_out) {
+               sr_err("%s: length_out was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (length_in == 0) {
+               sr_err("%s: length_in was 0", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!(outbuf = g_try_malloc0(length_in))) {
+               sr_err("%s: outbuf malloc failed", __func__);
+               return SR_ERR_MALLOC;
+       }
+
+       memcpy(outbuf, data_in, length_in);
+       *data_out = outbuf;
+       *length_out = length_in;
+
+       return SR_OK;
+}
+
+SR_PRIV struct sr_output_format output_binary = {
+       .id = "binary",
+       .description = "Raw binary",
+       .df_type = SR_DF_LOGIC,
+       .init = NULL,
+       .data = data,
+       .event = NULL,
+};
diff --git a/output/out_csv.c b/output/out_csv.c
new file mode 100644 (file)
index 0000000..0a7c504
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2011 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include "config.h" /* Needed for PACKAGE_STRING and others. */
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "output/csv: "
+#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)
+
+struct context {
+       unsigned int num_enabled_probes;
+       unsigned int unitsize;
+       uint64_t samplerate;
+       GString *header;
+       char separator;
+};
+
+/*
+ * TODO:
+ *  - Option to specify delimiter character and/or string.
+ *  - Option to (not) print metadata as comments.
+ *  - Option to specify the comment character(s), e.g. # or ; or C/C++-style.
+ *  - Option to (not) print samplenumber / time as extra column.
+ *  - Option to "compress" output (only print changed samples, VCD-like).
+ *  - Option to print comma-separated bits, or whole bytes/words (for 8/16
+ *    probe LAs) as ASCII/hex etc. etc.
+ *  - Trigger support.
+ */
+
+static int init(struct sr_output *o)
+{
+       struct context *ctx;
+       struct sr_probe *probe;
+       GSList *l;
+       GVariant *gvar;
+       int num_probes;
+       time_t t;
+
+       if (!o) {
+               sr_err("%s: o was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!o->sdi) {
+               sr_err("%s: o->sdi was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!(ctx = g_try_malloc0(sizeof(struct context)))) {
+               sr_err("%s: ctx malloc failed", __func__);
+               return SR_ERR_MALLOC;
+       }
+
+       o->internal = ctx;
+
+       /* Get the number of probes, and the unitsize. */
+       for (l = o->sdi->probes; l; l = l->next) {
+               probe = l->data;
+               if (probe->enabled)
+                       ctx->num_enabled_probes++;
+       }
+
+       ctx->unitsize = (ctx->num_enabled_probes + 7) / 8;
+
+       num_probes = g_slist_length(o->sdi->probes);
+
+       if (sr_config_get(o->sdi->driver, SR_CONF_SAMPLERATE, &gvar,
+                       o->sdi) == SR_OK) {
+               ctx->samplerate = g_variant_get_uint64(gvar);
+               g_variant_unref(gvar);
+       } else
+               ctx->samplerate = 0;
+
+       ctx->separator = ',';
+       ctx->header = g_string_sized_new(512);
+
+       t = time(NULL);
+
+       /* Some metadata */
+       g_string_append_printf(ctx->header, "; CSV, generated by %s on %s",
+                              PACKAGE_STRING, ctime(&t));
+       g_string_append_printf(ctx->header, "; Samplerate: %"PRIu64"\n",
+                              ctx->samplerate);
+
+       /* Columns / channels */
+       g_string_append_printf(ctx->header, "; Channels (%d/%d): ",
+                              ctx->num_enabled_probes, num_probes);
+       for (l = o->sdi->probes; l; l = l->next) {
+               probe = l->data;
+               if (probe->enabled)
+                       g_string_append_printf(ctx->header, "%s, ", probe->name);
+       }
+       g_string_append_printf(ctx->header, "\n");
+
+       return SR_OK;
+}
+
+static int event(struct sr_output *o, int event_type, uint8_t **data_out,
+                uint64_t *length_out)
+{
+       struct context *ctx;
+
+       if (!o) {
+               sr_err("%s: o was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!(ctx = o->internal)) {
+               sr_err("%s: o->internal was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!data_out) {
+               sr_err("%s: data_out was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       switch (event_type) {
+       case SR_DF_TRIGGER:
+               sr_dbg("%s: SR_DF_TRIGGER event", __func__);
+               /* TODO */
+               *data_out = NULL;
+               *length_out = 0;
+               break;
+       case SR_DF_END:
+               sr_dbg("%s: SR_DF_END event", __func__);
+               /* TODO */
+               *data_out = NULL;
+               *length_out = 0;
+               g_free(o->internal);
+               o->internal = NULL;
+               break;
+       default:
+               sr_err("%s: unsupported event type: %d", __func__, event_type);
+               *data_out = NULL;
+               *length_out = 0;
+               break;
+       }
+
+       return SR_OK;
+}
+
+static int data(struct sr_output *o, const uint8_t *data_in,
+               uint64_t length_in, uint8_t **data_out, uint64_t *length_out)
+{
+       struct context *ctx;
+       GString *outstr;
+       uint64_t sample, i;
+       int j;
+
+       if (!o) {
+               sr_err("%s: o was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!(ctx = o->internal)) {
+               sr_err("%s: o->internal was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (!data_in) {
+               sr_err("%s: data_in was NULL", __func__);
+               return SR_ERR_ARG;
+       }
+
+       if (ctx->header) {
+               /* First data packet. */
+               outstr = ctx->header;
+               ctx->header = NULL;
+       } else {
+               outstr = g_string_sized_new(512);
+       }
+
+       for (i = 0; i <= length_in - ctx->unitsize; i += ctx->unitsize) {
+               memcpy(&sample, data_in + i, ctx->unitsize);
+               for (j = ctx->num_enabled_probes - 1; j >= 0; j--) {
+                       g_string_append_printf(outstr, "%d%c",
+                               (int)((sample & (1 << j)) >> j),
+                               ctx->separator);
+               }
+               g_string_append_printf(outstr, "\n");
+       }
+
+       *data_out = (uint8_t *)outstr->str;
+       *length_out = outstr->len;
+       g_string_free(outstr, FALSE);
+
+       return SR_OK;
+}
+
+SR_PRIV struct sr_output_format output_csv = {
+       .id = "csv",
+       .description = "Comma-separated values (CSV)",
+       .df_type = SR_DF_LOGIC,
+       .init = init,
+       .data = data,
+       .event = event,
+};
diff --git a/output/out_vcd.c b/output/out_vcd.c
new file mode 100644 (file)
index 0000000..04d7fcb
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include "config.h" /* Needed for PACKAGE and others. */
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "output/vcd: "
+#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)
+
+struct context {
+       int num_enabled_probes;
+       GArray *probeindices;
+       GString *header;
+       uint8_t *prevsample;
+       int period;
+       uint64_t samplerate;
+       unsigned int unitsize;
+};
+
+static const char *vcd_header_comment = "\
+$comment\n  Acquisition with %d/%d probes at %s\n$end\n";
+
+static int init(struct sr_output *o)
+{
+       struct context *ctx;
+       struct sr_probe *probe;
+       GSList *l;
+       GVariant *gvar;
+       int num_probes, i;
+       char *samplerate_s, *frequency_s, *timestamp;
+       time_t t;
+
+       if (!(ctx = g_try_malloc0(sizeof(struct context)))) {
+               sr_err("%s: ctx malloc failed", __func__);
+               return SR_ERR_MALLOC;
+       }
+
+       o->internal = ctx;
+       ctx->num_enabled_probes = 0;
+       ctx->probeindices = g_array_new(FALSE, FALSE, sizeof(int));
+
+       for (l = o->sdi->probes; l; l = l->next) {
+               probe = l->data;
+               if (!probe->enabled)
+                       continue;
+               ctx->probeindices = g_array_append_val(
+                               ctx->probeindices, probe->index);
+               ctx->num_enabled_probes++;
+       }
+       if (ctx->num_enabled_probes > 94) {
+               sr_err("VCD only supports 94 probes.");
+               return SR_ERR;
+       }
+
+       ctx->unitsize = (ctx->num_enabled_probes + 7) / 8;
+       ctx->header = g_string_sized_new(512);
+       num_probes = g_slist_length(o->sdi->probes);
+
+       /* timestamp */
+       t = time(NULL);
+       timestamp = g_strdup(ctime(&t));
+       timestamp[strlen(timestamp)-1] = 0;
+       g_string_printf(ctx->header, "$date %s $end\n", timestamp);
+       g_free(timestamp);
+
+       /* generator */
+       g_string_append_printf(ctx->header, "$version %s %s $end\n",
+                       PACKAGE, PACKAGE_VERSION);
+
+       if (sr_config_get(o->sdi->driver, SR_CONF_SAMPLERATE, &gvar,
+                       o->sdi) == SR_OK) {
+               ctx->samplerate = g_variant_get_uint64(gvar);
+               g_variant_unref(gvar);
+               if (!((samplerate_s = sr_samplerate_string(ctx->samplerate)))) {
+                       g_string_free(ctx->header, TRUE);
+                       g_free(ctx);
+                       return SR_ERR;
+               }
+               g_string_append_printf(ctx->header, vcd_header_comment,
+                                ctx->num_enabled_probes, num_probes, samplerate_s);
+               g_free(samplerate_s);
+       }
+
+       /* timescale */
+       /* VCD can only handle 1/10/100 (s - fs), so scale up first */
+       if (ctx->samplerate > SR_MHZ(1))
+               ctx->period = SR_GHZ(1);
+       else if (ctx->samplerate > SR_KHZ(1))
+               ctx->period = SR_MHZ(1);
+       else
+               ctx->period = SR_KHZ(1);
+       if (!(frequency_s = sr_period_string(ctx->period))) {
+               g_string_free(ctx->header, TRUE);
+               g_free(ctx);
+               return SR_ERR;
+       }
+       g_string_append_printf(ctx->header, "$timescale %s $end\n", frequency_s);
+       g_free(frequency_s);
+
+       /* scope */
+       g_string_append_printf(ctx->header, "$scope module %s $end\n", PACKAGE);
+
+       /* Wires / channels */
+       for (i = 0, l = o->sdi->probes; l; l = l->next, i++) {
+               probe = l->data;
+               if (!probe->enabled)
+                       continue;
+               g_string_append_printf(ctx->header, "$var wire 1 %c %s $end\n",
+                               (char)('!' + i), probe->name);
+       }
+
+       g_string_append(ctx->header, "$upscope $end\n"
+                       "$enddefinitions $end\n$dumpvars\n");
+
+       if (!(ctx->prevsample = g_try_malloc0(ctx->unitsize))) {
+               g_string_free(ctx->header, TRUE);
+               g_free(ctx);
+               sr_err("%s: ctx->prevsample malloc failed", __func__);
+               return SR_ERR_MALLOC;
+       }
+
+       return SR_OK;
+}
+
+static int receive(struct sr_output *o, const struct sr_dev_inst *sdi,
+               const struct sr_datafeed_packet *packet, GString **out)
+{
+       const struct sr_datafeed_logic *logic;
+       struct context *ctx;
+       unsigned int i;
+       int p, curbit, prevbit, index;
+       uint8_t *sample;
+       static uint64_t samplecount = 0;
+
+       (void)sdi;
+
+       *out = NULL;
+       if (!o || !o->internal)
+               return SR_ERR_ARG;
+       ctx = o->internal;
+
+       if (packet->type == SR_DF_END) {
+               *out = g_string_new("$dumpoff\n$end\n");
+               return SR_OK;
+       } else if (packet->type != SR_DF_LOGIC)
+               return SR_OK;
+
+       if (ctx->header) {
+               /* The header is still here, this must be the first packet. */
+               *out = ctx->header;
+               ctx->header = NULL;
+       } else {
+               *out = g_string_sized_new(512);
+       }
+
+       logic = packet->payload;
+       for (i = 0; i <= logic->length - logic->unitsize; i += logic->unitsize) {
+               samplecount++;
+
+               sample = logic->data + i;
+
+               for (p = 0; p < ctx->num_enabled_probes; p++) {
+                       index = g_array_index(ctx->probeindices, int, p);
+                       curbit = (sample[p / 8] & (((uint8_t) 1) << index)) >> index;
+                       prevbit = (ctx->prevsample[p / 8] & (((uint64_t) 1) << index)) >> index;
+
+                       /* VCD only contains deltas/changes of signals. */
+                       if (prevbit == curbit)
+                               continue;
+
+                       /* Output which signal changed to which value. */
+                       g_string_append_printf(*out, "#%" PRIu64 "\n%i%c\n",
+                                       (uint64_t)(((float)samplecount / ctx->samplerate)
+                                       * ctx->period), curbit, (char)('!' + p));
+               }
+
+               memcpy(ctx->prevsample, sample, ctx->unitsize);
+       }
+
+       return SR_OK;
+}
+
+static int cleanup(struct sr_output *o)
+{
+       struct context *ctx;
+
+       if (!o || !o->internal)
+               return SR_ERR_ARG;
+
+       ctx = o->internal;
+       g_free(ctx);
+
+       return SR_OK;
+}
+
+struct sr_output_format output_vcd = {
+       .id = "vcd",
+       .description = "Value Change Dump (VCD)",
+       .df_type = SR_DF_LOGIC,
+       .init = init,
+       .receive = receive,
+       .cleanup = cleanup,
+};
index a3e5dc790363c1377159eb03d44b29446c524952..62ce0c189ce773ea3ea984c250e6b7f1743abd57 100644 (file)
@@ -54,9 +54,7 @@ extern SR_PRIV struct sr_output_format output_text_hex;
 extern SR_PRIV struct sr_output_format output_text_ascii;
 extern SR_PRIV struct sr_output_format output_binary;
 extern SR_PRIV struct sr_output_format output_vcd;
-extern SR_PRIV struct sr_output_format output_ols;
-extern SR_PRIV struct sr_output_format output_gnuplot;
-extern SR_PRIV struct sr_output_format output_chronovu_la8;
+
 extern SR_PRIV struct sr_output_format output_csv;
 extern SR_PRIV struct sr_output_format output_analog;
 /* extern SR_PRIV struct sr_output_format output_analog_gnuplot; */
@@ -68,9 +66,6 @@ static struct sr_output_format *output_module_list[] = {
        &output_text_ascii,
        &output_binary,
        &output_vcd,
-       &output_ols,
-       &output_gnuplot,
-       &output_chronovu_la8,
        &output_csv,
        &output_analog,
        /* &output_analog_gnuplot, */
index 348892c0a938e282071a870cdb0d8e97c613b9cd..a6edae8da12e2c0068e4284f960e076730172612 100644 (file)
 ##
 
 # Local lib, this is NOT meant to be installed!
-noinst_LTLIBRARIES = libsigrokoutputtext.la
+noinst_LTLIBRARIES = libsigrok4DSLogicoutputtext.la
 
-libsigrokoutputtext_la_SOURCES = \
+libsigrok4DSLogicoutputtext_la_SOURCES = \
        text.c \
        text.h \
        bits.c \
        hex.c \
        ascii.c
 
-libsigrokoutputtext_la_CFLAGS = \
+libsigrok4DSLogicoutputtext_la_CFLAGS = \
        -I$(top_srcdir)
 
diff --git a/proto.h b/proto.h
index 821846f223abb66e91fc0e29049245a49572feb6..322dc2d2688ae7fc543487732cff35ba06f7d6a1 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -103,11 +103,11 @@ SR_API int sr_session_stop(void);
 SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi,
                unsigned char *buf, int unitsize, int units);
 SR_API int sr_session_source_add(int fd, int events, int timeout,
-               sr_receive_data_callback_t cb, void *cb_data);
+               sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi);
 SR_API int sr_session_source_add_pollfd(GPollFD *pollfd, int timeout,
-               sr_receive_data_callback_t cb, void *cb_data);
+               sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi);
 SR_API int sr_session_source_add_channel(GIOChannel *channel, int events,
-               int timeout, sr_receive_data_callback_t cb, void *cb_data);
+               int timeout, sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi);
 SR_API int sr_session_source_remove(int fd);
 SR_API int sr_session_source_remove_pollfd(GPollFD *pollfd);
 SR_API int sr_session_source_remove_channel(GIOChannel *channel);
@@ -151,4 +151,29 @@ SR_API const char *sr_lib_version_string_get(void);
 SR_API const char *sr_strerror(int error_code);
 SR_API const char *sr_strerror_name(int error_code);
 
+/*--- libusbhp.c ------------------------------------------------------------*/
+SR_API int libusbhp_init(struct libusbhp_t **handle);
+
+SR_API void libusbhp_exit(struct libusbhp_t *handle);
+
+SR_API int libusbhp_handle_events_timeout(struct libusbhp_t *handle, struct timeval *tv);
+
+SR_API void libusbhp_register_hotplug_listeners(struct libusbhp_t *handle,
+                                        libusbhp_hotplug_cb_fn connected_cb,
+                                        libusbhp_hotplug_cb_fn disconnected_cb,
+                                        void *user_data);
+
+/*--- trigger.c ------------------------------------------------------------*/
+SR_API int ds_trigger_init(void);
+SR_API int ds_trigger_destroy(void);
+SR_API int ds_trigger_stage_set_value(uint16_t stage, uint16_t probes, char *trigger0, char *trigger1);
+SR_API int ds_trigger_stage_set_logic(uint16_t stage, uint16_t probes, unsigned char trigger_logic);
+SR_API int ds_trigger_stage_set_inv(uint16_t stage, uint16_t probes, unsigned char trigger0_inv, unsigned char trigger1_inv);
+SR_API int ds_trigger_stage_set_count(uint16_t stage, uint16_t probes, uint16_t trigger0_count, uint16_t trigger1_count);
+SR_API int ds_trigger_probe_set(uint16_t probe, unsigned char trigger0, unsigned char trigger1);
+SR_API int ds_trigger_set_stage(uint16_t stages);
+SR_API int ds_trigger_set_pos(uint16_t position);
+SR_API int ds_trigger_set_en(uint16_t enable);
+SR_API int ds_trigger_set_mode(uint16_t mode);
+
 #endif
index 4fa5dafea6ac48722dc6752cd5ae38519ce210fd..29e19085434bb67acbc9665b129d64d492812c8b 100644 (file)
--- a/session.c
+++ b/session.c
@@ -85,7 +85,7 @@ SR_API struct sr_session *sr_session_new(void)
 
        session->source_timeout = -1;
        session->abort_session = FALSE;
-       g_mutex_init(&session->stop_mutex);
+//     g_mutex_init(&session->stop_mutex);
 
        return session;
 }
@@ -106,9 +106,21 @@ SR_API int sr_session_destroy(void)
 
        sr_session_dev_remove_all();
 
+    sr_session_datafeed_callback_remove_all();
+
+    if (session->sources) {
+        g_free(session->sources);
+        session->sources = NULL;
+    }
+
+    if (session->pollfds) {
+        g_free(session->pollfds);
+        session->pollfds = NULL;
+    }
+
        /* TODO: Error checks needed? */
 
-       g_mutex_clear(&session->stop_mutex);
+//     g_mutex_clear(&session->stop_mutex);
 
        g_free(session);
        session = NULL;
@@ -259,13 +271,13 @@ static int sr_session_run_poll(void)
                         * we check the flag after processing every source, not
                         * just once per main event loop.
                         */
-                       g_mutex_lock(&session->stop_mutex);
+//                     g_mutex_lock(&session->stop_mutex);
                        if (session->abort_session) {
                                sr_session_stop_sync();
                                /* But once is enough. */
                                session->abort_session = FALSE;
                        }
-                       g_mutex_unlock(&session->stop_mutex);
+//                     g_mutex_unlock(&session->stop_mutex);
                }
        }
 
@@ -376,7 +388,7 @@ SR_PRIV int sr_session_stop_sync(void)
                sdi = l->data;
                if (sdi->driver) {
                        if (sdi->driver->dev_acquisition_stop)
-                               sdi->driver->dev_acquisition_stop(sdi, sdi);
+                sdi->driver->dev_acquisition_stop(sdi, NULL);
                }
        }
 
@@ -403,9 +415,9 @@ SR_API int sr_session_stop(void)
                return SR_ERR_BUG;
        }
 
-       g_mutex_lock(&session->stop_mutex);
+//     g_mutex_lock(&session->stop_mutex);
        session->abort_session = TRUE;
-       g_mutex_unlock(&session->stop_mutex);
+//     g_mutex_unlock(&session->stop_mutex);
 
        return SR_OK;
 }
@@ -506,7 +518,7 @@ SR_PRIV int sr_session_send(const struct sr_dev_inst *sdi,
  *         SR_ERR_MALLOC upon memory allocation errors.
  */
 static int _sr_session_source_add(GPollFD *pollfd, int timeout,
-       sr_receive_data_callback_t cb, void *cb_data, gintptr poll_object)
+    sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi, gintptr poll_object)
 {
        struct source *new_sources, *s;
        GPollFD *new_pollfds;
@@ -536,7 +548,7 @@ static int _sr_session_source_add(GPollFD *pollfd, int timeout,
        s = &new_sources[session->num_sources++];
        s->timeout = timeout;
        s->cb = cb;
-       s->cb_data = cb_data;
+       s->cb_data = sdi;
        s->poll_object = poll_object;
        session->pollfds = new_pollfds;
        session->sources = new_sources;
@@ -561,14 +573,14 @@ static int _sr_session_source_add(GPollFD *pollfd, int timeout,
  *         SR_ERR_MALLOC upon memory allocation errors.
  */
 SR_API int sr_session_source_add(int fd, int events, int timeout,
-               sr_receive_data_callback_t cb, void *cb_data)
+               sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi)
 {
        GPollFD p;
 
        p.fd = fd;
        p.events = events;
 
-       return _sr_session_source_add(&p, timeout, cb, cb_data, (gintptr)fd);
+    return _sr_session_source_add(&p, timeout, cb, sdi, (gintptr)fd);
 }
 
 /**
@@ -583,10 +595,10 @@ SR_API int sr_session_source_add(int fd, int events, int timeout,
  *         SR_ERR_MALLOC upon memory allocation errors.
  */
 SR_API int sr_session_source_add_pollfd(GPollFD *pollfd, int timeout,
-               sr_receive_data_callback_t cb, void *cb_data)
+               sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi)
 {
-       return _sr_session_source_add(pollfd, timeout, cb,
-                                     cb_data, (gintptr)pollfd);
+    return _sr_session_source_add(pollfd, timeout, cb,
+                      sdi, (gintptr)pollfd);
 }
 
 /**
@@ -602,7 +614,7 @@ SR_API int sr_session_source_add_pollfd(GPollFD *pollfd, int timeout,
  *         SR_ERR_MALLOC upon memory allocation errors.
  */
 SR_API int sr_session_source_add_channel(GIOChannel *channel, int events,
-               int timeout, sr_receive_data_callback_t cb, void *cb_data)
+               int timeout, sr_receive_data_callback_t cb, const struct sr_dev_inst *sdi)
 {
        GPollFD p;
 
@@ -613,7 +625,7 @@ SR_API int sr_session_source_add_channel(GIOChannel *channel, int events,
        p.events = events;
 #endif
 
-       return _sr_session_source_add(&p, timeout, cb, cb_data, (gintptr)channel);
+    return _sr_session_source_add(&p, timeout, cb, sdi, (gintptr)channel);
 }
 
 /**
index 9df848d4fdfc1a5267db82f3bc5951e04eabda3d..b040c07272eea7db84491b4ef4920dc11601f607 100644 (file)
@@ -47,6 +47,7 @@ struct session_vdev {
        struct zip_file *capfile;
        int bytes_read;
        uint64_t samplerate;
+    uint64_t total_samples;
        int unitsize;
        int num_probes;
 };
@@ -58,7 +59,7 @@ static const int hwcaps[] = {
        0,
 };
 
-static int receive_data(int fd, int revents, void *cb_data)
+static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi)
 {
        struct sr_dev_inst *sdi;
        struct session_vdev *vdev;
@@ -95,7 +96,7 @@ static int receive_data(int fd, int revents, void *cb_data)
                        logic.unitsize = vdev->unitsize;
                        logic.data = buf;
                        vdev->bytes_read += ret;
-                       sr_session_send(cb_data, &packet);
+                       sr_session_send(cb_sdi, &packet);
                } else {
                        /* done with this capture file */
                        zip_fclose(vdev->capfile);
@@ -107,7 +108,7 @@ static int receive_data(int fd, int revents, void *cb_data)
 
        if (!got_data) {
                packet.type = SR_DF_END;
-               sr_session_send(cb_data, &packet);
+               sr_session_send(cb_sdi, &packet);
                sr_session_source_remove(-1);
        }
 
@@ -160,6 +161,13 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
                } else
                        return SR_ERR;
                break;
+    case SR_CONF_LIMIT_SAMPLES:
+        if (sdi) {
+            vdev = sdi->priv;
+            *data = g_variant_new_uint64(vdev->total_samples);
+        } else
+            return SR_ERR;
+        break;
        default:
                return SR_ERR_ARG;
        }
@@ -189,6 +197,9 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
        case SR_CONF_CAPTURE_UNITSIZE:
                vdev->unitsize = g_variant_get_uint64(data);
                break;
+    case SR_CONF_LIMIT_SAMPLES:
+        vdev->total_samples = g_variant_get_uint64(data);
+        break;
        case SR_CONF_CAPTURE_NUM_PROBES:
                vdev->num_probes = g_variant_get_uint64(data);
                break;
@@ -207,8 +218,10 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
 
        switch (key) {
        case SR_CONF_DEVICE_OPTIONS:
-               *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
-                               hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
+//             *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
+//                             hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
+               *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"),
+                               hwcaps, ARRAY_SIZE(hwcaps)*sizeof(int32_t), TRUE, NULL, NULL);
                break;
        default:
                return SR_ERR_ARG;
@@ -248,10 +261,10 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
        }
 
        /* Send header packet to the session bus. */
-       std_session_send_df_header(cb_data, LOG_PREFIX);
+    std_session_send_df_header(sdi, LOG_PREFIX);
 
        /* freewheeling source */
-       sr_session_source_add(-1, 0, 0, receive_data, cb_data);
+    sr_session_source_add(-1, 0, 0, receive_data, sdi);
 
        return SR_OK;
 }
index 4838a6be00566b2f0fc7fb140697bc7f4b653b2c..43ba01c37d6ae74af8e26185fe283330437f8476 100644 (file)
@@ -84,27 +84,9 @@ SR_API int sr_session_load(const char *filename)
                return SR_ERR;
        }
 
-       /* check "version" */
-       version = 0;
-       if (!(zf = zip_fopen(archive, "version", 0))) {
-               sr_dbg("Not a sigrok session file.");
-               return SR_ERR;
-       }
-       if ((ret = zip_fread(zf, s, 10)) == -1) {
-               sr_dbg("Not a valid sigrok session file.");
-               return SR_ERR;
-       }
-       zip_fclose(zf);
-       s[ret] = 0;
-       version = strtoull(s, NULL, 10);
-       if (version != 1) {
-               sr_dbg("Not a valid sigrok session file version.");
-               return SR_ERR;
-       }
-
        /* read "metadata" */
-       if (zip_stat(archive, "metadata", 0, &zs) == -1) {
-               sr_dbg("Not a valid sigrok session file.");
+    if (zip_stat(archive, "header", 0, &zs) == -1) {
+        sr_dbg("Not a valid DSLogic session file.");
                return SR_ERR;
        }
 
@@ -129,10 +111,10 @@ SR_API int sr_session_load(const char *filename)
        capturefiles = g_ptr_array_new_with_free_func(g_free);
        sections = g_key_file_get_groups(kf, NULL);
        for (i = 0; sections[i]; i++) {
-               if (!strcmp(sections[i], "global"))
+        if (!strcmp(sections[i], "version"))
                        /* nothing really interesting in here yet */
                        continue;
-               if (!strncmp(sections[i], "device ", 7)) {
+        if (!strncmp(sections[i], "header", 6)) {
                        /* device section */
                        sdi = NULL;
                        enabled_probes = total_probes = 0;
@@ -140,7 +122,7 @@ SR_API int sr_session_load(const char *filename)
                        for (j = 0; keys[j]; j++) {
                                val = g_key_file_get_string(kf, sections[i], keys[j], NULL);
                                if (!strcmp(keys[j], "capturefile")) {
-                                       sdi = sr_dev_inst_new(devcnt, SR_ST_ACTIVE, NULL, NULL, NULL);
+                    sdi = sr_dev_inst_new(LOGIC, devcnt, SR_ST_ACTIVE, NULL, NULL, NULL);
                                        sdi->driver = &session_driver;
                                        if (devcnt == 0)
                                                /* first device, init the driver */
@@ -160,6 +142,10 @@ SR_API int sr_session_load(const char *filename)
                                        tmp_u64 = strtoull(val, NULL, 10);
                                        sdi->driver->config_set(SR_CONF_CAPTURE_UNITSIZE,
                                                        g_variant_new_uint64(tmp_u64), sdi);
+                } else if (!strcmp(keys[j], "total samples")) {
+                    tmp_u64 = strtoull(val, NULL, 10);
+                    sdi->driver->config_set(SR_CONF_LIMIT_SAMPLES,
+                            g_variant_new_uint64(tmp_u64), sdi);
                                } else if (!strcmp(keys[j], "total probes")) {
                                        total_probes = strtoull(val, NULL, 10);
                                        sdi->driver->config_set(SR_CONF_CAPTURE_NUM_PROBES,
@@ -213,15 +199,15 @@ SR_API int sr_session_load(const char *filename)
 SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi,
                unsigned char *buf, int unitsize, int units)
 {
-       GSList *l;
-       GVariant *gvar;
-       FILE *meta;
-       struct sr_probe *probe;
-       struct zip *zipfile;
-       struct zip_source *versrc, *metasrc, *logicsrc;
-       int tmpfile, ret, probecnt;
-       uint64_t samplerate;
-       char version[1], rawname[16], metafile[32], *s;
+    GSList *l;
+    GVariant *gvar;
+    FILE *meta;
+    struct sr_probe *probe;
+    struct zip *zipfile;
+    struct zip_source *versrc, *metasrc, *logicsrc;
+    int tmpfile, ret, probecnt;
+    uint64_t samplerate;
+    char rawname[16], metafile[32], *s;
 
        if (!filename) {
                sr_err("%s: filename was NULL", __func__);
@@ -233,77 +219,68 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi,
        if (!(zipfile = zip_open(filename, ZIP_CREATE, &ret)))
                return SR_ERR;
 
-       /* "version" */
-       version[0] = '1';
-       if (!(versrc = zip_source_buffer(zipfile, version, 1, 0)))
-               return SR_ERR;
-       if (zip_add(zipfile, "version", versrc) == -1) {
-               sr_info("error saving version into zipfile: %s",
-                       zip_strerror(zipfile));
-               return SR_ERR;
-       }
+    /* init "metadata" */
+    strcpy(metafile, "DSLogic-meta-XXXXXX");
+    if ((tmpfile = g_mkstemp(metafile)) == -1)
+        return SR_ERR;
+    close(tmpfile);
+    meta = g_fopen(metafile, "wb");
+    fprintf(meta, "[version]\n");
+    fprintf(meta, "DSLogic version = %s\n", PACKAGE_VERSION);
 
-       /* init "metadata" */
-       strcpy(metafile, "sigrok-meta-XXXXXX");
-       if ((tmpfile = g_mkstemp(metafile)) == -1)
-               return SR_ERR;
-       close(tmpfile);
-       meta = g_fopen(metafile, "wb");
-       fprintf(meta, "[global]\n");
-       fprintf(meta, "sigrok version = %s\n", PACKAGE_VERSION);
+    /* metadata */
+    fprintf(meta, "[header]\n");
+    if (sdi->driver)
+        fprintf(meta, "driver = %s\n", sdi->driver->name);
 
-       /* metadata */
-       fprintf(meta, "[device 1]\n");
-       if (sdi->driver)
-               fprintf(meta, "driver = %s\n", sdi->driver->name);
+    /* metadata */
+    fprintf(meta, "capturefile = data\n");
+    fprintf(meta, "unitsize = %d\n", unitsize);
+    fprintf(meta, "total samples = %d\n", units);
+    fprintf(meta, "total probes = %d\n", g_slist_length(sdi->probes));
+    if (sr_dev_has_option(sdi, SR_CONF_SAMPLERATE)) {
+        if (sr_config_get(sdi->driver, SR_CONF_SAMPLERATE,
+                &gvar, sdi) == SR_OK) {
+            samplerate = g_variant_get_uint64(gvar);
+            s = sr_samplerate_string(samplerate);
+            fprintf(meta, "samplerate = %s\n", s);
+            g_free(s);
+            g_variant_unref(gvar);
+        }
+    }
+    probecnt = 1;
+    for (l = sdi->probes; l; l = l->next) {
+        probe = l->data;
+        if (probe->enabled) {
+            if (probe->name)
+                fprintf(meta, "probe%d = %s\n", probecnt, probe->name);
+            if (probe->trigger)
+                fprintf(meta, " trigger%d = %s\n", probecnt, probe->trigger);
+            probecnt++;
+        }
+    }
 
-       /* metadata */
-       fprintf(meta, "capturefile = logic-1\n");
-       fprintf(meta, "unitsize = %d\n", unitsize);
-       fprintf(meta, "total probes = %d\n", g_slist_length(sdi->probes));
-       if (sr_dev_has_option(sdi, SR_CONF_SAMPLERATE)) {
-               if (sr_config_get(sdi->driver, SR_CONF_SAMPLERATE,
-                               &gvar, sdi) == SR_OK) {
-                       samplerate = g_variant_get_uint64(gvar);
-                       s = sr_samplerate_string(samplerate);
-                       fprintf(meta, "samplerate = %s\n", s);
-                       g_free(s);
-                       g_variant_unref(gvar);
-               }
-       }
-       probecnt = 1;
-       for (l = sdi->probes; l; l = l->next) {
-               probe = l->data;
-               if (probe->enabled) {
-                       if (probe->name)
-                               fprintf(meta, "probe%d = %s\n", probecnt, probe->name);
-                       if (probe->trigger)
-                               fprintf(meta, " trigger%d = %s\n", probecnt, probe->trigger);
-                       probecnt++;
-               }
-       }
-
-       if (!(logicsrc = zip_source_buffer(zipfile, buf,
-                          units * unitsize, FALSE)))
-               return SR_ERR;
-       snprintf(rawname, 15, "logic-1");
-       if (zip_add(zipfile, rawname, logicsrc) == -1)
-               return SR_ERR;
-       fclose(meta);
+    if (!(logicsrc = zip_source_buffer(zipfile, buf,
+               units * unitsize, FALSE)))
+        return SR_ERR;
+    snprintf(rawname, 15, "data");
+    if (zip_add(zipfile, rawname, logicsrc) == -1)
+        return SR_ERR;
+    fclose(meta);
 
-       if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1)))
-               return SR_ERR;
-       if (zip_add(zipfile, "metadata", metasrc) == -1)
-               return SR_ERR;
+    if (!(metasrc = zip_source_file(zipfile, metafile, 0, -1)))
+        return SR_ERR;
+    if (zip_add(zipfile, "header", metasrc) == -1)
+        return SR_ERR;
 
-       if ((ret = zip_close(zipfile)) == -1) {
-               sr_info("error saving zipfile: %s", zip_strerror(zipfile));
-               return SR_ERR;
-       }
+    if ((ret = zip_close(zipfile)) == -1) {
+        sr_info("error saving zipfile: %s", zip_strerror(zipfile));
+        return SR_ERR;
+    }
 
-       unlink(metafile);
+    unlink(metafile);
 
-       return SR_OK;
+    return SR_OK;
 }
 
 /** @} */
index 6c8a8605a26f7c294c67462ba23edf3f8fcb8c54..25f9438e3a1cee82b8e419f7923876050d9a213a 100644 (file)
@@ -35,6 +35,6 @@ check_main_SOURCES = \
 
 check_main_CFLAGS = @check_CFLAGS@
 
-check_main_LDADD = $(top_builddir)/libsigrok.la @check_LIBS@
+check_main_LDADD = $(top_builddir)/libsigrok4DSLogic.la @check_LIBS@
 
 endif
diff --git a/trigger.c b/trigger.c
new file mode 100644 (file)
index 0000000..d8a2aae
--- /dev/null
+++ b/trigger.c
@@ -0,0 +1,291 @@
+/*
+ * This file is part of the DSLogic project.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <glib.h>
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "session: "
+#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)
+
+/**
+ * @file
+ *
+ * init, set DSLogic trigger.
+ */
+
+/**
+ * @defgroup Trigger handling
+ *
+ * init, set DSLogic trigger
+ *
+ * @{
+ */
+
+struct ds_trigger *trigger;
+
+/**
+ * recovery trigger to initial status.
+ *
+ * @return SR_OK upon success.
+ */
+SR_API int ds_trigger_init(void)
+{
+    int i, j;
+
+    if (!(trigger = g_try_malloc0(sizeof(struct ds_trigger)))) {
+        sr_err("Trigger malloc failed.");
+        return SR_ERR_MALLOC;
+    }
+
+    trigger->trigger_en = 0;
+    trigger->trigger_mode = SIMPLE_TRIGGER;
+    trigger->trigger_pos = 0;
+    trigger->trigger_stages = 0;
+
+    for (i = 0; i <= TriggerStages; i++) {
+        for (j = 0; j < TriggerProbes; j++) {
+            trigger->trigger0[i][j] = 'X';
+            trigger->trigger1[i][j] = 'X';
+        }
+        trigger->trigger0_count[i] = 0;
+        trigger->trigger1_count[i] = 0;
+        trigger->trigger0_inv[i] = 0;
+        trigger->trigger1_inv[i] = 0;
+        trigger->trigger_logic[i] = 1;
+    }
+
+
+    return SR_OK;
+}
+
+SR_API int ds_trigger_destroy(void)
+{
+    if (trigger)
+        g_free(trigger);
+
+    return SR_OK;
+}
+
+/**
+ * set trigger based on stage
+ *
+ * @return SR_OK upon success.
+ */
+SR_API int ds_trigger_stage_set_value(uint16_t stage, uint16_t probes, char *trigger0, char *trigger1)
+{
+    assert(stage < TriggerStages);
+    assert(probes <= TriggerProbes);
+
+    int j;
+
+    for (j = 0; j< probes; j++) {
+        trigger->trigger0[stage][probes - j - 1] = *(trigger0 + j * 2);
+        trigger->trigger1[stage][probes - j - 1] = *(trigger1 + j * 2);
+    }
+
+    return SR_OK;
+}
+SR_API int ds_trigger_stage_set_logic(uint16_t stage, uint16_t probes, unsigned char trigger_logic)
+{
+    assert(stage < TriggerStages);
+    assert(probes <= TriggerProbes);
+
+    trigger->trigger_logic[stage] = trigger_logic;
+
+    return SR_OK;
+}
+SR_API int ds_trigger_stage_set_inv(uint16_t stage, uint16_t probes, unsigned char trigger0_inv, unsigned char trigger1_inv)
+{
+    assert(stage < TriggerStages);
+    assert(probes <= TriggerProbes);
+
+    trigger->trigger0_inv[stage] = trigger0_inv;
+    trigger->trigger1_inv[stage] = trigger1_inv;
+
+    return SR_OK;
+}
+SR_API int ds_trigger_stage_set_count(uint16_t stage, uint16_t probes, uint16_t trigger0_count, uint16_t trigger1_count)
+{
+    assert(stage < TriggerStages);
+    assert(probes <= TriggerProbes);
+
+    trigger->trigger0_count[stage] = trigger0_count;
+    trigger->trigger1_count[stage] = trigger1_count;
+
+    return SR_OK;
+}
+
+/**
+ * set trigger based on probe
+ *
+ * @return SR_OK upon success.
+ */
+SR_API int ds_trigger_probe_set(uint16_t probe, unsigned char trigger0, unsigned char trigger1)
+{
+    assert(probe < TriggerProbes);
+
+    trigger->trigger0[TriggerStages][probe] = trigger0;
+    trigger->trigger1[TriggerStages][probe] = trigger1;
+
+    return SR_OK;
+}
+
+/**
+ * set trigger stage
+ *
+ * @return SR_OK upon success.
+ */
+SR_API int ds_trigger_set_stage(uint16_t stages)
+{
+    assert(stages <= TriggerStages);
+
+    trigger->trigger_stages = stages;
+
+    return SR_OK;
+}
+
+/**
+ * set trigger position
+ *
+ * @return SR_OK upon success.
+ */
+SR_API int ds_trigger_set_pos(uint16_t position)
+{
+    assert(position <= 100);
+    assert(position >= 0);
+
+    trigger->trigger_pos = position;
+
+    return SR_OK;
+}
+
+/**
+ * set trigger en
+ *
+ * @return SR_OK upon success.
+ */
+SR_API int ds_trigger_set_en(uint16_t enable)
+{
+
+    trigger->trigger_en = enable;
+
+    return SR_OK;
+}
+
+/**
+ * set trigger mode
+ *
+ * @return SR_OK upon success.
+ */
+SR_API int ds_trigger_set_mode(uint16_t mode)
+{
+
+    trigger->trigger_mode = mode;
+
+    return SR_OK;
+}
+
+/*
+ *
+ */
+SR_PRIV uint64_t ds_trigger_get_mask0(uint16_t stage)
+{
+    assert(stage <= TriggerStages);
+
+    uint64_t mask = 0;
+    int i;
+
+    for (i = TriggerProbes - 1; i >= 0 ; i--) {
+        mask = (mask << 1);
+        mask += (trigger->trigger0[stage][i] == 'X' | trigger->trigger0[stage][i] == 'C');
+    }
+
+    return mask;
+}
+SR_PRIV uint64_t ds_trigger_get_mask1(uint16_t stage)
+{
+    assert(stage <= TriggerStages);
+
+    uint64_t mask = 0;
+    int i;
+
+    for (i = TriggerProbes - 1; i >= 0 ; i--) {
+        mask = (mask << 1);
+        mask += (trigger->trigger1[stage][i] == 'X' | trigger->trigger1[stage][i] == 'C');
+    }
+
+    return mask;
+}
+SR_PRIV uint64_t ds_trigger_get_value0(uint16_t stage)
+{
+    assert(stage <= TriggerStages);
+
+    uint64_t value = 0;
+    int i;
+
+    for (i = TriggerProbes - 1; i >= 0 ; i--) {
+        value = (value << 1);
+        value += (trigger->trigger0[stage][i] == '1' | trigger->trigger0[stage][i] == 'R');
+    }
+
+    return value;
+}
+SR_PRIV uint64_t ds_trigger_get_value1(uint16_t stage)
+{
+    assert(stage <= TriggerStages);
+
+    uint64_t value = 0;
+    int i;
+
+    for (i = TriggerProbes - 1; i >= 0 ; i--) {
+        value = (value << 1);
+        value += (trigger->trigger1[stage][i] == '1' | trigger->trigger1[stage][i] == 'R');
+    }
+
+    return value;
+}
+SR_PRIV uint64_t ds_trigger_get_edge0(uint16_t stage)
+{
+    assert(stage <= TriggerStages);
+
+    uint64_t edge = 0;
+    int i;
+
+    for (i = TriggerProbes - 1; i >= 0 ; i--) {
+        edge = (edge << 1);
+        edge += (trigger->trigger0[stage][i] == 'R' | trigger->trigger0[stage][i] == 'F' |
+                 trigger->trigger0[stage][i] == 'C');
+    }
+
+    return edge;
+}
+SR_PRIV uint64_t ds_trigger_get_edge1(uint16_t stage)
+{
+    assert(stage <= TriggerStages);
+
+    uint64_t edge = 0;
+    int i;
+
+    for (i = TriggerProbes - 1; i >= 0 ; i--) {
+        edge = (edge << 1);
+        edge += (trigger->trigger1[stage][i] == 'R' | trigger->trigger1[stage][i] == 'F' |
+                 trigger->trigger1[stage][i] == 'C');
+    }
+
+    return edge;
+}
+
+/** @} */