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)
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;
}
}
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;
}
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;
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;
sizeof(int32_t));
break;
case SR_CONF_OUTPUT_CHANNEL_CONFIG:
+ /* Not used. */
i = 0;
if (devc->device->features & PPS_INDEPENDENT)
s[i++] = "Independent";
#include <stdarg.h>
#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;
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;
}
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;