From: Alexandru Gagniuc Date: Mon, 4 Apr 2016 01:38:53 +0000 (-0700) Subject: hp-3457a: Implement AC, ACDC, and four-wire resistance modes X-Git-Tag: libsigrok-0.5.0~492 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=2c04f943efb4f7590941c44c27d8ca5d831b82dd;p=libsigrok.git hp-3457a: Implement AC, ACDC, and four-wire resistance modes The driver did not look at the mq_flags provided with the SR_CONF_MEASURED_QUANTITY key, and it defaulted to DC measurements. Use the second member of the tuple provided by the config key, which represents the flags for the measurement, and set the instrument's measurement mode accordingly. --- diff --git a/src/hardware/hp-3457a/api.c b/src/hardware/hp-3457a/api.c index d19e0827..1b652bdd 100644 --- a/src/hardware/hp-3457a/api.c +++ b/src/hardware/hp-3457a/api.c @@ -242,6 +242,7 @@ static int config_set(uint32_t key, GVariant *data, { int ret; enum sr_mq mq; + enum sr_mqflag mq_flags; struct dev_context *devc; GVariant *tuple_child; @@ -260,7 +261,9 @@ static int config_set(uint32_t key, GVariant *data, case SR_CONF_MEASURED_QUANTITY: tuple_child = g_variant_get_child_value(data, 0); mq = g_variant_get_uint32(tuple_child); - ret = hp_3457a_set_mq(sdi, mq); + tuple_child = g_variant_get_child_value(data, 1); + mq_flags = g_variant_get_uint64(tuple_child); + ret = hp_3457a_set_mq(sdi, mq, mq_flags); g_variant_unref(tuple_child); break; case SR_CONF_ADC_POWERLINE_CYCLES: diff --git a/src/hardware/hp-3457a/protocol.c b/src/hardware/hp-3457a/protocol.c index fca9e24b..bfc79025 100644 --- a/src/hardware/hp-3457a/protocol.c +++ b/src/hardware/hp-3457a/protocol.c @@ -22,23 +22,26 @@ #include #include "protocol.h" +static int set_mq_volt(struct sr_scpi_dev_inst *scpi, enum sr_mqflag flags); +static int set_mq_amp(struct sr_scpi_dev_inst *scpi, enum sr_mqflag flags); +static int set_mq_ohm(struct sr_scpi_dev_inst *scpi, enum sr_mqflag flags); /* - * Currently, only DC voltage and current are supported, as switching to AC or - * AC+DC requires mq flags, which is not yet implemented. - * Four-wire resistance measurements are not implemented (See "OHMF" command). * The source for the frequency measurement can be either AC voltage, AC+DC * voltage, AC current, or AC+DC current. Configuring this is not yet * supported. For details, see "FSOURCE" command. + * The set_mode function is optional and can be set to NULL, but in that case + * a cmd string must be provided. */ static const struct { enum sr_mq mq; enum sr_unit unit; const char *cmd; + int (*set_mode)(struct sr_scpi_dev_inst *scpi, enum sr_mqflag flags); } sr_mq_to_cmd_map[] = { - { SR_MQ_VOLTAGE, SR_UNIT_VOLT, "DCV" }, - { SR_MQ_CURRENT, SR_UNIT_AMPERE, "DCI" }, - { SR_MQ_RESISTANCE, SR_UNIT_OHM, "OHM" }, - { SR_MQ_FREQUENCY, SR_UNIT_HERTZ, "FREQ" }, + { SR_MQ_VOLTAGE, SR_UNIT_VOLT, "DCV", set_mq_volt }, + { SR_MQ_CURRENT, SR_UNIT_AMPERE, "DCI", set_mq_amp }, + { SR_MQ_RESISTANCE, SR_UNIT_OHM, "OHM", set_mq_ohm }, + { SR_MQ_FREQUENCY, SR_UNIT_HERTZ, "FREQ", NULL }, }; static const struct rear_card_info rear_card_parameters[] = { @@ -60,7 +63,46 @@ static const struct rear_card_info rear_card_parameters[] = { } }; -SR_PRIV int hp_3457a_set_mq(const struct sr_dev_inst *sdi, enum sr_mq mq) +static int send_mq_ac_dc(struct sr_scpi_dev_inst *scpi, const char *mode, + enum sr_mqflag flags) +{ + const char *ac_flag, *dc_flag; + + if (flags & ~(SR_MQFLAG_AC | SR_MQFLAG_DC)) + return SR_ERR_NA; + + ac_flag = (flags & SR_MQFLAG_AC) ? "AC" : ""; + dc_flag = ""; + /* Must specify DC measurement when AC flag is not given. */ + if ((flags & SR_MQFLAG_DC) || !(flags & SR_MQFLAG_AC)) + dc_flag = "DC"; + + return sr_scpi_send(scpi, "%s%s%s", ac_flag, dc_flag, mode); +} + +static int set_mq_volt(struct sr_scpi_dev_inst *scpi, enum sr_mqflag flags) +{ + return send_mq_ac_dc(scpi, "V", flags); +} + +static int set_mq_amp(struct sr_scpi_dev_inst *scpi, enum sr_mqflag flags) +{ + return send_mq_ac_dc(scpi, "I", flags); +} + +static int set_mq_ohm(struct sr_scpi_dev_inst *scpi, enum sr_mqflag flags) +{ + const char *ohm_flag; + + if (flags & ~(SR_MQFLAG_FOUR_WIRE)) + return SR_ERR_NA; + + ohm_flag = (flags & SR_MQFLAG_FOUR_WIRE) ? "F" : ""; + return sr_scpi_send(scpi, "OHM%s", ohm_flag); +} + +SR_PRIV int hp_3457a_set_mq(const struct sr_dev_inst *sdi, enum sr_mq mq, + enum sr_mqflag mq_flags) { int ret; size_t i; @@ -70,9 +112,14 @@ SR_PRIV int hp_3457a_set_mq(const struct sr_dev_inst *sdi, enum sr_mq mq) for (i = 0; i < ARRAY_SIZE(sr_mq_to_cmd_map); i++) { if (sr_mq_to_cmd_map[i].mq != mq) continue; - ret = sr_scpi_send(scpi, sr_mq_to_cmd_map[i].cmd); + if (sr_mq_to_cmd_map[i].set_mode) { + ret = sr_mq_to_cmd_map[i].set_mode(scpi, mq_flags); + } else { + ret = sr_scpi_send(scpi, sr_mq_to_cmd_map[i].cmd); + } if (ret == SR_OK) { devc->measurement_mq = sr_mq_to_cmd_map[i].mq; + devc->measurement_mq_flags = mq_flags; devc->measurement_unit = sr_mq_to_cmd_map[i].unit; } return ret; @@ -258,6 +305,7 @@ static void acq_send_measurement(struct sr_dev_inst *sdi) analog.data = &measurement_workaround; meaning.mq = devc->measurement_mq; + meaning.mqflags = devc->measurement_mq_flags; meaning.unit = devc->measurement_unit; sr_session_send(sdi, &packet); diff --git a/src/hardware/hp-3457a/protocol.h b/src/hardware/hp-3457a/protocol.h index 407756eb..64abadfd 100644 --- a/src/hardware/hp-3457a/protocol.h +++ b/src/hardware/hp-3457a/protocol.h @@ -56,6 +56,7 @@ struct dev_context { /* Acquisition settings */ enum sr_mq measurement_mq; + enum sr_mqflag measurement_mq_flags; enum sr_unit measurement_unit; uint64_t limit_samples; float nplc; @@ -70,7 +71,8 @@ struct dev_context { SR_PRIV const struct rear_card_info *hp_3457a_probe_rear_card(struct sr_scpi_dev_inst *scpi); SR_PRIV int hp_3457a_receive_data(int fd, int revents, void *cb_data); -SR_PRIV int hp_3457a_set_mq(const struct sr_dev_inst *sdi, enum sr_mq mq); +SR_PRIV int hp_3457a_set_mq(const struct sr_dev_inst *sdi, enum sr_mq mq, + enum sr_mqflag mq_flags); SR_PRIV int hp_3457a_set_nplc(const struct sr_dev_inst *sdi, float nplc); #endif