From: Martin Ling Date: Sat, 1 Feb 2014 10:01:05 +0000 (+0000) Subject: Add librevisa SCPI backend. X-Git-Tag: libsigrok-0.3.0~167 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=1fb2312f99a27d552cbd13df7827eb366bcc3122;p=libsigrok.git Add librevisa SCPI backend. --- diff --git a/configure.ac b/configure.ac index df6c0393..0ac2ec23 100644 --- a/configure.ac +++ b/configure.ac @@ -316,6 +316,22 @@ fi # Serial port helper code is only compiled in if libserialport was found. AM_CONDITIONAL(NEED_SERIAL, test "x$have_libserialport" != xno) +PKG_CHECK_MODULES([librevisa], [librevisa >= 0.0.20130812], + [CFLAGS="$CFLAGS $librevisa_CFLAGS"; + LIBS="$LIBS $librevisa_LIBS"; + SR_PKGLIBS="$SR_PKGLIBS librevisa"], []) + +# VISA SCPI backend is only compiled in if librevisa was found. +AM_CONDITIONAL(NEED_VISA, test "x$have_librevisa" != xno) + +# Define HAVE_LIBREVISA in config.h if we found librevisa. +if test "x$have_librevisa" != "xno"; then + AC_DEFINE_UNQUOTED(HAVE_LIBREVISA, [1], + [Specifies whether we have librevisa.]) +fi + +AM_CONDITIONAL(NEED_VISA, test "x$have_librevisa" != xno) + # libusb-1.0 is only needed for some hardware drivers. Disable the respective # drivers if it is not found. case "$host" in @@ -635,7 +651,7 @@ echo "Detected libraries:" echo # Note: This only works for libs with pkg-config integration. -for lib in "glib-2.0 >= 2.32.0" "libzip >= 0.10" "libserialport >= 0.1.0" "libusb-1.0 >= 1.0.16" "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" "librevisa >= 0.0.20130812" "libusb-1.0 >= 1.0.16" "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)" diff --git a/hardware/common/Makefile.am b/hardware/common/Makefile.am index bba80672..cdffe470 100644 --- a/hardware/common/Makefile.am +++ b/hardware/common/Makefile.am @@ -36,6 +36,10 @@ if NEED_USB libsigrok_hw_common_la_SOURCES += ezusb.c usb.c endif +if NEED_VISA +libsigrok_hw_common_la_SOURCES += scpi_visa.c +endif + libsigrok_hw_common_la_LIBADD = dmm/libsigrok_hw_common_dmm.la libsigrok_hw_common_la_CFLAGS = \ diff --git a/hardware/common/scpi.c b/hardware/common/scpi.c index e188946d..fc61855f 100644 --- a/hardware/common/scpi.c +++ b/hardware/common/scpi.c @@ -70,6 +70,7 @@ SR_PRIV extern const struct sr_scpi_dev_inst scpi_tcp_raw_dev; SR_PRIV extern const struct sr_scpi_dev_inst scpi_tcp_rigol_dev; SR_PRIV extern const struct sr_scpi_dev_inst scpi_usbtmc_dev; SR_PRIV extern const struct sr_scpi_dev_inst scpi_vxi_dev; +SR_PRIV extern const struct sr_scpi_dev_inst scpi_visa_dev; static const struct sr_scpi_dev_inst *scpi_devs[] = { &scpi_tcp_raw_dev, @@ -78,6 +79,9 @@ static const struct sr_scpi_dev_inst *scpi_devs[] = { #if HAVE_RPC &scpi_vxi_dev, #endif +#ifdef HAVE_LIBREVISA + &scpi_visa_dev, +#endif #ifdef HAVE_LIBSERIALPORT &scpi_serial_dev, /* must be last as it matches any resource */ #endif diff --git a/hardware/common/scpi_visa.c b/hardware/common/scpi_visa.c new file mode 100644 index 00000000..07d4b9a0 --- /dev/null +++ b/hardware/common/scpi_visa.c @@ -0,0 +1,175 @@ +/* + * This file is part of the libsigrok project. + * + * Copyright (C) 2013 Martin Ling + * + * 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 . + */ + +#include "libsigrok.h" +#include "libsigrok-internal.h" + +#include +#include + +#define LOG_PREFIX "scpi_visa" + +struct scpi_visa { + char *resource; + ViSession rmgr; + ViSession vi; +}; + +static int scpi_visa_dev_inst_new(void *priv, const char *resource, + char **params, const char *serialcomm) +{ + struct scpi_visa *vscpi = priv; + + (void)resource; + (void)serialcomm; + + if (!params || !params[1]) { + sr_err("Invalid parameters."); + return SR_ERR; + } + + vscpi->resource = g_strdup(params[1]); + + return SR_OK; +} + +static int scpi_visa_open(void *priv) +{ + struct scpi_visa *vscpi = priv; + + if (viOpenDefaultRM(&vscpi->rmgr) != VI_SUCCESS) { + sr_err("Cannot open default resource manager."); + return SR_ERR; + } + + if (viOpen(vscpi->rmgr, vscpi->resource, VI_NO_LOCK, 0, &vscpi->vi) != VI_SUCCESS) + { + sr_err("Cannot open resource."); + return SR_ERR; + } + + return SR_OK; +} + +static int scpi_visa_source_add(void *priv, int events, int timeout, + sr_receive_data_callback_t cb, void *cb_data) +{ + (void) priv; + + /* Hook up a dummy handler to receive data from the device. */ + return sr_source_add(-1, events, timeout, cb, cb_data); +} + +static int scpi_visa_source_remove(void *priv) +{ + (void) priv; + + return sr_source_remove(-1);; +} + +static int scpi_visa_send(void *priv, const char *command) +{ + struct scpi_visa *vscpi = priv; + gchar *terminated_command; + ViUInt32 written; + int len; + + terminated_command = g_strconcat(command, "\n", NULL); + len = strlen(terminated_command); + if (viWrite(vscpi->vi, (ViBuf) (terminated_command + written), len, + &written) != VI_SUCCESS) { + sr_err("Error while sending SCPI command: '%s'.", command); + g_free(terminated_command); + return SR_ERR; + } + + g_free(terminated_command); + + sr_spew("Successfully sent SCPI command: '%s'.", command); + + return SR_OK; +} + +static int scpi_visa_read_begin(void *priv) +{ + (void) priv; + + return SR_OK; +} + +static int scpi_visa_read_data(void *priv, char *buf, int maxlen) +{ + struct scpi_visa *vscpi = priv; + ViUInt32 count; + + if (viRead(vscpi->vi, (ViBuf) buf, maxlen, &count) != VI_SUCCESS) + { + sr_err("Read failed"); + return SR_ERR; + } + + return count; +} + +static int scpi_visa_read_complete(void *priv) +{ + struct scpi_visa *vscpi = priv; + ViUInt16 status; + + if (viReadSTB(vscpi->vi, &status) != VI_SUCCESS) { + sr_err("Failed to read status"); + return SR_ERR; + } + + return !(status & 16); +} + +static int scpi_visa_close(void *priv) +{ + struct scpi_visa *vscpi = priv; + + viClose(vscpi->vi); + viClose(vscpi->rmgr); + + return SR_OK; +} + +static void scpi_visa_free(void *priv) +{ + struct scpi_visa *vscpi = priv; + + g_free(vscpi->resource); + g_free(vscpi); +} + +SR_PRIV const struct sr_scpi_dev_inst scpi_visa_dev = { + .name = "VISA", + .prefix = "visa", + .priv_size = sizeof(struct scpi_visa), + .dev_inst_new = scpi_visa_dev_inst_new, + .open = scpi_visa_open, + .source_add = scpi_visa_source_add, + .source_remove = scpi_visa_source_remove, + .send = scpi_visa_send, + .read_begin = scpi_visa_read_begin, + .read_data = scpi_visa_read_data, + .read_complete = scpi_visa_read_complete, + .close = scpi_visa_close, + .free = scpi_visa_free, +};