]> sigrok.org Git - libsigrok.git/commitdiff
Make SCPI functions device independent, with separate serial backend.
authorMartin Ling <redacted>
Tue, 3 Dec 2013 20:40:19 +0000 (20:40 +0000)
committerMartin Ling <redacted>
Tue, 3 Dec 2013 22:00:31 +0000 (22:00 +0000)
hardware/common/Makefile.am
hardware/common/scpi.c
hardware/common/scpi_serial.c [new file with mode: 0644]
hardware/hameg-hmo/api.c
hardware/hameg-hmo/protocol.c
libsigrok-internal.h
libsigrok.h
std.c

index 716436b75babb5f6ca3c5dcb9e0f9cc402a26c4f..82493ac9649b93f2ef2cc678e3c98ef7a535f787 100644 (file)
@@ -25,7 +25,7 @@ noinst_LTLIBRARIES = libsigrok_hw_common.la
 libsigrok_hw_common_la_SOURCES =
 
 if NEED_SERIAL
-libsigrok_hw_common_la_SOURCES += serial.c scpi.c
+libsigrok_hw_common_la_SOURCES += serial.c scpi.c scpi_serial.c
 endif
 
 if NEED_USB
index ff18b6e507fb75287850f70db2b0e3cf2221f24f..f8810a59250bfebe12666754bd76d987b7409448 100644 (file)
@@ -71,40 +71,110 @@ static int parse_strict_bool(const char *str, gboolean *ret)
        return SR_ERR;
 }
 
+/**
+ * Open SCPI device.
+ *
+ * @param scpi Previously initialized SCPI device structure.
+ *
+ * @return SR_OK on success, SR_ERR on failure.
+ */
+SR_PRIV int sr_scpi_open(struct sr_scpi_dev_inst *scpi)
+{
+       return scpi->open(scpi->priv);
+}
+
+/**
+ * Add an event source for an SCPI device.
+ *
+ * @param scpi Previously initialized SCPI device structure.
+ * @param events Events to check for.
+ * @param timeout Max time to wait before the callback is called, ignored if 0.
+ * @param cb Callback function to add. Must not be NULL.
+ * @param cb_data Data for the callback function. Can be NULL.
+ *
+ * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
+ *         SR_ERR_MALLOC upon memory allocation errors.
+ */
+SR_PRIV int sr_scpi_source_add(struct sr_scpi_dev_inst *scpi, int events,
+               int timeout, sr_receive_data_callback_t cb, void *cb_data)
+{
+       return scpi->source_add(scpi->priv, events, timeout, cb, cb_data);
+}
+
+/**
+ * Remove event source for an SCPI device.
+ *
+ * @param scpi Previously initialized SCPI device structure.
+ *
+ * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments, or
+ *         SR_ERR_MALLOC upon memory allocation errors, SR_ERR_BUG upon
+ *         internal errors.
+ */
+SR_PRIV int sr_scpi_source_remove(struct sr_scpi_dev_inst *scpi)
+{
+       return scpi->source_remove(scpi->priv);
+}
+
 /**
  * Send a SCPI command.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialized SCPI device structure.
  * @param command The SCPI command to send to the device.
  *
  * @return SR_OK on success, SR_ERR on failure.
  */
