From: Bert Vermeulen Date: Sun, 7 Sep 2014 22:02:03 +0000 (+0200) Subject: scpi-pps: Simplify SCPI command handling. X-Git-Tag: libsigrok-0.4.0~1033 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=478c8d923e026fe2dda707f67336326da635b2eb;p=libsigrok.git scpi-pps: Simplify SCPI command handling. --- diff --git a/src/hardware/scpi-pps/api.c b/src/hardware/scpi-pps/api.c index 31e7ca6c..b7b68b74 100644 --- a/src/hardware/scpi-pps/api.c +++ b/src/hardware/scpi-pps/api.c @@ -171,8 +171,9 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, struct dev_context *devc; struct sr_scpi_dev_inst *scpi; struct sr_channel *ch; - double d; - int ret; + const GVariantType *gvtype; + unsigned int i; + int cmd, ret; char *s; if (!sdi) @@ -181,43 +182,88 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, devc = sdi->priv; scpi = sdi->conn; - ret = SR_OK; - if (!cg) { - /* No channel group: global options. */ - switch (key) { - case SR_CONF_OVER_TEMPERATURE_PROTECTION: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION) == SR_OK) { - if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) { - *data = g_variant_new_boolean(!strcmp(s, "ON")); - ret = SR_OK; - } - } - break; - return SR_ERR_NA; - break; - case SR_CONF_OUTPUT_CHANNEL_CONFIG: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OUTPUT_CHANNEL_CONFIG) == SR_OK) { - if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) { - *data = g_variant_new_string(s); - g_free(s); - ret = SR_OK; - } - } - break; - default: - return SR_ERR_NA; - } - } else { + if (cg) { /* * These options only apply to channel groups with a single * channel -- they're per-channel settings for the device. */ if (g_slist_length(cg->channels) > 1) return SR_ERR_NA; + + /* + * Config keys are handled below depending on whether a channel + * group was provided by the frontend. However some of these + * take a CG on one PPS but not on others. Check the device's + * profile for that here, and NULL out the channel group as needed. + */ + for (i = 0; i < devc->device->num_devopts; i++) { + if (devc->device->devopts[i] == key) { + cg = NULL; + break; + } + } + ch = cg->channels->data; + } + gvtype = NULL; + cmd = -1; + switch (key) { + case SR_CONF_OUTPUT_ENABLED: + gvtype = G_VARIANT_TYPE_BOOLEAN; + cmd = SCPI_CMD_GET_OUTPUT_ENABLED; + break; + case SR_CONF_OUTPUT_VOLTAGE: + gvtype = G_VARIANT_TYPE_DOUBLE; + cmd = SCPI_CMD_GET_MEAS_VOLTAGE; + break; + case SR_CONF_OUTPUT_VOLTAGE_MAX: + gvtype = G_VARIANT_TYPE_DOUBLE; + cmd = SCPI_CMD_GET_VOLTAGE_MAX; + break; + case SR_CONF_OUTPUT_CURRENT: + gvtype = G_VARIANT_TYPE_DOUBLE; + cmd = SCPI_CMD_GET_MEAS_CURRENT; + break; + case SR_CONF_OUTPUT_CURRENT_MAX: + gvtype = G_VARIANT_TYPE_DOUBLE; + cmd = SCPI_CMD_GET_CURRENT_MAX; + break; + case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED: + gvtype = G_VARIANT_TYPE_BOOLEAN; + cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ENABLED; + break; + case SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE: + gvtype = G_VARIANT_TYPE_BOOLEAN; + cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ACTIVE; + break; + case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD: + gvtype = G_VARIANT_TYPE_DOUBLE; + cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_THRESHOLD; + break; + case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED: + gvtype = G_VARIANT_TYPE_BOOLEAN; + cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ENABLED; + break; + case SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE: + gvtype = G_VARIANT_TYPE_BOOLEAN; + cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE; + break; + case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD: + gvtype = G_VARIANT_TYPE_DOUBLE; + cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD; + break; + case SR_CONF_OVER_TEMPERATURE_PROTECTION: + gvtype = G_VARIANT_TYPE_BOOLEAN; + cmd = SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION; + break; + } + if (gvtype) { + if (cg) + ret = scpi_cmd_resp(sdi, data, gvtype, cmd, ch->name); + else + ret = scpi_cmd_resp(sdi, data, gvtype, cmd); + } else if (cg) { switch (key) { case SR_CONF_OUTPUT_REGULATION: ret = SR_ERR; @@ -233,115 +279,11 @@ static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi, } } break; - case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ENABLED, - ch->name) == SR_OK) { - if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) { - *data = g_variant_new_boolean(!strcmp(s, "ON")); - ret = SR_OK; - } - } - break; - case SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ACTIVE, - ch->name) == SR_OK) { - if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) { - *data = g_variant_new_boolean(!strcmp(s, "YES")); - ret = SR_OK; - } - } - break; - case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_THRESHOLD, - ch->name) == SR_OK) { - if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) { - *data = g_variant_new_double(d); - ret = SR_OK; - } - } - break; - case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ENABLED, - ch->name) == SR_OK) { - if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) { - *data = g_variant_new_boolean(!strcmp(s, "ON")); - ret = SR_OK; - } - } - break; - case SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE, - ch->name) == SR_OK) { - if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) { - *data = g_variant_new_boolean(!strcmp(s, "YES")); - ret = SR_OK; - } - } - break; - case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, - ch->name) == SR_OK) { - if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) { - *data = g_variant_new_double(d); - ret = SR_OK; - } - } - break; - case SR_CONF_OUTPUT_VOLTAGE: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_MEAS_VOLTAGE, ch->name) == SR_OK) { - if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) { - *data = g_variant_new_double(d); - ret = SR_OK; - } - } - break; - case SR_CONF_OUTPUT_VOLTAGE_MAX: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_VOLTAGE_MAX, ch->name) == SR_OK) { - if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) { - *data = g_variant_new_double(d); - ret = SR_OK; - } - } - break; - case SR_CONF_OUTPUT_CURRENT: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_MEAS_CURRENT, ch->name) == SR_OK) { - if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) { - *data = g_variant_new_double(d); - ret = SR_OK; - } - } - break; - case SR_CONF_OUTPUT_CURRENT_MAX: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_CURRENT_MAX, ch->name) == SR_OK) { - if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) { - *data = g_variant_new_double(d); - ret = SR_OK; - } - } - break; - case SR_CONF_OUTPUT_ENABLED: - ret = SR_ERR; - if (scpi_cmd(sdi, SCPI_CMD_GET_OUTPUT_ENABLED, ch->name) == SR_OK) { - if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) { - *data = g_variant_new_boolean(!strcmp(s, "ON")); - ret = SR_OK; - } - } - break; default: - return SR_ERR_NA; + ret = SR_ERR_NA; } - } + } else + ret = SR_ERR_NA; return ret; } @@ -357,20 +299,25 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, if (sdi->status != SR_ST_ACTIVE) return SR_ERR_DEV_CLOSED; - ret = SR_OK; if (!cg) { switch (key) { /* No channel group: global options. */ - case SR_CONF_OVER_TEMPERATURE_PROTECTION: + case SR_CONF_OUTPUT_ENABLED: s = g_variant_get_boolean(data) ? "ON" : "OFF"; - if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION, s) < 0) - ret = SR_ERR; + ret = scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_ENABLED, s); break; - case SR_CONF_OUTPUT_CHANNEL_CONFIG: - s = g_variant_get_string(data, NULL); - if (scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_CHANNEL_CONFIG, s) < 0) - ret = SR_ERR; + case SR_CONF_OUTPUT_VOLTAGE_MAX: + d = g_variant_get_double(data); + ret = scpi_cmd(sdi, SCPI_CMD_SET_VOLTAGE_MAX, d); + break; + case SR_CONF_OUTPUT_CURRENT_MAX: + d = g_variant_get_double(data); + ret = scpi_cmd(sdi, SCPI_CMD_SET_CURRENT_MAX, d); + break; + case SR_CONF_OVER_TEMPERATURE_PROTECTION: + s = g_variant_get_boolean(data) ? "ON" : "OFF"; + ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION, s); break; default: ret = SR_ERR_NA; @@ -383,44 +330,37 @@ static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi, return SR_ERR_NA; ch = cg->channels->data; switch (key) { + case SR_CONF_OUTPUT_ENABLED: + s = g_variant_get_boolean(data) ? "ON" : "OFF"; + ret = scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_ENABLED, ch->name, s); + break; case SR_CONF_OUTPUT_VOLTAGE_MAX: d = g_variant_get_double(data); - if (scpi_cmd(sdi, SCPI_CMD_SET_VOLTAGE_MAX, ch->name, d) < 0) - ret = SR_ERR; + ret = scpi_cmd(sdi, SCPI_CMD_SET_VOLTAGE_MAX, ch->name, d); break; case SR_CONF_OUTPUT_CURRENT_MAX: d = g_variant_get_double(data); - if (scpi_cmd(sdi, SCPI_CMD_SET_CURRENT_MAX, ch->name, d) < 0) - ret = SR_ERR; - break; - case SR_CONF_OUTPUT_ENABLED: - s = g_variant_get_boolean(data) ? "ON" : "OFF"; - if (scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_ENABLED, ch->name, s) < 0) - ret = SR_ERR; + ret = scpi_cmd(sdi, SCPI_CMD_SET_CURRENT_MAX, ch->name, d); break; case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED: s = g_variant_get_boolean(data) ? "ON" : "OFF"; - if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_ENABLED, - ch->name, s) < 0) - ret = SR_ERR; + ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_ENABLED, + ch->name, s); break; case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD: d = g_variant_get_double(data); - if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, - ch->name, d) < 0) - ret = SR_ERR; + ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, + ch->name, d); break; case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED: s = g_variant_get_boolean(data) ? "ON" : "OFF"; - if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLED, - ch->name, s) < 0) - ret = SR_ERR; + ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLED, + ch->name, s); break; case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD: d = g_variant_get_double(data); - if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, - ch->name, d) < 0) - ret = SR_ERR; + ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, + ch->name, d); break; default: ret = SR_ERR_NA; @@ -462,6 +402,7 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, sizeof(int32_t)); break; case SR_CONF_OUTPUT_CHANNEL_CONFIG: + /* Not used. */ i = 0; if (devc->device->features & PPS_INDEPENDENT) s[i++] = "Independent"; diff --git a/src/hardware/scpi-pps/protocol.c b/src/hardware/scpi-pps/protocol.c index b6049dc3..bdb4fe40 100644 --- a/src/hardware/scpi-pps/protocol.c +++ b/src/hardware/scpi-pps/protocol.c @@ -21,13 +21,10 @@ #include #include "protocol.h" -SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi, int command, ...) +SR_PRIV char *scpi_cmd_get(const struct sr_dev_inst *sdi, int command) { - va_list args; struct dev_context *devc; - struct sr_scpi_dev_inst *scpi; unsigned int i; - int ret; char *cmd; devc = sdi->priv; @@ -38,7 +35,18 @@ SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi, int command, ...) break; } } - if (!cmd) { + + return cmd; +} + +SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi, int command, ...) +{ + struct sr_scpi_dev_inst *scpi; + va_list args; + int ret; + char *cmd; + + if (!(cmd = scpi_cmd_get(sdi, command))) { /* Device does not implement this command, that's OK. */ return SR_OK_CONTINUE; } @@ -51,6 +59,47 @@ SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi, int command, ...) return ret; } +SR_PRIV int scpi_cmd_resp(const struct sr_dev_inst *sdi, GVariant **gvar, + const GVariantType *gvtype, int command, ...) +{ + struct sr_scpi_dev_inst *scpi; + va_list args; + double d; + int ret; + char *cmd, *s; + + if (!(cmd = scpi_cmd_get(sdi, command))) { + /* Device does not implement this command, that's OK. */ + return SR_OK_CONTINUE; + } + + scpi = sdi->conn; + va_start(args, command); + ret = sr_scpi_send_variadic(scpi, cmd, args); + va_end(args); + if (ret != SR_OK) + return ret; + + if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_BOOLEAN)) { + if ((ret = sr_scpi_get_string(scpi, NULL, &s)) != SR_OK) + return ret; + if (!strcasecmp(s, "ON") || !strcasecmp(s, "1") || !strcasecmp(s, "YES")) + *gvar = g_variant_new_boolean(TRUE); + else if (!strcasecmp(s, "OFF") || !strcasecmp(s, "0") || !strcasecmp(s, "NO")) + *gvar = g_variant_new_boolean(FALSE); + else + ret = SR_ERR; + } if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_DOUBLE)) { + if ((ret = sr_scpi_get_double(scpi, NULL, &d)) == SR_OK) + *gvar = g_variant_new_double(d); + } if (g_variant_type_equal(gvtype, G_VARIANT_TYPE_STRING)) { + if ((ret = sr_scpi_get_string(scpi, NULL, &s)) == SR_OK) + *gvar = g_variant_new_string(s); + } + + return ret; +} + SR_PRIV int scpi_pps_receive_data(int fd, int revents, void *cb_data) { struct dev_context *devc; diff --git a/src/hardware/scpi-pps/protocol.h b/src/hardware/scpi-pps/protocol.h index fc332ed7..247e41fb 100644 --- a/src/hardware/scpi-pps/protocol.h +++ b/src/hardware/scpi-pps/protocol.h @@ -51,8 +51,6 @@ enum pps_scpi_cmds { SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE, SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, - SCPI_CMD_GET_OUTPUT_CHANNEL_CONFIG, - SCPI_CMD_SET_OUTPUT_CHANNEL_CONFIG, }; /* @@ -129,7 +127,10 @@ struct dev_context { }; const char *get_vendor(const char *raw_vendor); +SR_PRIV char *scpi_cmd_get(const struct sr_dev_inst *sdi, int command); SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi, int command, ...); +SR_PRIV int scpi_cmd_resp(const struct sr_dev_inst *sdi, GVariant **gvar, + const GVariantType *gvtype, int command, ...); SR_PRIV int scpi_pps_receive_data(int fd, int revents, void *cb_data); #endif