X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fscpi%2Fscpi.c;h=8d24ceea97e29c88de244fae03600a8cf52b6507;hb=HEAD;hp=ec0ddc555c73b37b6cdec6799ecf9573fee3534c;hpb=191af3d9ca2f347810a12a3f9d87bdc8c8db15aa;p=libsigrok.git diff --git a/src/scpi/scpi.c b/src/scpi/scpi.c index ec0ddc55..8d24ceea 100644 --- a/src/scpi/scpi.c +++ b/src/scpi/scpi.c @@ -38,6 +38,7 @@ static const char *scpi_vendors[][2] = { { "Keysight Technologies", "Keysight" }, { "PHILIPS", "Philips" }, { "RIGOL TECHNOLOGIES", "Rigol" }, + { "Siglent Technologies", "Siglent" }, }; /** @@ -315,33 +316,32 @@ SR_PRIV GSList *sr_scpi_scan(struct drv_context *drvc, GSList *options, { GSList *resources, *l, *devices; struct sr_dev_inst *sdi; - const char *resource = NULL; - const char *serialcomm = NULL; + const char *resource, *conn; + const char *serialcomm, *comm; gchar **res; unsigned i; - for (l = options; l; l = l->next) { - struct sr_config *src = l->data; - switch (src->key) { - case SR_CONF_CONN: - resource = g_variant_get_string(src->data, NULL); - break; - case SR_CONF_SERIALCOMM: - serialcomm = g_variant_get_string(src->data, NULL); - break; - } - } + resource = NULL; + serialcomm = NULL; + (void)sr_serial_extract_options(options, &resource, &serialcomm); devices = NULL; for (i = 0; i < ARRAY_SIZE(scpi_devs); i++) { - if ((resource && strcmp(resource, scpi_devs[i]->prefix)) - || !scpi_devs[i]->scan) + if (resource && strcmp(resource, scpi_devs[i]->prefix) != 0) + continue; + if (!scpi_devs[i]->scan) continue; resources = scpi_devs[i]->scan(drvc); for (l = resources; l; l = l->next) { res = g_strsplit(l->data, ":", 2); - if (res[0] && (sdi = sr_scpi_scan_resource(drvc, res[0], - serialcomm ? serialcomm : res[1], probe_device))) { + if (!res[0]) { + g_strfreev(res); + continue; + } + conn = res[0]; + comm = serialcomm ? : res[1]; + sdi = sr_scpi_scan_resource(drvc, conn, comm, probe_device); + if (sdi) { devices = g_slist_append(devices, sdi); sdi->connection_id = g_strdup(l->data); } @@ -1038,7 +1038,29 @@ SR_PRIV int sr_scpi_get_block(struct sr_scpi_dev_inst *scpi, buf[0] = response->str[1]; buf[1] = '\0'; ret = sr_atol(buf, &llen); - if ((ret != SR_OK) || (llen == 0)) { + /* + * The form "#0..." is legal, and does not mean "empty response", + * but means that the number of data bytes is not known (or was + * not communicated) at this time. Instead the block ends at an + * "END MESSAGE" termination sequence. Which translates to active + * EOI while a text line termination is sent (CR or LF, and this + * text line termination is not part of the block's data value). + * Since this kind of #0... response is considered rare, and + * depends on specific support in physical transports underneath + * the SCPI layer, let's flag the condition and bail out with an + * error here, until it's found to be a genuine issue in the field. + * + * The SCPI 1999.0 specification (see page 220 and following in + * the "HCOPy" description) references IEEE 488.2, especially + * section 8.7.9 for DEFINITE LENGTH and section 8.7.10 for + * INDEFINITE LENGTH ARBITRARY BLOCK RESPONSE DATA. The latter + * with a leading "#0" length and a trailing "NL^END" marker. + */ + if (ret == SR_OK && !llen) { + sr_err("unsupported INDEFINITE LENGTH ARBITRARY BLOCK RESPONSE"); + ret = SR_ERR_NA; + } + if (ret != SR_OK) { g_mutex_unlock(&scpi->scpi_mutex); g_string_free(response, TRUE); return ret;