-SR_PRIV int sr_scpi_send(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_send(struct sr_scpi_dev_inst *scpi,
                         const char *command)
 {
-       int len, out;
-       gchar *terminated_command;
-
-       terminated_command = g_strconcat(command, "\n", NULL);
-       len = strlen(terminated_command);
-       out = serial_write(serial, terminated_command, len);
-       g_free(terminated_command);
+       return scpi->send(scpi->priv, command);
+}
 
-       if (out != len) {
-               sr_dbg("Only sent %d/%d bytes of SCPI command: '%s'.", out,
-                      len, command);
-               return SR_ERR;
-       }
+/**
+ * Receive an SCPI reply and store the reply in scpi_response.
+ *
+ * @param scpi Previously initialised SCPI device structure.
+ * @param scpi_response Pointer where to store the SCPI response.
+ *
+ * @return SR_OK upon fetching a full SCPI response, SR_ERR upon fetching an
+ *         incomplete or no response. The allocated response must be freed by
+ *         the caller in the case of a full response as well in the case of
+ *         an incomplete.
+ */
+SR_PRIV int sr_scpi_receive(struct sr_scpi_dev_inst *scpi,
+                       char **scpi_response)
+{
+       return scpi->receive(scpi->priv, scpi_response);
+}
 
-       sr_spew("Successfully sent SCPI command: '%s'.", command);
+/**
+ * Close SCPI device.
+ *
+ * @param scpi Previously initialized SCPI device structure.
+ *
+ * @return SR_OK on success, SR_ERR on failure.
+ */
+SR_PRIV int sr_scpi_close(struct sr_scpi_dev_inst *scpi)
+{
+       return scpi->close(scpi->priv);
+}
 
-       return SR_OK;
+/**
+ * Free SCPI device.
+ *
+ * @param scpi Previously initialized SCPI device structure.
+ *
+ * @return SR_OK on success, SR_ERR on failure.
+ */
+SR_PRIV void sr_scpi_free(struct sr_scpi_dev_inst *scpi)
+{
+       scpi->free(scpi->priv);
+       g_free(scpi);
 }
 
 /**
  * Send a SCPI command, receive the reply and store the reply in scpi_response.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param command The SCPI command to send to the device (can be NULL).
  * @param scpi_response Pointer where to store the SCPI response.
  *
@@ -113,74 +183,27 @@ SR_PRIV int sr_scpi_send(struct sr_serial_dev_inst *serial,
  *         the caller in the case of a full response as well in the case of
  *         an incomplete.
  */
-SR_PRIV int sr_scpi_get_string(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi,
                               const char *command, char **scpi_response)
 {
-       int len, ret;
-       char buf[256];
-       unsigned int i;
-       GString *response;
-
        if (command)
-               if (sr_scpi_send(serial, command) != SR_OK)
+               if (sr_scpi_send(scpi, command) != SR_OK)
                        return SR_ERR;
 
-       response = g_string_sized_new(1024);
-
-       for (i = 0; i <= SCPI_READ_RETRIES; i++) {
-               while ((len = serial_read(serial, buf, sizeof(buf))) > 0)
-                       response = g_string_append_len(response, buf, len);
-
-               if (response->len > 0 &&
-                   response->str[response->len-1] == '\n') {
-                       sr_spew("Fetched full SCPI response.");
-                       break;
-               }
-
-               g_usleep(SCPI_READ_RETRY_TIMEOUT);
-       }
-
-       if (response->len == 0) {
-               sr_dbg("No SCPI response received.");
-               g_string_free(response, TRUE);
-               *scpi_response = NULL;
-               return SR_ERR;
-       } else if (response->str[response->len - 1] == '\n') {
-               /*
-                * The SCPI response contains a LF ('\n') at the end and we
-                * don't need this so replace it with a '\0' and decrement
-                * the length.
-                */
-               response->str[--response->len] = '\0';
-               ret = SR_OK;
-       } else {
-               sr_warn("Incomplete SCPI response received!");
-               ret = SR_ERR;
-       }
-
-       /* Minor optimization: steal the string instead of copying. */
-       *scpi_response = response->str;
-
-       /* A SCPI response can be quite large, print at most 50 characters. */
-       sr_dbg("SCPI response for command %s received (length %d): '%.50s'",
-              command, response->len, response->str);
-
-       g_string_free(response, FALSE);
-
-       return ret;
+       return sr_scpi_receive(scpi, scpi_response);
 }
 
 /**
  * Send a SCPI command, read the reply, parse it as a bool value and store the
  * result in scpi_response.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param command The SCPI command to send to the device (can be NULL).
  * @param scpi_response Pointer where to store the parsed result.
  *
  * @return SR_OK on success, SR_ERR on failure.
  */
-SR_PRIV int sr_scpi_get_bool(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_bool(struct sr_scpi_dev_inst *scpi,
                             const char *command, gboolean *scpi_response)
 {
        int ret;
@@ -188,7 +211,7 @@ SR_PRIV int sr_scpi_get_bool(struct sr_serial_dev_inst *serial,
 
        response = NULL;
 
-       if (sr_scpi_get_string(serial, command, &response) != SR_OK)
+       if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
                if (!response)
                        return SR_ERR;
 
@@ -206,13 +229,13 @@ SR_PRIV int sr_scpi_get_bool(struct sr_serial_dev_inst *serial,
  * Send a SCPI command, read the reply, parse it as an integer and store the
  * result in scpi_response.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param command The SCPI command to send to the device (can be NULL).
  * @param scpi_response Pointer where to store the parsed result.
  *
  * @return SR_OK on success, SR_ERR on failure.
  */
-SR_PRIV int sr_scpi_get_int(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_int(struct sr_scpi_dev_inst *scpi,
                            const char *command, int *scpi_response)
 {
        int ret;
@@ -220,7 +243,7 @@ SR_PRIV int sr_scpi_get_int(struct sr_serial_dev_inst *serial,
 
        response = NULL;
 
-       if (sr_scpi_get_string(serial, command, &response) != SR_OK)
+       if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
                if (!response)
                        return SR_ERR;
 
@@ -238,13 +261,13 @@ SR_PRIV int sr_scpi_get_int(struct sr_serial_dev_inst *serial,
  * Send a SCPI command, read the reply, parse it as a float and store the
  * result in scpi_response.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param command The SCPI command to send to the device (can be NULL).
  * @param scpi_response Pointer where to store the parsed result.
  *
  * @return SR_OK on success, SR_ERR on failure.
  */
-SR_PRIV int sr_scpi_get_float(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_float(struct sr_scpi_dev_inst *scpi,
                              const char *command, float *scpi_response)
 {
        int ret;
@@ -252,7 +275,7 @@ SR_PRIV int sr_scpi_get_float(struct sr_serial_dev_inst *serial,
 
        response = NULL;
 
-       if (sr_scpi_get_string(serial, command, &response) != SR_OK)
+       if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
                if (!response)
                        return SR_ERR;
 
@@ -270,13 +293,13 @@ SR_PRIV int sr_scpi_get_float(struct sr_serial_dev_inst *serial,
  * Send a SCPI command, read the reply, parse it as a double and store the
  * result in scpi_response.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param command The SCPI command to send to the device (can be NULL).
  * @param scpi_response Pointer where to store the parsed result.
  *
  * @return SR_OK on success, SR_ERR on failure.
  */
-SR_PRIV int sr_scpi_get_double(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi,
                               const char *command, double *scpi_response)
 {
        int ret;
@@ -284,7 +307,7 @@ SR_PRIV int sr_scpi_get_double(struct sr_serial_dev_inst *serial,
 
        response = NULL;
 
-       if (sr_scpi_get_string(serial, command, &response) != SR_OK)
+       if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
                if (!response)
                        return SR_ERR;
 
@@ -302,17 +325,17 @@ SR_PRIV int sr_scpi_get_double(struct sr_serial_dev_inst *serial,
  * Send a SCPI *OPC? command, read the reply and return the result of the
  * command.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  *
  * @return SR_OK on success, SR_ERR on failure.
  */
-SR_PRIV int sr_scpi_get_opc(struct sr_serial_dev_inst *serial)
+SR_PRIV int sr_scpi_get_opc(struct sr_scpi_dev_inst *scpi)
 {
        unsigned int i;
        gboolean opc;
 
        for (i = 0; i < SCPI_READ_RETRIES; ++i) {
-               sr_scpi_get_bool(serial, SCPI_CMD_OPC, &opc);
+               sr_scpi_get_bool(scpi, SCPI_CMD_OPC, &opc);
                if (opc)
                        return SR_OK;
                g_usleep(SCPI_READ_RETRY_TIMEOUT);
@@ -325,7 +348,7 @@ SR_PRIV int sr_scpi_get_opc(struct sr_serial_dev_inst *serial)
  * Send a SCPI command, read the reply, parse it as comma separated list of
  * floats and store the as an result in scpi_response.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param command The SCPI command to send to the device (can be NULL).
  * @param scpi_response Pointer where to store the parsed result.
  *
@@ -334,7 +357,7 @@ SR_PRIV int sr_scpi_get_opc(struct sr_serial_dev_inst *serial)
  *         the caller in the case of an SR_OK as well as in the case of
  *         parsing error.
  */
-SR_PRIV int sr_scpi_get_floatv(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_floatv(struct sr_scpi_dev_inst *scpi,
                               const char *command, GArray **scpi_response)
 {
        int ret;
@@ -347,7 +370,7 @@ SR_PRIV int sr_scpi_get_floatv(struct sr_serial_dev_inst *serial,
        response = NULL;
        tokens = NULL;
 
-       if (sr_scpi_get_string(serial, command, &response) != SR_OK)
+       if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
                if (!response)
                        return SR_ERR;
 
@@ -383,7 +406,7 @@ SR_PRIV int sr_scpi_get_floatv(struct sr_serial_dev_inst *serial,
  * Send a SCPI command, read the reply, parse it as comma separated list of
  * unsigned 8 bit integers and store the as an result in scpi_response.
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param command The SCPI command to send to the device (can be NULL).
  * @param scpi_response Pointer where to store the parsed result.
  *
@@ -392,7 +415,7 @@ SR_PRIV int sr_scpi_get_floatv(struct sr_serial_dev_inst *serial,
  *         the caller in the case of an SR_OK as well as in the case of
  *         parsing error.
  */
-SR_PRIV int sr_scpi_get_uint8v(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_uint8v(struct sr_scpi_dev_inst *scpi,
                               const char *command, GArray **scpi_response)
 {
        int tmp, ret;
@@ -404,7 +427,7 @@ SR_PRIV int sr_scpi_get_uint8v(struct sr_serial_dev_inst *serial,
        response = NULL;
        tokens = NULL;
 
-       if (sr_scpi_get_string(serial, command, &response) != SR_OK)
+       if (sr_scpi_get_string(scpi, command, &response) != SR_OK)
                if (!response)
                        return SR_ERR;
 
@@ -442,12 +465,12 @@ SR_PRIV int sr_scpi_get_uint8v(struct sr_serial_dev_inst *serial,
  *
  * The hw_info structure must be freed by the caller via sr_scpi_hw_info_free().
  *
- * @param serial Previously initialized serial port structure.
+ * @param scpi Previously initialised SCPI device structure.
  * @param scpi_response Pointer where to store the hw_info structure.
  *
  * @return SR_OK upon success, SR_ERR on failure.
  */
-SR_PRIV int sr_scpi_get_hw_id(struct sr_serial_dev_inst *serial,
+SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
                              struct sr_scpi_hw_info **scpi_response)
 {
        int num_tokens;
@@ -458,7 +481,7 @@ SR_PRIV int sr_scpi_get_hw_id(struct sr_serial_dev_inst *serial,
        response = NULL;
        tokens = NULL;
 
-       if (sr_scpi_get_string(serial, SCPI_CMD_IDN, &response) != SR_OK)
+       if (sr_scpi_get_string(scpi, SCPI_CMD_IDN, &response) != SR_OK)
                if (!response)
                        return SR_ERR;
 
diff --git a/hardware/common/scpi_serial.c b/hardware/common/scpi_serial.c
new file mode 100644 (file)
index 0000000..cbe51b0
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * This file is part of the libsigrok project.
+ *
+ * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.com>
+ * Copyright (C) 2013 Martin Ling <martin-sigrok@earth.li>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "libsigrok.h"
+#include "libsigrok-internal.h"
+
+#include <glib.h>
+#include <string.h>
+
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "scpi_serial: "
+#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 SCPI_READ_RETRIES 100
+#define SCPI_READ_RETRY_TIMEOUT 10000
+
+SR_PRIV int scpi_serial_open(void *priv)
+{
+       struct sr_serial_dev_inst *serial = priv;
+
+       return serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK);
+}
+
+SR_PRIV int scpi_serial_source_add(void *priv, int events, int timeout,
+                       sr_receive_data_callback_t cb, void *cb_data)
+{
+       struct sr_serial_dev_inst *serial = priv;
+
+       return sr_source_add(serial->fd, events, timeout, cb, cb_data);
+}
+
+SR_PRIV int scpi_serial_source_remove(void *priv)
+{
+       struct sr_serial_dev_inst *serial = priv;
+
+       return sr_source_remove(serial->fd);
+}
+
+SR_PRIV int scpi_serial_send(void *priv, const char *command)
+{
+       int len, out;
+       gchar *terminated_command;
+       struct sr_serial_dev_inst *serial = priv;
+
+       terminated_command = g_strconcat(command, "\n", NULL);
+       len = strlen(terminated_command);
+       out = serial_write(serial, terminated_command, len);
+       g_free(terminated_command);
+
+       if (out != len) {
+               sr_dbg("Only sent %d/%d bytes of SCPI command: '%s'.", out,
+                      len, command);
+               return SR_ERR;
+       }
+
+       sr_spew("Successfully sent SCPI command: '%s'.", command);
+
+       return SR_OK;
+}
+
+SR_PRIV int scpi_serial_receive(void *priv, char **scpi_response)
+{
+       int len, ret;
+       char buf[256];
+       unsigned int i;
+       GString *response;
+       struct sr_serial_dev_inst *serial = priv;
+
+       response = g_string_sized_new(1024);
+
+       for (i = 0; i <= SCPI_READ_RETRIES; i++) {
+               while ((len = serial_read(serial, buf, sizeof(buf))) > 0)
+                       response = g_string_append_len(response, buf, len);
+
+               if (response->len > 0 &&
+                   response->str[response->len-1] == '\n') {
+                       sr_spew("Fetched full SCPI response.");
+                       break;
+               }
+
+               g_usleep(SCPI_READ_RETRY_TIMEOUT);
+       }
+
+       if (response->len == 0) {
+               sr_dbg("No SCPI response received.");
+               g_string_free(response, TRUE);
+               *scpi_response = NULL;
+               return SR_ERR;
+       } else if (response->str[response->len - 1] == '\n') {
+               /*
+                * The SCPI response contains a LF ('\n') at the end and we
+                * don't need this so replace it with a '\0' and decrement
+                * the length.
+                */
+               response->str[--response->len] = '\0';
+               ret = SR_OK;
+       } else {
+               sr_warn("Incomplete SCPI response received!");
+               ret = SR_ERR;
+       }
+
+       /* Minor optimization: steal the string instead of copying. */
+       *scpi_response = response->str;
+
+       /* A SCPI response can be quite large, print at most 50 characters. */
+       sr_dbg("SCPI response received (length %d): '%.50s'",
+              response->len, response->str);
+
+       g_string_free(response, FALSE);
+
+       return ret;
+}
+
+SR_PRIV struct sr_scpi_dev_inst *scpi_serial_dev_inst_new(const char *port,
+               const char *serialcomm)
+{
+       struct sr_scpi_dev_inst *scpi;
+       struct sr_serial_dev_inst *serial;
+
+       scpi = g_try_malloc(sizeof(struct sr_scpi_dev_inst));
+
+       if (!(serial = sr_serial_dev_inst_new(port, serialcomm)))
+       {
+               g_free(scpi);
+               return NULL;
+       }
+
+       scpi->open = scpi_serial_open;
+       scpi->source_add = scpi_serial_source_add;
+       scpi->source_remove = scpi_serial_source_remove;
+       scpi->send = scpi_serial_send;
+       scpi->receive = scpi_serial_receive;
+       scpi->close = serial_close;
+       scpi->free = sr_serial_dev_inst_free;
+       scpi->priv = serial;
+
+       return scpi;
+}
index 4868410a00655d179260062a016815bb17a1e588..6a16bb1dba832419eed31d151e8e06dad74bc218 100644 (file)
@@ -270,8 +270,7 @@ static int dev_clear(void)
 
 static int dev_open(struct sr_dev_inst *sdi)
 {
-       if (sdi->status != SR_ST_ACTIVE &&
-           serial_open(sdi->conn, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
+       if (sdi->status != SR_ST_ACTIVE && sr_scpi_open(sdi->conn) != SR_OK)
                return SR_ERR;
 
        if (hmo_scope_state_get(sdi) != SR_OK)
@@ -287,7 +286,7 @@ static int dev_close(struct sr_dev_inst *sdi)
        if (sdi->status == SR_ST_INACTIVE)
                return SR_OK;
 
-       serial_close(sdi->conn);
+       sr_scpi_close(sdi->conn);
 
        sdi->status = SR_ST_INACTIVE;
 
@@ -679,10 +678,10 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi)
        struct scope_config *model;
        struct sr_probe *probe;
        struct dev_context *devc;
-       struct sr_serial_dev_inst *serial;
+       struct sr_scpi_dev_inst *scpi;
 
        devc = sdi->priv;
-       serial = sdi->conn;
+       scpi = sdi->conn;
        state = devc->model_state;
        model = devc->model_config;
 
@@ -698,7 +697,7 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi)
                                   (*model->scpi_dialect)[SCPI_CMD_SET_ANALOG_CHAN_STATE],
                                   probe->index + 1, probe->enabled);
 
-                       if (sr_scpi_send(serial, command) != SR_OK)
+                       if (sr_scpi_send(scpi, command) != SR_OK)
                                return SR_ERR;
                        state->analog_channels[probe->index].state = probe->enabled;
                        break;
@@ -716,7 +715,7 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi)
                                   (*model->scpi_dialect)[SCPI_CMD_SET_DIG_CHAN_STATE],
                                   probe->index, probe->enabled);
 
-                       if (sr_scpi_send(serial, command) != SR_OK)
+                       if (sr_scpi_send(scpi, command) != SR_OK)
                                return SR_ERR;
 
                        state->digital_channels[probe->index] = probe->enabled;
@@ -732,7 +731,7 @@ static int hmo_setup_probes(const struct sr_dev_inst *sdi)
                g_snprintf(command, sizeof(command),
                           (*model->scpi_dialect)[SCPI_CMD_SET_DIG_POD_STATE],
                           i, pod_enabled[i - 1]);
-               if (sr_scpi_send(serial, command) != SR_OK)
+               if (sr_scpi_send(scpi, command) != SR_OK)
                        return SR_ERR;
                state->digital_pods[i - 1] = pod_enabled[i - 1];
        }
@@ -748,12 +747,12 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
        gboolean digital_added;
        struct sr_probe *probe;
        struct dev_context *devc;
-       struct sr_serial_dev_inst *serial;
+       struct sr_scpi_dev_inst *scpi;
 
        if (sdi->status != SR_ST_ACTIVE)
                return SR_ERR_DEV_CLOSED;
 
-       serial = sdi->conn;
+       scpi = sdi->conn;
        devc = sdi->priv;
        digital_added = FALSE;
 
@@ -783,7 +782,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
                return SR_ERR;
        }
 
-       sr_source_add(serial->fd, G_IO_IN, 50, hmo_receive_data, (void *)sdi);
+       sr_scpi_source_add(scpi, G_IO_IN, 50, hmo_receive_data, (void *)sdi);
 
        /* Send header packet to the session bus. */
        std_session_send_df_header(cb_data, LOG_PREFIX);
@@ -796,7 +795,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
 {
        struct dev_context *devc;
-       struct sr_serial_dev_inst *serial;
+       struct sr_scpi_dev_inst *scpi;
 
        (void)cb_data;
 
@@ -807,8 +806,8 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
 
        g_slist_free(devc->enabled_probes);
        devc->enabled_probes = NULL;
-       serial = sdi->conn;
-       sr_source_remove(serial->fd);
+       scpi = sdi->conn;
+       sr_scpi_source_remove(scpi);
 
        return SR_OK;
 }
index d76a6778e6d80dc7922f07b3a7caf53977a0b883..b4807990b1ba16c0f42e7a7a0576958b93b791f0 100644 (file)
@@ -296,13 +296,13 @@ static void scope_state_dump(struct scope_config *config,
                state->horiz_triggerpos);
 }
 
-static int scope_state_get_array_option(struct sr_serial_dev_inst *serial,
+static int scope_state_get_array_option(struct sr_scpi_dev_inst *scpi,
                const char *command, const char *(*array)[], int *result)
 {
        char *tmp;
        unsigned int i;
 
-       if (sr_scpi_get_string(serial, command, &tmp) != SR_OK) {
+       if (sr_scpi_get_string(scpi, command, &tmp) != SR_OK) {
                g_free(tmp);
                return SR_ERR;
        }
@@ -324,7 +324,7 @@ static int scope_state_get_array_option(struct sr_serial_dev_inst *serial,
        return SR_OK;
 }
 
-static int analog_channel_state_get(struct sr_serial_dev_inst *serial,
+static int analog_channel_state_get(struct sr_scpi_dev_inst *scpi,
                                    struct scope_config *config,
                                    struct scope_state *state)
 {
@@ -336,7 +336,7 @@ static int analog_channel_state_get(struct sr_serial_dev_inst *serial,
                           (*config->scpi_dialect)[SCPI_CMD_GET_ANALOG_CHAN_STATE],
                           i + 1);
 
-               if (sr_scpi_get_bool(serial, command,
+               if (sr_scpi_get_bool(scpi, command,
                                     &state->analog_channels[i].state) != SR_OK)
                        return SR_ERR;
 
@@ -344,7 +344,7 @@ static int analog_channel_state_get(struct sr_serial_dev_inst *serial,
                           (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_DIV],
                           i + 1);
 
-               if (sr_scpi_get_float(serial, command,
+               if (sr_scpi_get_float(scpi, command,
                                     &state->analog_channels[i].vdiv) != SR_OK)
                        return SR_ERR;
 
@@ -352,7 +352,7 @@ static int analog_channel_state_get(struct sr_serial_dev_inst *serial,
                           (*config->scpi_dialect)[SCPI_CMD_GET_VERTICAL_OFFSET],
                           i + 1);
 
-               if (sr_scpi_get_float(serial, command,
+               if (sr_scpi_get_float(scpi, command,
                                     &state->analog_channels[i].vertical_offset) != SR_OK)
                        return SR_ERR;
 
@@ -360,7 +360,7 @@ static int analog_channel_state_get(struct sr_serial_dev_inst *serial,
                           (*config->scpi_dialect)[SCPI_CMD_GET_COUPLING],
                           i + 1);
 
-               if (scope_state_get_array_option(serial, command, config->coupling_options,
+               if (scope_state_get_array_option(scpi, command, config->coupling_options,
                                         &state->analog_channels[i].coupling) != SR_OK)
                        return SR_ERR;
        }
@@ -368,7 +368,7 @@ static int analog_channel_state_get(struct sr_serial_dev_inst *serial,
        return SR_OK;
 }
 
-static int digital_channel_state_get(struct sr_serial_dev_inst *serial,
+static int digital_channel_state_get(struct sr_scpi_dev_inst *scpi,
                                     struct scope_config *config,
                                     struct scope_state *state)
 {
@@ -380,7 +380,7 @@ static int digital_channel_state_get(struct sr_serial_dev_inst *serial,
                           (*config->scpi_dialect)[SCPI_CMD_GET_DIG_CHAN_STATE],
                           i);
 
-               if (sr_scpi_get_bool(serial, command,
+               if (sr_scpi_get_bool(scpi, command,
                                     &state->digital_channels[i]) != SR_OK)
                        return SR_ERR;
        }
@@ -390,7 +390,7 @@ static int digital_channel_state_get(struct sr_serial_dev_inst *serial,
                           (*config->scpi_dialect)[SCPI_CMD_GET_DIG_POD_STATE],
                           i + 1);
 
-               if (sr_scpi_get_bool(serial, command,
+               if (sr_scpi_get_bool(scpi, command,
                                     &state->digital_pods[i]) != SR_OK)
                        return SR_ERR;
        }
@@ -566,21 +566,21 @@ SR_PRIV struct sr_dev_inst *hmo_probe_serial_device(const char *serial_device,
        struct sr_dev_inst *sdi;
        struct dev_context *devc;
        struct sr_scpi_hw_info *hw_info;
-       struct sr_serial_dev_inst *serial;
+       struct sr_scpi_dev_inst *scpi;
 
        sdi = NULL;
        devc = NULL;
-       serial = NULL;
+       scpi = NULL;
        hw_info = NULL;
 
-       if (!(serial = sr_serial_dev_inst_new(serial_device, serial_options)))
+       if (!(scpi = scpi_serial_dev_inst_new(serial_device, serial_options)))
                goto fail;
 
        sr_info("Probing %s.", serial_device);
-       if (serial_open(serial, SERIAL_RDWR | SERIAL_NONBLOCK) != SR_OK)
+       if (sr_scpi_open(scpi) != SR_OK)
                goto fail;
 
-       if (sr_scpi_get_hw_id(serial, &hw_info) != SR_OK) {
+       if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
                sr_info("Couldn't get IDN response.");
                goto fail;
        }
@@ -601,8 +601,8 @@ SR_PRIV struct sr_dev_inst *hmo_probe_serial_device(const char *serial_device,
 
        sdi->driver = di;
        sdi->priv = devc;
-       sdi->inst_type = SR_INST_SERIAL;
-       sdi->conn = serial;
+       sdi->inst_type = SR_INST_SCPI;
+       sdi->conn = scpi;
 
        if (hmo_init_device(sdi) != SR_OK)
                goto fail;
@@ -612,8 +612,8 @@ SR_PRIV struct sr_dev_inst *hmo_probe_serial_device(const char *serial_device,
 fail:
        if (hw_info)
                sr_scpi_hw_info_free(hw_info);
-       if (serial)
-               sr_serial_dev_inst_free(serial);
+       if (scpi)
+               sr_scpi_free(scpi);
        if (sdi)
                sr_dev_inst_free(sdi);
        if (devc)
index e7a97aae668521d01878f2f2150b6339fe5f4eb8..3df28fe2195b0727aa2ee8b9936e02b389076bab 100644 (file)
@@ -285,29 +285,55 @@ struct sr_scpi_hw_info {
        char *firmware_version;
 };
 
-SR_PRIV int sr_scpi_send(struct sr_serial_dev_inst *serial,
-                        const char *command);
-SR_PRIV int sr_scpi_get_string(struct sr_serial_dev_inst *serial,
-                              const char *command, char **scpi_response);
-SR_PRIV int sr_scpi_get_bool(struct sr_serial_dev_inst *serial,
-                            const char *command, gboolean *scpi_response);
-SR_PRIV int sr_scpi_get_int(struct sr_serial_dev_inst *serial,
-                                 const char *command, int *scpi_response);
-SR_PRIV int sr_scpi_get_float(struct sr_serial_dev_inst *serial,
-                             const char *command, float *scpi_response);
-SR_PRIV int sr_scpi_get_double(struct sr_serial_dev_inst *serial,
-                             const char *command, double *scpi_response);
-SR_PRIV int sr_scpi_get_opc(struct sr_serial_dev_inst *serial);
-SR_PRIV int sr_scpi_get_floatv(struct sr_serial_dev_inst *serial,
-                             const char *command, GArray **scpi_response);
-SR_PRIV int sr_scpi_get_uint8v(struct sr_serial_dev_inst *serial,
-                             const char *command, GArray **scpi_response);
-SR_PRIV int sr_scpi_get_hw_id(struct sr_serial_dev_inst *serial,
-                             struct sr_scpi_hw_info **scpi_reponse);
+struct sr_scpi_dev_inst {
+       int (*open)(void *priv);
+       int (*source_add)(void *priv, int events,
+               int timeout, sr_receive_data_callback_t cb, void *cb_data);
+       int (*source_remove)(void *priv);
+       int (*send)(void *priv, const char *command);
+       int (*receive)(void *priv, char **scpi_response);
+       int (*close)(void *priv);
+       void (*free)(void *priv);
+       void *priv;
+};
+
+SR_PRIV int sr_scpi_open(struct sr_scpi_dev_inst *scpi);
+SR_PRIV int sr_scpi_source_add(struct sr_scpi_dev_inst *scpi, int events,
+               int timeout, sr_receive_data_callback_t cb, void *cb_data);
+SR_PRIV int sr_scpi_source_remove(struct sr_scpi_dev_inst *scpi);
+SR_PRIV int sr_scpi_send(struct sr_scpi_dev_inst *scpi,
+                       const char *command);
+SR_PRIV int sr_scpi_receive(struct sr_scpi_dev_inst *scpi,
+                       char **scpi_response);
+SR_PRIV int sr_scpi_close(struct sr_scpi_dev_inst *scpi);
+SR_PRIV void sr_scpi_free(struct sr_scpi_dev_inst *scpi);
+
+SR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi,
+                       const char *command, char **scpi_response);
+SR_PRIV int sr_scpi_get_bool(struct sr_scpi_dev_inst *scpi,
+                       const char *command, gboolean *scpi_response);
+SR_PRIV int sr_scpi_get_int(struct sr_scpi_dev_inst *scpi,
+                       const char *command, int *scpi_response);
+SR_PRIV int sr_scpi_get_float(struct sr_scpi_dev_inst *scpi,
+                       const char *command, float *scpi_response);
+SR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi,
+                       const char *command, double *scpi_response);
+SR_PRIV int sr_scpi_get_opc(struct sr_scpi_dev_inst *scpi);
+SR_PRIV int sr_scpi_get_floatv(struct sr_scpi_dev_inst *scpi,
+                       const char *command, GArray **scpi_response);
+SR_PRIV int sr_scpi_get_uint8v(struct sr_scpi_dev_inst *scpi,
+                       const char *command, GArray **scpi_response);
+SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
+                       struct sr_scpi_hw_info **scpi_response);
 SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info);
 
 #endif
 
+/*--- hardware/common/scpi_serial.c -----------------------------------------*/
+
+SR_PRIV struct sr_scpi_dev_inst *scpi_serial_dev_inst_new(const char *port,
+                       const char *serialcomm);
+
 /*--- hardware/common/dmm/es51922.c -----------------------------------------*/
 
 #define ES51922_PACKET_SIZE 14
index 1e45a5e1a1d4828f1a579490a43afc440a7c5a20..53ff8c2470431c9e83619e5d256573e2b435bbe0 100644 (file)
@@ -805,6 +805,8 @@ enum {
        SR_INST_SERIAL,
        /** Device instance type for USBTMC devices. */
        SR_INST_USBTMC,
+       /** Device instance type for SCPI devices. */
+       SR_INST_SCPI,
 };
 
 /** Device instance status. */
diff --git a/std.c b/std.c
index d1ff84e037c29cdb70044ac68d36c33be1ee7328..ab4fd76df09639029afefffedef326e957bc32ec 100644 (file)
--- a/std.c
+++ b/std.c
@@ -217,6 +217,8 @@ SR_PRIV int std_dev_clear(const struct sr_dev_driver *driver,
 #endif
                        if (sdi->inst_type == SR_INST_USBTMC)
                                sr_usbtmc_dev_inst_free(sdi->conn);
+                       if (sdi->inst_type == SR_INST_SCPI)
+                               sr_scpi_free(sdi->conn);
                }
                if (clear_private)
                        clear_private(sdi->priv);