diff --git a/configure.ac b/configure.ac index 3385596f..72a31b89 100644 --- a/configure.ac +++ b/configure.ac @@ -150,15 +150,6 @@ if test "x$LA_FX2LAFW" = "xyes"; then AC_DEFINE(HAVE_LA_FX2LAFW, 1, [fx2lafw support]) fi -AC_ARG_ENABLE(genericdmm, AC_HELP_STRING([--enable-genericdmm], - [enable genericdmm support (for most DMMs) [default=yes]]), - [HW_GENERICDMM="$enableval"], - [HW_GENERICDMM=yes]) -AM_CONDITIONAL(HW_GENERICDMM, test x$HW_GENERICDMM = xyes) -if test "x$HW_GENERICDMM" = "xyes"; then - AC_DEFINE(HAVE_HW_GENERICDMM, 1, [Generic DMM support]) -fi - AC_ARG_ENABLE(hantek-dso, AC_HELP_STRING([--enable-hantek-dso], [enable Hantek DSO support [default=yes]]), [HW_HANTEK_DSO="$enableval"], @@ -319,7 +310,6 @@ AM_CONDITIONAL(NEED_EZUSB, \ AM_CONDITIONAL(NEED_SERIAL, \ test "x$LA_OLS" != xno \ -o "x$HW_AGILENT_DMM" != xno \ - -o "x$HW_GENERICDMM" != xno \ ) AC_SUBST(SR_PKGLIBS) @@ -370,7 +360,6 @@ AC_CONFIG_FILES([Makefile version.h hardware/Makefile hardware/demo/Makefile hardware/fluke-dmm/Makefile hardware/fx2lafw/Makefile - hardware/genericdmm/Makefile hardware/hantek-dso/Makefile hardware/link-mso19/Makefile hardware/openbench-logic-sniffer/Makefile @@ -416,7 +405,6 @@ echo " - Colead SLM...................... $HW_COLEAD_SLM" echo " - Demo driver..................... $LA_DEMO" echo " - Fluke DMM....................... $HW_FLUKE_DMM" echo " - fx2lafw (for FX2 LAs)........... $LA_FX2LAFW" -echo " - Generic DMM..................... $HW_GENERICDMM" echo " - Hantek DSO...................... $HW_HANTEK_DSO" echo " - Link MSO-19..................... $LA_LINK_MSO19" echo " - Openbench Logic Sniffer......... $LA_OLS" diff --git a/hardware/Makefile.am b/hardware/Makefile.am index cba3ac81..89da7bb0 100644 --- a/hardware/Makefile.am +++ b/hardware/Makefile.am @@ -28,7 +28,6 @@ SUBDIRS = \ demo \ fluke-dmm \ fx2lafw \ - genericdmm \ hantek-dso \ link-mso19 \ openbench-logic-sniffer \ @@ -78,10 +77,6 @@ if LA_FX2LAFW libsigrokhardware_la_LIBADD += fx2lafw/libsigrokhwfx2lafw.la endif -if HW_GENERICDMM -libsigrokhardware_la_LIBADD += genericdmm/libsigrokhwgenericdmm.la -endif - if HW_HANTEK_DSO libsigrokhardware_la_LIBADD += hantek-dso/libsigrokhw_hantek_dso.la endif diff --git a/hardware/genericdmm/Makefile.am b/hardware/genericdmm/Makefile.am deleted file mode 100644 index 2c86a534..00000000 --- a/hardware/genericdmm/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## -## This file is part of the sigrok project. -## -## Copyright (C) 2012 Bert Vermeulen -## -## 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 . -## - -if HW_GENERICDMM - -# Local lib, this is NOT meant to be installed! -noinst_LTLIBRARIES = libsigrokhwgenericdmm.la - -libsigrokhwgenericdmm_la_SOURCES = \ - api.c \ - victor-70c.c \ - genericdmm.h - -libsigrokhwgenericdmm_la_CFLAGS = \ - -I$(top_srcdir) - -endif diff --git a/hardware/genericdmm/api.c b/hardware/genericdmm/api.c deleted file mode 100644 index 9a86ff01..00000000 --- a/hardware/genericdmm/api.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * This file is part of the sigrok project. - * - * Copyright (C) 2012 Uwe Hermann - * Copyright (C) 2012 Bert Vermeulen - * - * 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 -#include -#include -#include "libsigrok.h" -#include "libsigrok-internal.h" -#include "genericdmm.h" - -extern SR_PRIV struct dmmchip dmmchip_victor70c; - -static struct sr_hwopt victor_70c_vidpid[] = { - { SR_HWOPT_CONN, "1244.d237" }, - { 0, NULL } -}; -static struct dev_profile dev_profiles[] = { - { "victor-70c", "Victor", "70C", &dmmchip_victor70c, - DMM_TRANSPORT_USBHID, 1000, victor_70c_vidpid - }, - { NULL, NULL, NULL, NULL, 0, 0, NULL } -}; - -static const int hwopts[] = { - SR_HWOPT_MODEL, - SR_HWOPT_CONN, - SR_HWOPT_SERIALCOMM, - 0, -}; - -static const int hwcaps[] = { - SR_HWCAP_MULTIMETER, - SR_HWCAP_LIMIT_SAMPLES, - SR_HWCAP_LIMIT_MSEC, - SR_HWCAP_CONTINUOUS, - 0, -}; - -static const char *probe_names[] = { - "Probe", - NULL, -}; - -SR_PRIV struct sr_dev_driver genericdmm_driver_info; -static struct sr_dev_driver *gdi = &genericdmm_driver_info; -/* TODO need a way to keep this local to the static library */ -static libusb_context *genericdmm_usb_context = NULL; -static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data); - -static GSList *connect_serial(const char *conn, const char *serialcomm) -{ - GSList *devices; - - devices = NULL; - - /* TODO */ - sr_dbg("Not yet implemented."); - - return devices; -} - -GSList *genericdmm_connect(const char *conn, const char *serialcomm) -{ - GSList *devices, *l; - struct sr_dev_inst *sdi; - struct dev_context *devc; - struct drv_context *drvc; - struct sr_probe *probe; - struct libusb_device *ldev; - int i, devcnt; - - drvc = gdi->priv; - - devices = NULL; - - if (serialcomm) - /* Must be a serial port. */ - return connect_serial(conn, serialcomm); - - if (!(l = sr_usb_connect(genericdmm_usb_context, conn))) { - return NULL; - } - - for (i = 0; i < (int)g_slist_length(l); i++) { - ldev = (struct libusb_device *)l->data; - - if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) { - sr_err("Device context malloc failed."); - return NULL; - } - - devcnt = g_slist_length(drvc->instances); - if (!(sdi = sr_dev_inst_new(devcnt, SR_ST_INACTIVE, - NULL, NULL, NULL))) { - sr_err("sr_dev_inst_new returned NULL."); - return NULL; - } - sdi->priv = devc; - if (!(probe = sr_probe_new(0, SR_PROBE_ANALOG, TRUE, "P1"))) - return NULL; - sdi->probes = g_slist_append(sdi->probes, probe); - devc->usb = sr_usb_dev_inst_new( - libusb_get_bus_number(ldev), - libusb_get_device_address(ldev), NULL); - devices = g_slist_append(devices, sdi); - - return devices; - } - - return NULL; -} - -static GSList *default_scan(GSList *options) -{ - GSList *l, *devices; - struct sr_hwopt *opt; - const char *conn, *serialcomm; - - devices = NULL; - conn = serialcomm = NULL; - for (l = options; l; l = l->next) { - opt = l->data; - switch (opt->hwopt) { - case SR_HWOPT_CONN: - conn = opt->value; - break; - case SR_HWOPT_SERIALCOMM: - serialcomm = opt->value; - break; - } - } - if (conn) - devices = genericdmm_connect(conn, serialcomm); - - return devices; -} - -static int clear_instances(void) -{ - GSList *l; - struct sr_dev_inst *sdi; - struct dev_context *devc; - struct drv_context *drvc; - - if (!(drvc = gdi->priv)) - return SR_OK; - - /* Properly close and free all devices. */ - for (l = drvc->instances; l; l = l->next) { - if (!(sdi = l->data)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("sdi was NULL, continuing."); - continue; - } - if (!(devc = sdi->priv)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("sdi->priv was NULL, continuing."); - continue; - } - - if (devc->profile) { - switch (devc->profile->transport) { - case DMM_TRANSPORT_USBHID: - sr_usb_dev_inst_free(devc->usb); - break; - case DMM_TRANSPORT_SERIAL: - if (devc->serial && devc->serial->fd != -1) - serial_close(devc->serial->fd); - sr_serial_dev_inst_free(devc->serial); - break; - } - } - - sr_dev_inst_free(sdi); - } - - g_slist_free(drvc->instances); - drvc->instances = NULL; - - return SR_OK; -} - -static int hw_init(void) -{ - struct drv_context *drvc; - - if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) { - sr_err("Driver context malloc failed."); - return SR_ERR_MALLOC; - } - - if (libusb_init(&genericdmm_usb_context) != 0) { - sr_err("Failed to initialize USB."); - return SR_ERR; - } - - gdi->priv = drvc; - - return SR_OK; -} - -static GSList *hw_scan(GSList *options) -{ - GSList *l, *ldef, *defopts, *newopts, *devices; - struct sr_hwopt *opt, *defopt; - struct dev_profile *pr, *profile; - struct sr_dev_inst *sdi; - struct drv_context *drvc; - struct dev_context *devc; - const char *model; - - drvc = gdi->priv; - - /* Separate model from the options list. */ - model = NULL; - newopts = NULL; - for (l = options; l; l = l->next) { - opt = l->data; - if (opt->hwopt == SR_HWOPT_MODEL) - model = opt->value; - else - /* New list with references to the original data. */ - newopts = g_slist_append(newopts, opt); - } - if (!model) { - /* This driver only works when a model is specified. */ - return NULL; - } - - /* Find a profile with this model name. */ - profile = NULL; - for (pr = dev_profiles; pr->modelid; pr++) { - if (!strcmp(pr->modelid, model)) { - profile = pr; - break; - } - } - if (!profile) { - sr_err("Unknown model %s.", model); - return NULL; - } - - /* Initialize the DMM chip driver. */ - if (profile->chip->init) - profile->chip->init(); - - /* Convert the profile's default options list to a GSList. */ - defopts = NULL; - for (opt = profile->defaults_opts; opt->hwopt; opt++) { - /* New list with references to const data in the profile. */ - defopts = g_slist_append(defopts, opt); - } - - /* Options given as argument to this function override the - * profile's default options. - */ - for (ldef = defopts; ldef; ldef = ldef->next) { - defopt = ldef->data; - for (l = newopts; l; l = l->next) { - opt = l->data; - if (opt->hwopt == defopt->hwopt) { - /* Override the default, and drop it from the - * options list. - */ - ldef->data = l->data; - newopts = g_slist_remove(newopts, opt); - break; - } - } - } - /* Whatever is left in newopts wasn't in the default options. */ - defopts = g_slist_concat(defopts, newopts); - g_slist_free(newopts); - - if (profile->chip->scan) - /* The DMM chip driver wants to do its own scanning. */ - devices = profile->chip->scan(defopts); - else - devices = default_scan(defopts); - g_slist_free(defopts); - - if (devices) { - /* TODO: need to fix up sdi->index fields */ - for (l = devices; l; l = l->next) { - /* The default connection-based scanner doesn't really - * know about profiles, so it never filled in the vendor - * or model. Do that now. - */ - sdi = l->data; - devc = sdi->priv; - devc->profile = profile; - sdi->driver = gdi; - if (!sdi->vendor) - sdi->vendor = g_strdup(profile->vendor); - if (!sdi->model) - sdi->model = g_strdup(profile->model); - /* Add a copy of these new devices to the driver instances. */ - drvc->instances = g_slist_append(drvc->instances, l->data); - } - } - - return devices; -} - -static GSList *hw_dev_list(void) -{ - struct drv_context *drvc; - - drvc = gdi->priv; - - return drvc->instances; -} - -static int hw_dev_open(struct sr_dev_inst *sdi) -{ - struct dev_context *devc; - int ret; - - if (!(devc = sdi->priv)) { - sr_err("sdi->priv was NULL."); - return SR_ERR_BUG; - } - - ret = SR_OK; - switch (devc->profile->transport) { - case DMM_TRANSPORT_USBHID: - if (sdi->status == SR_ST_ACTIVE) { - sr_err("Device already in use."); - ret = SR_ERR; - } else { - ret = sr_usb_open(genericdmm_usb_context, devc->usb); - } - break; - case DMM_TRANSPORT_SERIAL: - sr_dbg("Opening serial port '%s'.", devc->serial->port); - devc->serial->fd = serial_open(devc->serial->port, O_RDWR | O_NONBLOCK); - if (devc->serial->fd == -1) { - sr_err("Couldn't open serial port '%s'.", - devc->serial->port); - ret = SR_ERR; - } - // serial_set_params(devc->serial->fd, 2400, 8, 0, 1, 2); - break; - default: - sr_err("No transport set."); - ret = SR_ERR; - } - - return ret; -} - -static int hw_dev_close(struct sr_dev_inst *sdi) -{ - struct dev_context *devc; - - if (!(devc = sdi->priv)) { - sr_err("%s: sdi->priv was NULL.", __func__); - return SR_ERR_BUG; - } - - switch (devc->profile->transport) { - case DMM_TRANSPORT_USBHID: - /* TODO */ - break; - case DMM_TRANSPORT_SERIAL: - if (devc->serial && devc->serial->fd != -1) { - serial_close(devc->serial->fd); - devc->serial->fd = -1; - sdi->status = SR_ST_INACTIVE; - } - break; - } - - return SR_OK; -} - -static int hw_cleanup(void) -{ - - clear_instances(); - - if (genericdmm_usb_context) - libusb_exit(genericdmm_usb_context); - - return SR_OK; -} - -static int hw_info_get(int info_id, const void **data, - const struct sr_dev_inst *sdi) -{ - struct dev_context *devc; - - (void)sdi; - (void)devc; - - switch (info_id) { - case SR_DI_HWOPTS: - *data = hwopts; - break; - case SR_DI_HWCAPS: - *data = hwcaps; - break; - case SR_DI_NUM_PROBES: - *data = GINT_TO_POINTER(1); - break; - case SR_DI_PROBE_NAMES: - *data = probe_names; - break; - case SR_DI_CUR_SAMPLERATE: - /* TODO get rid of this */ - *data = NULL; - return SR_ERR_ARG; - break; - default: - /* Unknown device info ID. */ - return SR_ERR_ARG; - } - - return SR_OK; -} - -static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap, - const void *value) -{ - struct dev_context *devc; - - if (!(devc = sdi->priv)) { - sr_err("sdi->priv was NULL."); - return SR_ERR_BUG; - } - - switch (hwcap) { - case SR_HWCAP_LIMIT_MSEC: - /* TODO: not yet implemented */ - if (*(const uint64_t *)value == 0) { - sr_err("LIMIT_MSEC can't be 0."); - return SR_ERR; - } - devc->limit_msec = *(const uint64_t *)value; - sr_dbg("Setting time limit to %" PRIu64 "ms.", - devc->limit_msec); - break; - case SR_HWCAP_LIMIT_SAMPLES: - devc->limit_samples = *(const uint64_t *)value; - sr_dbg("Setting sample limit to %" PRIu64 ".", - devc->limit_samples); - break; - default: - sr_err("Unknown capability: %d.", hwcap); - return SR_ERR; - break; - } - - return SR_OK; -} - -static int receive_data(int fd, int revents, void *cb_data) -{ - struct sr_dev_inst *sdi; - struct dev_context *devc; - - (void)revents; - - if (!(sdi = cb_data)) - return TRUE; - - if (!(devc = sdi->priv)) - return TRUE; - - switch (devc->profile->transport) { - case DMM_TRANSPORT_USBHID: - if (devc->profile->chip->data) - devc->profile->chip->data(sdi); - break; - case DMM_TRANSPORT_SERIAL: - /* TODO */ - fd = fd; - break; - } - - if (devc->num_samples >= devc->limit_samples) - hw_dev_acquisition_stop(sdi, cb_data); - - return TRUE; -} - -static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, - void *cb_data) -{ - struct sr_datafeed_packet packet; - struct sr_datafeed_header header; - struct sr_datafeed_meta_analog meta; - struct dev_context *devc; - - if (!(devc = sdi->priv)) { - sr_err("sdi->priv was NULL."); - return SR_ERR_BUG; - } - - sr_dbg("Starting acquisition."); - - devc->cb_data = cb_data; - - /* Send header packet to the session bus. */ - sr_dbg("Sending SR_DF_HEADER."); - packet.type = SR_DF_HEADER; - packet.payload = (uint8_t *)&header; - header.feed_version = 1; - gettimeofday(&header.starttime, NULL); - sr_session_send(devc->cb_data, &packet); - - /* Send metadata about the SR_DF_ANALOG packets to come. */ - sr_dbg("Sending SR_DF_META_ANALOG."); - packet.type = SR_DF_META_ANALOG; - packet.payload = &meta; - meta.num_probes = 1; - sr_session_send(devc->cb_data, &packet); - - /* Hook up a proxy handler to receive data from the device. */ - switch (devc->profile->transport) { - case DMM_TRANSPORT_USBHID: - /* Callously using stdin here. This works because no G_IO_* flags - * are set, but will certainly break when any other driver does - * this, and runs at the same time as genericdmm. - * We'll need a timeout-only source when revamping the whole - * driver source system. - */ - sr_source_add(0, 0, devc->profile->poll_timeout, - receive_data, (void *)sdi); - break; - case DMM_TRANSPORT_SERIAL: - /* TODO serial FD setup */ - // sr_source_add(devc->serial->fd, G_IO_IN, -1, receive_data, sdi); - break; - } - - return SR_OK; -} - -static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) -{ - struct sr_datafeed_packet packet; - - (void)sdi; - - sr_dbg("Stopping acquisition."); - - /* Send end packet to the session bus. */ - sr_dbg("Sending SR_DF_END."); - packet.type = SR_DF_END; - sr_session_send(cb_data, &packet); - - sr_source_remove(0); - - return SR_OK; -} - -SR_PRIV struct sr_dev_driver genericdmm_driver_info = { - .name = "genericdmm", - .longname = "Generic DMM", - .api_version = 1, - .init = hw_init, - .cleanup = hw_cleanup, - .scan = hw_scan, - .dev_list = hw_dev_list, - .dev_clear = clear_instances, - .dev_open = hw_dev_open, - .dev_close = hw_dev_close, - .info_get = hw_info_get, - .dev_config_set = hw_dev_config_set, - .dev_acquisition_start = hw_dev_acquisition_start, - .dev_acquisition_stop = hw_dev_acquisition_stop, - .priv = NULL, -}; diff --git a/hardware/genericdmm/genericdmm.h b/hardware/genericdmm/genericdmm.h deleted file mode 100644 index 7a023089..00000000 --- a/hardware/genericdmm/genericdmm.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the sigrok project. - * - * Copyright (C) 2012 Bert Vermeulen - * - * 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 . - */ - -#ifndef LIBSIGROK_GENERICDMM_H -#define LIBSIGROK_GENERICDMM_H - -/* Message logging helpers with driver-specific prefix string. */ -#define DRIVER_LOG_DOMAIN "genericdmm: " -#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args) -#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args) -#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args) -#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args) -#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args) -#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args) - -/* SR_HWCAP_CONN takes one of these: */ -#define DMM_CONN_USB_VIDPID "^([0-9a-z]{1,4})\\.([0-9a-z]{1,4})$" -#define DMM_CONN_USB_BUSADDR "^(\\d+)\\.(\\d+)$" -#define DMM_CONN_SERIALPORT "^([a-z0-9/\\-_]+)$" - -/* SR_HWCAP_SERIALCOMM like 2400/8n1 */ -#define DMM_CONN_SERIALCOMM "^(\\d+)/(\\d)([neo])(\\d)$" - -enum { - DMM_TRANSPORT_SERIAL, - DMM_TRANSPORT_USBHID, -}; - - -struct dev_profile { - char *modelid; - char *vendor; - char *model; - struct dmmchip *chip; - int transport; - int poll_timeout; - struct sr_hwopt *defaults_opts; -}; - -/* Private, per-device-instance driver context. */ -struct dev_context { - struct dev_profile *profile; - uint64_t limit_samples; - uint64_t limit_msec; - - /* Opaque pointer passed in by the frontend. */ - void *cb_data; - - /* Only used for USB-connected devices. */ - struct sr_usb_dev_inst *usb; - - /* Only used for serial-connected devices. */ - struct sr_serial_dev_inst *serial; - int serial_speed; - int serial_databits; - int serial_parity; - int serial_stopbits; - - /* Runtime. */ - uint64_t num_samples; - - /* DMM chip-specific data, if needed. */ - void *priv; -}; - -struct dmmchip { - /* Optional, called once before measurement starts. */ - int (*init) (void); - - /* Scan for devices with the given options. */ - GSList *(*scan) (GSList *options); - - /* Called whenever a chunk of data arrives. */ - int (*data) (struct sr_dev_inst *sdi); -}; - - -#endif /* LIBSIGROK_GENERICDMM_H */ diff --git a/hardware/genericdmm/victor-70c.c b/hardware/genericdmm/victor-70c.c deleted file mode 100644 index a180a023..00000000 --- a/hardware/genericdmm/victor-70c.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - * This file is part of the sigrok project. - * - * Copyright (C) 2012 Bert Vermeulen - * - * 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 "genericdmm.h" -#include -#include -#include - -/* Message logging helpers with driver-specific prefix string. */ -#define DRIVER_LOG_DOMAIN "victor-dmm: " -#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args) -#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args) -#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args) -#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args) -#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args) -#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args) - -#define DMM_DATA_SIZE 14 - -/* Reverse the high nibble into the low nibble */ -static uint8_t decode_digit(uint8_t in) -{ - uint8_t out, i; - - out = 0; - in >>= 4; - for (i = 0x08; i; i >>= 1) { - out >>= 1; - if (in & i) - out |= 0x08; - } - - return out; -} - -static void decode_buf(struct dev_context *devc, unsigned char *data) -{ - struct sr_datafeed_packet packet; - struct sr_datafeed_analog analog; - long factor, ivalue; - uint8_t digits[4]; - gboolean is_duty, is_continuity, is_diode, is_ac, is_dc, is_auto; - gboolean is_hold, is_max, is_min, is_relative, minus; - float fvalue; - - digits[0] = decode_digit(data[12]); - digits[1] = decode_digit(data[11]); - digits[2] = decode_digit(data[10]); - digits[3] = decode_digit(data[9]); - - if (digits[0] == 0x0f && digits[1] == 0x00 && digits[2] == 0x0a && - digits[3] == 0x0f) - /* The "over limit" (OL) display comes through like this */ - ivalue = -1; - else if (digits[0] > 9 || digits[1] > 9 || digits[2] > 9 || digits[3] > 9) - /* An invalid digit in any position denotes no value. */ - ivalue = -2; - else { - ivalue = digits[0] * 1000; - ivalue += digits[1] * 100; - ivalue += digits[2] * 10; - ivalue += digits[3]; - } - - /* Decimal point position */ - switch (data[7] >> 4) { - case 0x00: - factor = 0; - break; - case 0x02: - factor = 1; - break; - case 0x04: - factor = 2; - break; - case 0x08: - factor = 3; - break; - default: - sr_err("Unknown decimal point value %.2x.", data[7]); - } - - /* Minus flag */ - minus = data[2] & 0x01; - - /* Mode detail symbols on the right side of the digits */ - is_duty = is_continuity = is_diode = FALSE; - switch (data[4]) { - case 0x00: - /* None. */ - break; - case 0x01: - /* Micro */ - factor += 6; - break; - case 0x02: - /* Milli */ - factor += 3; - break; - case 0x04: - /* Kilo */ - ivalue *= 1000; - break; - case 0x08: - /* Mega */ - ivalue *= 1000000; - break; - case 0x10: - /* Continuity shows up as Ohm + this bit */ - is_continuity = TRUE; - break; - case 0x20: - /* Diode tester is Volt + this bit */ - is_diode = TRUE; - break; - case 0x40: - is_duty = TRUE; - break; - case 0x80: - /* Never seen */ - sr_dbg("Unknown mode right detail %.2x.", data[4]); - break; - default: - sr_dbg("Unknown/invalid mode right detail %.2x.", data[4]); - } - - /* Scale flags on the right, continued */ - is_max = is_min = TRUE; - if (data[5] & 0x04) - is_max = TRUE; - if (data[5] & 0x08) - is_min = TRUE; - if (data[5] & 0x40) - /* Nano */ - factor += 9; - - /* Mode detail symbols on the left side of the digits */ - is_auto = is_dc = is_ac = is_hold = is_relative = FALSE; - if (data[6] & 0x04) - is_auto = TRUE; - if (data[6] & 0x08) - is_dc = TRUE; - if (data[6] & 0x10) - is_ac = TRUE; - if (data[6] & 0x20) - is_relative = TRUE; - if (data[6] & 0x40) - is_hold = TRUE; - - fvalue = (float)ivalue / pow(10, factor); - if (minus) - fvalue = -fvalue; - - memset(&analog, 0, sizeof(struct sr_datafeed_analog)); - - /* Measurement mode */ - analog.mq = -1; - switch (data[3]) { - case 0x00: - if (is_duty) { - analog.mq = SR_MQ_DUTY_CYCLE; - analog.unit = SR_UNIT_PERCENTAGE; - } else - sr_dbg("Unknown measurement mode %.2x.", data[3]); - break; - case 0x01: - if (is_diode) { - analog.mq = SR_MQ_VOLTAGE; - analog.unit = SR_UNIT_VOLT; - analog.mqflags |= SR_MQFLAG_DIODE; - if (ivalue < 0) - fvalue = NAN; - } else { - if (ivalue < 0) - break; - analog.mq = SR_MQ_VOLTAGE; - analog.unit = SR_UNIT_VOLT; - if (is_ac) - analog.mqflags |= SR_MQFLAG_AC; - if (is_dc) - analog.mqflags |= SR_MQFLAG_DC; - } - break; - case 0x02: - analog.mq = SR_MQ_CURRENT; - analog.unit = SR_UNIT_AMPERE; - if (is_ac) - analog.mqflags |= SR_MQFLAG_AC; - if (is_dc) - analog.mqflags |= SR_MQFLAG_DC; - break; - case 0x04: - if (is_continuity) { - analog.mq = SR_MQ_CONTINUITY; - analog.unit = SR_UNIT_BOOLEAN; - fvalue = ivalue < 0 ? 0.0 : 1.0; - } else { - analog.mq = SR_MQ_RESISTANCE; - analog.unit = SR_UNIT_OHM; - if (ivalue < 0) - fvalue = INFINITY; - } - break; - case 0x08: - /* Never seen */ - sr_dbg("Unknown measurement mode %.2x.", data[3]); - break; - case 0x10: - analog.mq = SR_MQ_FREQUENCY; - analog.unit = SR_UNIT_HERTZ; - break; - case 0x20: - analog.mq = SR_MQ_CAPACITANCE; - analog.unit = SR_UNIT_FARAD; - break; - case 0x40: - analog.mq = SR_MQ_TEMPERATURE; - analog.unit = SR_UNIT_CELSIUS; - break; - case 0x80: - analog.mq = SR_MQ_TEMPERATURE; - analog.unit = SR_UNIT_FAHRENHEIT; - break; - default: - sr_dbg("Unknown/invalid measurement mode %.2x.", data[3]); - } - if (analog.mq == -1) - return; - - if (is_auto) - analog.mqflags |= SR_MQFLAG_AUTORANGE; - if (is_hold) - analog.mqflags |= SR_MQFLAG_HOLD; - if (is_max) - analog.mqflags |= SR_MQFLAG_MAX; - if (is_min) - analog.mqflags |= SR_MQFLAG_MIN; - if (is_relative) - analog.mqflags |= SR_MQFLAG_RELATIVE; - - analog.num_samples = 1; - analog.data = &fvalue; - packet.type = SR_DF_ANALOG; - packet.payload = &analog; - sr_session_send(devc->cb_data, &packet); - - devc->num_samples++; -} - -static int victor70c_data(struct sr_dev_inst *sdi) -{ - struct dev_context *devc; - GString *dbg; - int len, ret, i; - unsigned char buf[DMM_DATA_SIZE], data[DMM_DATA_SIZE]; - unsigned char obfuscation[DMM_DATA_SIZE] = "jodenxunickxia"; - unsigned char shuffle[DMM_DATA_SIZE] = { - 6, 13, 5, 11, 2, 7, 9, 8, 3, 10, 12, 0, 4, 1 - }; - - devc = sdi->priv; - - if (sdi->status == SR_ST_INACTIVE) { - /* First time through. */ - if (libusb_kernel_driver_active(devc->usb->devhdl, 0) == 1) { - if (libusb_detach_kernel_driver(devc->usb->devhdl, 0) < 0) { - sr_err("Failed to detach kernel driver."); - return SR_ERR; - } - } - - if (libusb_claim_interface(devc->usb->devhdl, 0)) { - sr_err("Failed to claim interface 0."); - return SR_ERR; - } - sdi->status = SR_ST_ACTIVE; - } - - ret = libusb_interrupt_transfer(devc->usb->devhdl, 0x81, buf, DMM_DATA_SIZE, - &len, 100); - if (ret != 0) { - sr_err("Failed to get data: libusb error %d.", ret); - return SR_ERR; - } - - if (len != DMM_DATA_SIZE) { - sr_dbg("Short packet: received %d/%d bytes.", - len, DMM_DATA_SIZE); - return SR_ERR; - } - - for (i = 0; i < DMM_DATA_SIZE && buf[i] == 0; i++); - if (i == DMM_DATA_SIZE) { - /* This DMM outputs all zeroes from time to time, just ignore it. */ - sr_dbg("Received all zeroes."); - return SR_OK; - } - - /* Deobfuscate and reorder data. */ - for (i = 0; i < DMM_DATA_SIZE; i++) - data[shuffle[i]] = (buf[i] - obfuscation[i]) & 0xff; - - if (sr_log_loglevel_get() >= SR_LOG_SPEW) { - dbg = g_string_sized_new(128); - g_string_printf(dbg, "Deobfuscated."); - for (i = 0; i < DMM_DATA_SIZE; i++) - g_string_append_printf(dbg, " %.2x", data[i]); - sr_spew("%s", dbg->str); - g_string_free(dbg, TRUE); - } - - decode_buf(devc, data); - - return SR_OK; -} - -SR_PRIV struct dmmchip dmmchip_victor70c = { - .data = victor70c_data, -}; diff --git a/hwdriver.c b/hwdriver.c index fdb96585..f5002295 100644 --- a/hwdriver.c +++ b/hwdriver.c @@ -104,9 +104,6 @@ extern SR_PRIV struct sr_dev_driver fx2lafw_driver_info; #ifdef HAVE_HW_HANTEK_DSO extern SR_PRIV struct sr_dev_driver hantek_dso_driver_info; #endif -#ifdef HAVE_HW_GENERICDMM -extern SR_PRIV struct sr_dev_driver genericdmm_driver_info; -#endif #ifdef HAVE_HW_AGILENT_DMM extern SR_PRIV struct sr_dev_driver agdmm_driver_info; #endif @@ -162,9 +159,6 @@ static struct sr_dev_driver *drivers_list[] = { #ifdef HAVE_HW_HANTEK_DSO &hantek_dso_driver_info, #endif -#ifdef HAVE_HW_GENERICDMM - &genericdmm_driver_info, -#endif #ifdef HAVE_HW_AGILENT_DMM &agdmm_driver_info, #endif