scpi-dmm: Gracefully handle meters that lack OPC command.
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>
Sun, 28 Feb 2021 13:32:08 +0000 (15:32 +0200)
committerGerhard Sittig <gerhard.sittig@gmx.net>
Sat, 6 Mar 2021 18:04:19 +0000 (19:04 +0100)
The SCPI standard requires OPeration Complete command,
but some Owon meters do not implement it. This commit
makes the probe try OPC once, and if it gets no reply
it assumes it is not supported.

src/hardware/scpi-dmm/api.c
src/hardware/scpi-dmm/protocol.c
src/scpi.h

index 456c24dbf9ea93e13668efa56b482f642057185a..c6753860b866a072443e9221acd04179bd48ebe9 100644 (file)
@@ -241,6 +241,25 @@ static const struct scpi_dmm_model *is_compatible(const char *vendor, const char
        return NULL;
 }
 
+/*
+ * Some devices (such as Owon XDM2041) do not support the standard
+ * OPeration Complete? command. This function tests the command with
+ * a short timeout, and returns TRUE if any reply (busy or not) is received.
+ */
+static gboolean probe_opc_support(struct sr_scpi_dev_inst *scpi)
+{
+       gboolean result;
+       GString *response;
+
+       response = g_string_sized_new(128);
+       result = TRUE;
+       if (sr_scpi_get_data(scpi, SCPI_CMD_OPC, &response) != SR_OK)
+               result = FALSE;
+       g_string_free(response, TRUE);
+
+       return result;
+}
+
 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
 {
        struct sr_scpi_hw_info *hw_info;
@@ -253,6 +272,9 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
        gchar *channel_name;
        const char *command;
 
+       if (!probe_opc_support(scpi))
+               scpi->no_opc_command = TRUE;
+
        scpi_dmm_cmd_delay(scpi);
        ret = sr_scpi_get_hw_id(scpi, &hw_info);
        if (ret != SR_OK) {
index bc739400cb38240e101573f58fa0d064f725715a..fe20441408fa39b1c43fbdd9ab82ce0676a39c26 100644 (file)
@@ -28,7 +28,9 @@ SR_PRIV void scpi_dmm_cmd_delay(struct sr_scpi_dev_inst *scpi)
 {
        if (WITH_CMD_DELAY)
                g_usleep(WITH_CMD_DELAY * 1000);
-       sr_scpi_get_opc(scpi);
+
+       if (!scpi->no_opc_command)
+               sr_scpi_get_opc(scpi);
 }
 
 SR_PRIV const struct mqopt_item *scpi_dmm_lookup_mq_number(
index 312f5e8a0f2c7940937f7e40c93ee78cb12c7627..634c2727110b88334dbabdc34074a8d7565f733a 100644 (file)
@@ -113,6 +113,7 @@ struct sr_scpi_dev_inst {
        uint64_t firmware_version;
        GMutex scpi_mutex;
        char *actual_channel_name;
+       gboolean no_opc_command;
 };
 
 SR_PRIV GSList *sr_scpi_scan(struct drv_context *drvc, GSList *options,