scpi: Make helper functions from scpi-pps available library-wide.
This commit is contained in:
parent
5a1afc0907
commit
91ef511db2
|
@ -92,6 +92,7 @@ libsigrok_la_SOURCES += \
|
||||||
# SCPI support
|
# SCPI support
|
||||||
libsigrok_la_SOURCES += \
|
libsigrok_la_SOURCES += \
|
||||||
src/scpi/scpi.c \
|
src/scpi/scpi.c \
|
||||||
|
src/scpi/helpers.c \
|
||||||
src/scpi/scpi_tcp.c
|
src/scpi/scpi_tcp.c
|
||||||
if NEED_RPC
|
if NEED_RPC
|
||||||
libsigrok_la_SOURCES += \
|
libsigrok_la_SOURCES += \
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include "scpi.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
SR_PRIV struct sr_dev_driver scpi_pps_driver_info;
|
SR_PRIV struct sr_dev_driver scpi_pps_driver_info;
|
||||||
|
@ -72,7 +73,7 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
|
||||||
|
|
||||||
device = NULL;
|
device = NULL;
|
||||||
for (i = 0; i < num_pps_profiles; i++) {
|
for (i = 0; i < num_pps_profiles; i++) {
|
||||||
vendor = get_vendor(hw_info->manufacturer);
|
vendor = sr_vendor_alias(hw_info->manufacturer);
|
||||||
if (strcasecmp(vendor, pps_profiles[i].vendor))
|
if (strcasecmp(vendor, pps_profiles[i].vendor))
|
||||||
continue;
|
continue;
|
||||||
model_re = g_regex_new(pps_profiles[i].model, 0, 0, NULL);
|
model_re = g_regex_new(pps_profiles[i].model, 0, 0, NULL);
|
||||||
|
@ -128,7 +129,7 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
|
||||||
for (ch_num = 0; ch_num < num_channels; ch_num++) {
|
for (ch_num = 0; ch_num < num_channels; ch_num++) {
|
||||||
/* Create one channel per measurable output unit. */
|
/* Create one channel per measurable output unit. */
|
||||||
for (i = 0; i < ARRAY_SIZE(pci); i++) {
|
for (i = 0; i < ARRAY_SIZE(pci); i++) {
|
||||||
if (!scpi_cmd_get(sdi, pci[i].command))
|
if (!scpi_cmd_get(devc->device->commands, pci[i].command))
|
||||||
continue;
|
continue;
|
||||||
g_snprintf(ch_name, 16, "%s%s", pci[i].prefix,
|
g_snprintf(ch_name, 16, "%s%s", pci[i].prefix,
|
||||||
channels[ch_num].name);
|
channels[ch_num].name);
|
||||||
|
@ -165,7 +166,7 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
|
||||||
sr_scpi_hw_info_free(hw_info);
|
sr_scpi_hw_info_free(hw_info);
|
||||||
hw_info = NULL;
|
hw_info = NULL;
|
||||||
|
|
||||||
scpi_cmd(sdi, SCPI_CMD_LOCAL);
|
scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
|
||||||
sr_scpi_close(scpi);
|
sr_scpi_close(scpi);
|
||||||
|
|
||||||
return sdi;
|
return sdi;
|
||||||
|
@ -201,13 +202,15 @@ static int dev_open(struct sr_dev_inst *sdi)
|
||||||
|
|
||||||
sdi->status = SR_ST_ACTIVE;
|
sdi->status = SR_ST_ACTIVE;
|
||||||
|
|
||||||
scpi_cmd(sdi, SCPI_CMD_REMOTE);
|
devc = sdi->priv;
|
||||||
|
scpi_cmd(sdi, devc->device->commands, SCPI_CMD_REMOTE);
|
||||||
devc = sdi->priv;
|
devc = sdi->priv;
|
||||||
devc->beeper_was_set = FALSE;
|
devc->beeper_was_set = FALSE;
|
||||||
if (scpi_cmd_resp(sdi, &beeper, G_VARIANT_TYPE_BOOLEAN, SCPI_CMD_BEEPER) == SR_OK) {
|
if (scpi_cmd_resp(sdi, devc->device->commands, &beeper,
|
||||||
|
G_VARIANT_TYPE_BOOLEAN, SCPI_CMD_BEEPER) == SR_OK) {
|
||||||
if (g_variant_get_boolean(beeper)) {
|
if (g_variant_get_boolean(beeper)) {
|
||||||
devc->beeper_was_set = TRUE;
|
devc->beeper_was_set = TRUE;
|
||||||
scpi_cmd(sdi, SCPI_CMD_BEEPER_DISABLE);
|
scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_DISABLE);
|
||||||
}
|
}
|
||||||
g_variant_unref(beeper);
|
g_variant_unref(beeper);
|
||||||
}
|
}
|
||||||
|
@ -227,8 +230,8 @@ static int dev_close(struct sr_dev_inst *sdi)
|
||||||
scpi = sdi->conn;
|
scpi = sdi->conn;
|
||||||
if (scpi) {
|
if (scpi) {
|
||||||
if (devc->beeper_was_set)
|
if (devc->beeper_was_set)
|
||||||
scpi_cmd(sdi, SCPI_CMD_BEEPER_ENABLE);
|
scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_ENABLE);
|
||||||
scpi_cmd(sdi, SCPI_CMD_LOCAL);
|
scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
|
||||||
sr_scpi_close(scpi);
|
sr_scpi_close(scpi);
|
||||||
sdi->status = SR_ST_INACTIVE;
|
sdi->status = SR_ST_INACTIVE;
|
||||||
}
|
}
|
||||||
|
@ -258,6 +261,7 @@ static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *s
|
||||||
const GVariantType *gvtype;
|
const GVariantType *gvtype;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int cmd, ret;
|
int cmd, ret;
|
||||||
|
char *s;
|
||||||
|
|
||||||
if (!sdi)
|
if (!sdi)
|
||||||
return SR_ERR_ARG;
|
return SR_ERR_ARG;
|
||||||
|
@ -347,12 +351,33 @@ static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *s
|
||||||
gvtype = G_VARIANT_TYPE_STRING;
|
gvtype = G_VARIANT_TYPE_STRING;
|
||||||
cmd = SCPI_CMD_GET_OUTPUT_REGULATION;
|
cmd = SCPI_CMD_GET_OUTPUT_REGULATION;
|
||||||
}
|
}
|
||||||
if (gvtype) {
|
if (!gvtype)
|
||||||
if (cg)
|
return SR_ERR_NA;
|
||||||
select_channel(sdi, cg->channels->data);
|
|
||||||
ret = scpi_cmd_resp(sdi, data, gvtype, cmd);
|
if (cg)
|
||||||
} else
|
select_channel(sdi, cg->channels->data);
|
||||||
ret = SR_ERR_NA;
|
ret = scpi_cmd_resp(sdi, devc->device->commands, data, gvtype, cmd);
|
||||||
|
|
||||||
|
if (cmd == SCPI_CMD_GET_OUTPUT_REGULATION) {
|
||||||
|
/*
|
||||||
|
* The Rigol DP800 series return CV/CC/UR, Philips PM2800
|
||||||
|
* return VOLT/CURR. We always return a GVariant string in
|
||||||
|
* the Rigol notation.
|
||||||
|
*/
|
||||||
|
if ((ret = sr_scpi_get_string(sdi->conn, NULL, &s)) != SR_OK)
|
||||||
|
return ret;
|
||||||
|
if (!strcmp(s, "CV") || !strcmp(s, "VOLT")) {
|
||||||
|
*data = g_variant_new_string("CV");
|
||||||
|
} else if (!strcmp(s, "CC") || !strcmp(s, "CURR")) {
|
||||||
|
*data = g_variant_new_string("CC");
|
||||||
|
} else if (!strcmp(s, "UR")) {
|
||||||
|
*data = g_variant_new_string("UR");
|
||||||
|
} else {
|
||||||
|
sr_dbg("Unknown response to SCPI_CMD_GET_OUTPUT_REGULATION: %s", s);
|
||||||
|
ret = SR_ERR_DATA;
|
||||||
|
}
|
||||||
|
g_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -360,6 +385,7 @@ static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *s
|
||||||
static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
|
static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
|
||||||
const struct sr_channel_group *cg)
|
const struct sr_channel_group *cg)
|
||||||
{
|
{
|
||||||
|
struct dev_context *devc;
|
||||||
double d;
|
double d;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -373,51 +399,65 @@ static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sd
|
||||||
/* Channel group specified. */
|
/* Channel group specified. */
|
||||||
select_channel(sdi, cg->channels->data);
|
select_channel(sdi, cg->channels->data);
|
||||||
|
|
||||||
|
devc = sdi->priv;
|
||||||
ret = SR_OK;
|
ret = SR_OK;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case SR_CONF_ENABLED:
|
case SR_CONF_ENABLED:
|
||||||
if (g_variant_get_boolean(data))
|
if (g_variant_get_boolean(data))
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_ENABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OUTPUT_ENABLE);
|
||||||
else
|
else
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_DISABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OUTPUT_DISABLE);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_VOLTAGE_TARGET:
|
case SR_CONF_VOLTAGE_TARGET:
|
||||||
d = g_variant_get_double(data);
|
d = g_variant_get_double(data);
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_VOLTAGE_TARGET, d);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_VOLTAGE_TARGET, d);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_OUTPUT_FREQUENCY_TARGET:
|
case SR_CONF_OUTPUT_FREQUENCY_TARGET:
|
||||||
d = g_variant_get_double(data);
|
d = g_variant_get_double(data);
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_FREQUENCY_TARGET, d);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_FREQUENCY_TARGET, d);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_CURRENT_LIMIT:
|
case SR_CONF_CURRENT_LIMIT:
|
||||||
d = g_variant_get_double(data);
|
d = g_variant_get_double(data);
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_CURRENT_LIMIT, d);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_CURRENT_LIMIT, d);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
|
case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
|
||||||
if (g_variant_get_boolean(data))
|
if (g_variant_get_boolean(data))
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_ENABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_ENABLE);
|
||||||
else
|
else
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_DISABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_DISABLE);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
|
case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
|
||||||
d = g_variant_get_double(data);
|
d = g_variant_get_double(data);
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, d);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, d);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
|
case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
|
||||||
if (g_variant_get_boolean(data))
|
if (g_variant_get_boolean(data))
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLE);
|
||||||
else
|
else
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_DISABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_CURRENT_PROTECTION_DISABLE);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
|
case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
|
||||||
d = g_variant_get_double(data);
|
d = g_variant_get_double(data);
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, d);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, d);
|
||||||
break;
|
break;
|
||||||
case SR_CONF_OVER_TEMPERATURE_PROTECTION:
|
case SR_CONF_OVER_TEMPERATURE_PROTECTION:
|
||||||
if (g_variant_get_boolean(data))
|
if (g_variant_get_boolean(data))
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_ENABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_ENABLE);
|
||||||
else
|
else
|
||||||
ret = scpi_cmd(sdi, SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_DISABLE);
|
ret = scpi_cmd(sdi, devc->device->commands,
|
||||||
|
SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_DISABLE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = SR_ERR_NA;
|
ret = SR_ERR_NA;
|
||||||
|
@ -536,8 +576,7 @@ static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_acquisition_start(const struct sr_dev_inst *sdi,
|
static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
|
||||||
void *cb_data)
|
|
||||||
{
|
{
|
||||||
struct dev_context *devc;
|
struct dev_context *devc;
|
||||||
struct sr_scpi_dev_inst *scpi;
|
struct sr_scpi_dev_inst *scpi;
|
||||||
|
@ -572,7 +611,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi,
|
||||||
cmd = SCPI_CMD_GET_MEAS_POWER;
|
cmd = SCPI_CMD_GET_MEAS_POWER;
|
||||||
else
|
else
|
||||||
return SR_ERR;
|
return SR_ERR;
|
||||||
scpi_cmd(sdi, cmd, pch->hwname);
|
scpi_cmd(sdi, devc->device->commands, cmd, pch->hwname);
|
||||||
|
|
||||||
return SR_OK;
|
return SR_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,27 +26,6 @@
|
||||||
#define CH_IDX(x) (1 << x)
|
#define CH_IDX(x) (1 << x)
|
||||||
#define FREQ_DC_ONLY {0, 0, 0}
|
#define FREQ_DC_ONLY {0, 0, 0}
|
||||||
|
|
||||||
static const char *pps_vendors[][2] = {
|
|
||||||
{ "RIGOL TECHNOLOGIES", "Rigol" },
|
|
||||||
{ "HEWLETT-PACKARD", "HP" },
|
|
||||||
{ "PHILIPS", "Philips" },
|
|
||||||
{ "CHROMA", "Chroma" },
|
|
||||||
{ "Chroma ATE", "Chroma" },
|
|
||||||
{ "Agilent Technologies", "Agilent" },
|
|
||||||
};
|
|
||||||
|
|
||||||
SR_PRIV const char *get_vendor(const char *raw_vendor)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(pps_vendors); i++) {
|
|
||||||
if (!strcasecmp(raw_vendor, pps_vendors[i][0]))
|
|
||||||
return pps_vendors[i][1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return raw_vendor;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint32_t devopts_none[] = { };
|
static const uint32_t devopts_none[] = { };
|
||||||
|
|
||||||
/* Agilent/Keysight N5700A series */
|
/* Agilent/Keysight N5700A series */
|
||||||
|
@ -96,6 +75,7 @@ static const struct scpi_command agilent_n5700a_cmd[] = {
|
||||||
/* Current limit (CC mode) and OCP are set using the same command. */
|
/* Current limit (CC mode) and OCP are set using the same command. */
|
||||||
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR?" },
|
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR?" },
|
||||||
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR %.6f" },
|
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR %.6f" },
|
||||||
|
ALL_ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Chroma 61600 series AC source */
|
/* Chroma 61600 series AC source */
|
||||||
|
@ -141,6 +121,7 @@ static const struct scpi_command chroma_61604_cmd[] = {
|
||||||
/* This is not a current limit mode. It is overcurrent protection. */
|
/* This is not a current limit mode. It is overcurrent protection. */
|
||||||
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:LIM?" },
|
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:LIM?" },
|
||||||
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:LIM %.2f" },
|
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:LIM %.2f" },
|
||||||
|
ALL_ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Chroma 62000 series DC source */
|
/* Chroma 62000 series DC source */
|
||||||
|
@ -183,6 +164,7 @@ static const struct scpi_command chroma_62000_cmd[] = {
|
||||||
{ SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, ":SOUR:VOLT:PROT:HIGH %.6f" },
|
{ SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, ":SOUR:VOLT:PROT:HIGH %.6f" },
|
||||||
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:PROT:HIGH?" },
|
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:PROT:HIGH?" },
|
||||||
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:PROT:HIGH %.6f" },
|
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":SOUR:CURR:PROT:HIGH %.6f" },
|
||||||
|
ALL_ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
static int chroma_62000p_probe_channels(struct sr_dev_inst *sdi,
|
static int chroma_62000p_probe_channels(struct sr_dev_inst *sdi,
|
||||||
|
@ -307,6 +289,7 @@ static const struct scpi_command rigol_dp800_cmd[] = {
|
||||||
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE, ":OUTP:OCP:QUES?" },
|
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE, ":OUTP:OCP:QUES?" },
|
||||||
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":OUTP:OCP:VAL?" },
|
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD, ":OUTP:OCP:VAL?" },
|
||||||
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":OUTP:OCP:VAL %.6f" },
|
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":OUTP:OCP:VAL %.6f" },
|
||||||
|
ALL_ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
/* HP 663xx series */
|
/* HP 663xx series */
|
||||||
|
@ -337,6 +320,7 @@ static const struct scpi_command hp_6632b_cmd[] = {
|
||||||
{ SCPI_CMD_SET_VOLTAGE_TARGET, ":SOUR:VOLT %.6f" },
|
{ SCPI_CMD_SET_VOLTAGE_TARGET, ":SOUR:VOLT %.6f" },
|
||||||
{ SCPI_CMD_GET_CURRENT_LIMIT, ":SOUR:CURR?" },
|
{ SCPI_CMD_GET_CURRENT_LIMIT, ":SOUR:CURR?" },
|
||||||
{ SCPI_CMD_SET_CURRENT_LIMIT, ":SOUR:CURR %.6f" },
|
{ SCPI_CMD_SET_CURRENT_LIMIT, ":SOUR:CURR %.6f" },
|
||||||
|
ALL_ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Philips/Fluke PM2800 series */
|
/* Philips/Fluke PM2800 series */
|
||||||
|
@ -483,6 +467,7 @@ static const struct scpi_command philips_pm2800_cmd[] = {
|
||||||
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLE, ":SOUR:CURR:PROT:STAT ON" },
|
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLE, ":SOUR:CURR:PROT:STAT ON" },
|
||||||
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_DISABLE, ":SOUR:CURR:PROT:STAT OFF" },
|
{ SCPI_CMD_SET_OVER_CURRENT_PROTECTION_DISABLE, ":SOUR:CURR:PROT:STAT OFF" },
|
||||||
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE, ":SOUR:CURR:PROT:TRIP?" },
|
{ SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE, ":SOUR:CURR:PROT:TRIP?" },
|
||||||
|
ALL_ZERO
|
||||||
};
|
};
|
||||||
|
|
||||||
SR_PRIV const struct scpi_pps pps_profiles[] = {
|
SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
|
@ -492,7 +477,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(agilent_n5700a_devopts_cg),
|
ARRAY_AND_SIZE(agilent_n5700a_devopts_cg),
|
||||||
ARRAY_AND_SIZE(agilent_n5767a_ch),
|
ARRAY_AND_SIZE(agilent_n5767a_ch),
|
||||||
ARRAY_AND_SIZE(agilent_n5767a_cg),
|
ARRAY_AND_SIZE(agilent_n5767a_cg),
|
||||||
ARRAY_AND_SIZE(agilent_n5700a_cmd),
|
agilent_n5700a_cmd,
|
||||||
.probe_channels = NULL,
|
.probe_channels = NULL,
|
||||||
},
|
},
|
||||||
/* Chroma 61604 */
|
/* Chroma 61604 */
|
||||||
|
@ -501,7 +486,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(chroma_61604_devopts_cg),
|
ARRAY_AND_SIZE(chroma_61604_devopts_cg),
|
||||||
ARRAY_AND_SIZE(chroma_61604_ch),
|
ARRAY_AND_SIZE(chroma_61604_ch),
|
||||||
ARRAY_AND_SIZE(chroma_61604_cg),
|
ARRAY_AND_SIZE(chroma_61604_cg),
|
||||||
ARRAY_AND_SIZE(chroma_61604_cmd),
|
chroma_61604_cmd,
|
||||||
.probe_channels = NULL,
|
.probe_channels = NULL,
|
||||||
},
|
},
|
||||||
/* Chroma 62000 series */
|
/* Chroma 62000 series */
|
||||||
|
@ -510,7 +495,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(chroma_62000_devopts_cg),
|
ARRAY_AND_SIZE(chroma_62000_devopts_cg),
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
ARRAY_AND_SIZE(chroma_62000_cmd),
|
chroma_62000_cmd,
|
||||||
.probe_channels = chroma_62000p_probe_channels,
|
.probe_channels = chroma_62000p_probe_channels,
|
||||||
},
|
},
|
||||||
/* HP 6632B */
|
/* HP 6632B */
|
||||||
|
@ -519,7 +504,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(devopts_none),
|
ARRAY_AND_SIZE(devopts_none),
|
||||||
ARRAY_AND_SIZE(hp_6632b_ch),
|
ARRAY_AND_SIZE(hp_6632b_ch),
|
||||||
ARRAY_AND_SIZE(hp_6632b_cg),
|
ARRAY_AND_SIZE(hp_6632b_cg),
|
||||||
ARRAY_AND_SIZE(hp_6632b_cmd),
|
hp_6632b_cmd,
|
||||||
.probe_channels = NULL,
|
.probe_channels = NULL,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -529,7 +514,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(rigol_dp800_devopts_cg),
|
ARRAY_AND_SIZE(rigol_dp800_devopts_cg),
|
||||||
ARRAY_AND_SIZE(rigol_dp821a_ch),
|
ARRAY_AND_SIZE(rigol_dp821a_ch),
|
||||||
ARRAY_AND_SIZE(rigol_dp820_cg),
|
ARRAY_AND_SIZE(rigol_dp820_cg),
|
||||||
ARRAY_AND_SIZE(rigol_dp800_cmd),
|
rigol_dp800_cmd,
|
||||||
.probe_channels = NULL,
|
.probe_channels = NULL,
|
||||||
},
|
},
|
||||||
{ "Rigol", "^DP831A$", PPS_OTP,
|
{ "Rigol", "^DP831A$", PPS_OTP,
|
||||||
|
@ -537,7 +522,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(rigol_dp800_devopts_cg),
|
ARRAY_AND_SIZE(rigol_dp800_devopts_cg),
|
||||||
ARRAY_AND_SIZE(rigol_dp831_ch),
|
ARRAY_AND_SIZE(rigol_dp831_ch),
|
||||||
ARRAY_AND_SIZE(rigol_dp830_cg),
|
ARRAY_AND_SIZE(rigol_dp830_cg),
|
||||||
ARRAY_AND_SIZE(rigol_dp800_cmd),
|
rigol_dp800_cmd,
|
||||||
.probe_channels = NULL,
|
.probe_channels = NULL,
|
||||||
},
|
},
|
||||||
{ "Rigol", "^(DP832|DP832A)$", PPS_OTP,
|
{ "Rigol", "^(DP832|DP832A)$", PPS_OTP,
|
||||||
|
@ -545,7 +530,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(rigol_dp800_devopts_cg),
|
ARRAY_AND_SIZE(rigol_dp800_devopts_cg),
|
||||||
ARRAY_AND_SIZE(rigol_dp832_ch),
|
ARRAY_AND_SIZE(rigol_dp832_ch),
|
||||||
ARRAY_AND_SIZE(rigol_dp830_cg),
|
ARRAY_AND_SIZE(rigol_dp830_cg),
|
||||||
ARRAY_AND_SIZE(rigol_dp800_cmd),
|
rigol_dp800_cmd,
|
||||||
.probe_channels = NULL,
|
.probe_channels = NULL,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -555,7 +540,7 @@ SR_PRIV const struct scpi_pps pps_profiles[] = {
|
||||||
ARRAY_AND_SIZE(philips_pm2800_devopts_cg),
|
ARRAY_AND_SIZE(philips_pm2800_devopts_cg),
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
ARRAY_AND_SIZE(philips_pm2800_cmd),
|
philips_pm2800_cmd,
|
||||||
philips_pm2800_probe_channels,
|
philips_pm2800_probe_channels,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,112 +20,9 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include "scpi.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
SR_PRIV const char *scpi_cmd_get(const struct sr_dev_inst *sdi, int command)
|
|
||||||
{
|
|
||||||
struct dev_context *devc;
|
|
||||||
unsigned int i;
|
|
||||||
const char *cmd;
|
|
||||||
|
|
||||||
devc = sdi->priv;
|
|
||||||
cmd = NULL;
|
|
||||||
for (i = 0; i < devc->device->num_commands; i++) {
|
|
||||||
if (devc->device->commands[i].command == command) {
|
|
||||||
cmd = devc->device->commands[i].string;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
const char *cmd;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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 *s;
|
|
||||||
const char *cmd;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* Non-standard data type responses. */
|
|
||||||
if (command == SCPI_CMD_GET_OUTPUT_REGULATION) {
|
|
||||||
/*
|
|
||||||
* The Rigol DP800 series return CV/CC/UR, Philips PM2800
|
|
||||||
* return VOLT/CURR. We always return a GVariant string in
|
|
||||||
* the Rigol notation.
|
|
||||||
*/
|
|
||||||
if ((ret = sr_scpi_get_string(scpi, NULL, &s)) != SR_OK)
|
|
||||||
return ret;
|
|
||||||
if (!strcmp(s, "CV") || !strcmp(s, "VOLT")) {
|
|
||||||
*gvar = g_variant_new_string("CV");
|
|
||||||
} else if (!strcmp(s, "CC") || !strcmp(s, "CURR")) {
|
|
||||||
*gvar = g_variant_new_string("CC");
|
|
||||||
} else if (!strcmp(s, "UR")) {
|
|
||||||
*gvar = g_variant_new_string("UR");
|
|
||||||
} else {
|
|
||||||
sr_dbg("Unknown response to SCPI_CMD_GET_OUTPUT_REGULATION: %s", s);
|
|
||||||
ret = SR_ERR_DATA;
|
|
||||||
}
|
|
||||||
g_free(s);
|
|
||||||
} else {
|
|
||||||
/* Straight SCPI getters to GVariant types. */
|
|
||||||
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;
|
|
||||||
g_free(s);
|
|
||||||
} 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 select_channel(const struct sr_dev_inst *sdi, struct sr_channel *ch)
|
SR_PRIV int select_channel(const struct sr_dev_inst *sdi, struct sr_channel *ch)
|
||||||
{
|
{
|
||||||
struct dev_context *devc;
|
struct dev_context *devc;
|
||||||
|
@ -149,7 +46,8 @@ SR_PRIV int select_channel(const struct sr_dev_inst *sdi, struct sr_channel *ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = scpi_cmd(sdi, SCPI_CMD_SELECT_CHANNEL, new_pch->hwname)) >= 0)
|
if ((ret = scpi_cmd(sdi, devc->device->commands, SCPI_CMD_SELECT_CHANNEL,
|
||||||
|
new_pch->hwname)) >= 0)
|
||||||
devc->cur_channel = ch;
|
devc->cur_channel = ch;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -235,7 +133,7 @@ SR_PRIV int scpi_pps_receive_data(int fd, int revents, void *cb_data)
|
||||||
cmd = SCPI_CMD_GET_MEAS_POWER;
|
cmd = SCPI_CMD_GET_MEAS_POWER;
|
||||||
else
|
else
|
||||||
return SR_ERR;
|
return SR_ERR;
|
||||||
scpi_cmd(sdi, cmd);
|
scpi_cmd(sdi, devc->device->commands, cmd);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <libsigrok/libsigrok.h>
|
#include <libsigrok/libsigrok.h>
|
||||||
#include "libsigrok-internal.h"
|
#include "libsigrok-internal.h"
|
||||||
|
#include "scpi.h"
|
||||||
|
|
||||||
#define LOG_PREFIX "scpi-pps"
|
#define LOG_PREFIX "scpi-pps"
|
||||||
|
|
||||||
|
@ -92,7 +93,6 @@ struct scpi_pps {
|
||||||
const struct channel_group_spec *channel_groups;
|
const struct channel_group_spec *channel_groups;
|
||||||
unsigned int num_channel_groups;
|
unsigned int num_channel_groups;
|
||||||
const struct scpi_command *commands;
|
const struct scpi_command *commands;
|
||||||
unsigned int num_commands;
|
|
||||||
int (*probe_channels) (struct sr_dev_inst *sdi, struct sr_scpi_hw_info *hwinfo,
|
int (*probe_channels) (struct sr_dev_inst *sdi, struct sr_scpi_hw_info *hwinfo,
|
||||||
struct channel_spec **channels, unsigned int *num_channels,
|
struct channel_spec **channels, unsigned int *num_channels,
|
||||||
struct channel_group_spec **channel_groups, unsigned int *num_channel_groups);
|
struct channel_group_spec **channel_groups, unsigned int *num_channel_groups);
|
||||||
|
@ -106,11 +106,6 @@ struct channel_spec {
|
||||||
float frequency[3];
|
float frequency[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct scpi_command {
|
|
||||||
int command;
|
|
||||||
const char *string;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct channel_group_spec {
|
struct channel_group_spec {
|
||||||
const char *name;
|
const char *name;
|
||||||
uint64_t channel_index_mask;
|
uint64_t channel_index_mask;
|
||||||
|
@ -160,10 +155,6 @@ SR_PRIV extern unsigned int num_pps_profiles;
|
||||||
SR_PRIV extern const struct scpi_pps pps_profiles[];
|
SR_PRIV extern const struct scpi_pps pps_profiles[];
|
||||||
|
|
||||||
SR_PRIV const char *get_vendor(const char *raw_vendor);
|
SR_PRIV const char *get_vendor(const char *raw_vendor);
|
||||||
SR_PRIV const 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 select_channel(const struct sr_dev_inst *sdi, struct sr_channel *ch);
|
SR_PRIV int select_channel(const struct sr_dev_inst *sdi, struct sr_channel *ch);
|
||||||
SR_PRIV struct sr_channel *next_enabled_channel(const struct sr_dev_inst *sdi,
|
SR_PRIV struct sr_channel *next_enabled_channel(const struct sr_dev_inst *sdi,
|
||||||
struct sr_channel *cur_channel);
|
struct sr_channel *cur_channel);
|
||||||
|
|
13
src/scpi.h
13
src/scpi.h
|
@ -58,6 +58,11 @@ enum {
|
||||||
SCPI_CMD_GET_SAMPLE_RATE_LIVE,
|
SCPI_CMD_GET_SAMPLE_RATE_LIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct scpi_command {
|
||||||
|
int command;
|
||||||
|
const char *string;
|
||||||
|
};
|
||||||
|
|
||||||
struct sr_scpi_hw_info {
|
struct sr_scpi_hw_info {
|
||||||
char *manufacturer;
|
char *manufacturer;
|
||||||
char *model;
|
char *model;
|
||||||
|
@ -125,4 +130,12 @@ SR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi,
|
||||||
struct sr_scpi_hw_info **scpi_response);
|
struct sr_scpi_hw_info **scpi_response);
|
||||||
SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info);
|
SR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info);
|
||||||
|
|
||||||
|
SR_PRIV const char *sr_vendor_alias(const char *raw_vendor);
|
||||||
|
SR_PRIV const char *scpi_cmd_get(const struct scpi_command *cmdtable, int command);
|
||||||
|
SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi,
|
||||||
|
const struct scpi_command *cmdtable, int command, ...);
|
||||||
|
SR_PRIV int scpi_cmd_resp(const struct sr_dev_inst *sdi,
|
||||||
|
const struct scpi_command *cmdtable,
|
||||||
|
GVariant **gvar, const GVariantType *gvtype, int command, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the libsigrok project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Bert Vermeulen <bert@biot.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <strings.h>
|
||||||
|
#include <libsigrok/libsigrok.h>
|
||||||
|
#include "libsigrok-internal.h"
|
||||||
|
#include "scpi.h"
|
||||||
|
|
||||||
|
#define LOG_PREFIX "scpi/helpers"
|
||||||
|
|
||||||
|
static const char *scpi_vendors[][2] = {
|
||||||
|
{ "HEWLETT-PACKARD", "HP" },
|
||||||
|
{ "Agilent Technologies", "Agilent" },
|
||||||
|
{ "RIGOL TECHNOLOGIES", "Rigol" },
|
||||||
|
{ "PHILIPS", "Philips" },
|
||||||
|
{ "CHROMA", "Chroma" },
|
||||||
|
{ "Chroma ATE", "Chroma" },
|
||||||
|
};
|
||||||
|
|
||||||
|
SR_PRIV const char *sr_vendor_alias(const char *raw_vendor)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(scpi_vendors); i++) {
|
||||||
|
if (!strcasecmp(raw_vendor, scpi_vendors[i][0]))
|
||||||
|
return scpi_vendors[i][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return raw_vendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
SR_PRIV const char *scpi_cmd_get(const struct scpi_command *cmdtable, int command)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
const char *cmd;
|
||||||
|
|
||||||
|
if (!cmdtable)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cmd = NULL;
|
||||||
|
for (i = 0; cmdtable[i].command; i++) {
|
||||||
|
if (cmdtable[i].command == command) {
|
||||||
|
cmd = cmdtable[i].string;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
SR_PRIV int scpi_cmd(const struct sr_dev_inst *sdi, const struct scpi_command *cmdtable,
|
||||||
|
int command, ...)
|
||||||
|
{
|
||||||
|
struct sr_scpi_dev_inst *scpi;
|
||||||
|
va_list args;
|
||||||
|
int ret;
|
||||||
|
const char *cmd;
|
||||||
|
|
||||||
|
if (!(cmd = scpi_cmd_get(cmdtable, command))) {
|
||||||
|
/* Device does not implement this command, that's OK. */
|
||||||
|
/* TODO: deprecate SR_OK_CONTINUE */
|
||||||
|
return SR_OK_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
scpi = sdi->conn;
|
||||||
|
va_start(args, command);
|
||||||
|
ret = sr_scpi_send_variadic(scpi, cmd, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
SR_PRIV int scpi_cmd_resp(const struct sr_dev_inst *sdi, const struct scpi_command *cmdtable,
|
||||||
|
GVariant **gvar, const GVariantType *gvtype, int command, ...)
|
||||||
|
{
|
||||||
|
struct sr_scpi_dev_inst *scpi;
|
||||||
|
va_list args;
|
||||||
|
double d;
|
||||||
|
int ret;
|
||||||
|
char *s;
|
||||||
|
const char *cmd;
|
||||||
|
|
||||||
|
if (!(cmd = scpi_cmd_get(cmdtable, 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;
|
||||||
|
|
||||||
|
/* Straight SCPI getters to GVariant types. */
|
||||||
|
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;
|
||||||
|
g_free(s);
|
||||||
|
} 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);
|
||||||
|
} else {
|
||||||
|
sr_err("Unable to convert to desired GVariant type.");
|
||||||
|
ret = SR_ERR_NA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in New Issue