##
-## 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>
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 \
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
-------------------------------------------------------------------------------
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
- 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
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
-------
http://sigrok.org/wiki/Libsigrok
+ http://dreamsourcelab.com
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])
# 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"
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().
[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
[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
;;
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],
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
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
])
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)"
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
}
/** @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;
}
sdi->driver = NULL;
+ sdi->mode = mode;
sdi->index = index;
sdi->status = status;
sdi->inst_type = -1;
}
/** @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;
##
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
-
## 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
#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. */
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[] = {
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. */
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)
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);
}
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;
}
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;
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;
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;
(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;
}
{
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
/* 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();
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",
.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,
"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},
};
/** @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,
};
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);
}
/** @} */
##
# 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)
--- /dev/null
+/*
+ * 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,
+};
--- /dev/null
+/*
+ * 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,
+};
--- /dev/null
+/*
+ * 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,
+};
+
*/
/** @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;
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,
/*--- 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
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 -------------------------------------------------------------*/
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 {
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
#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
};
#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)
#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 {
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;
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;
/** 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,
/** 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. */
/** Device options for a particular device. */
SR_CONF_DEVICE_OPTIONS,
+ SR_CONF_DEVICE_CONFIGS,
/** Session filename. */
SR_CONF_SESSIONFILE,
int index;
int status;
int inst_type;
+ int mode;
char *vendor;
char *model;
char *version;
/* 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,
* 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"
--- /dev/null
+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}
+
--- /dev/null
+/*
+ * 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;
+}
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
--- /dev/null
+/*
+ * 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
+};
--- /dev/null
+/*
+ * 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,
+};
--- /dev/null
+/*
+ * 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,
+};
--- /dev/null
+/*
+ * 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,
+};
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; */
&output_text_ascii,
&output_binary,
&output_vcd,
- &output_ols,
- &output_gnuplot,
- &output_chronovu_la8,
&output_csv,
&output_analog,
/* &output_analog_gnuplot, */
##
# 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)
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);
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
session->source_timeout = -1;
session->abort_session = FALSE;
- g_mutex_init(&session->stop_mutex);
+// g_mutex_init(&session->stop_mutex);
return session;
}
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;
* 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);
}
}
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);
}
}
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;
}
* 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;
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;
* 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);
}
/**
* 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);
}
/**
* 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;
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);
}
/**
struct zip_file *capfile;
int bytes_read;
uint64_t samplerate;
+ uint64_t total_samples;
int unitsize;
int num_probes;
};
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;
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);
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);
}
} 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;
}
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;
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;
}
/* 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;
}
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;
}
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;
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 */
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,
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__);
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;
}
/** @} */
check_main_CFLAGS = @check_CFLAGS@
-check_main_LDADD = $(top_builddir)/libsigrok.la @check_LIBS@
+check_main_LDADD = $(top_builddir)/libsigrok4DSLogic.la @check_LIBS@
endif
--- /dev/null
+/*
+ * 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;
+}
+
+/** @} */