From ddeaa49d431f3cb79a4d3e9f07fcc636797944ca Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Sun, 28 Feb 2021 15:32:08 +0200 Subject: [PATCH] scpi-dmm: Gracefully handle meters that lack OPC command. 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 | 22 ++++++++++++++++++++++ src/hardware/scpi-dmm/protocol.c | 4 +++- src/scpi.h | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/hardware/scpi-dmm/api.c b/src/hardware/scpi-dmm/api.c index 456c24db..c6753860 100644 --- a/src/hardware/scpi-dmm/api.c +++ b/src/hardware/scpi-dmm/api.c @@ -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) { diff --git a/src/hardware/scpi-dmm/protocol.c b/src/hardware/scpi-dmm/protocol.c index bc739400..fe204414 100644 --- a/src/hardware/scpi-dmm/protocol.c +++ b/src/hardware/scpi-dmm/protocol.c @@ -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( diff --git a/src/scpi.h b/src/scpi.h index 312f5e8a..634c2727 100644 --- a/src/scpi.h +++ b/src/scpi.h @@ -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, -- 2.30.2