]> sigrok.org Git - libsigrok.git/commitdiff
hp-3457a: Implement AC, ACDC, and four-wire resistance modes
authorAlexandru Gagniuc <redacted>
Mon, 4 Apr 2016 01:38:53 +0000 (18:38 -0700)
committerUwe Hermann <redacted>
Sat, 23 Apr 2016 15:44:26 +0000 (17:44 +0200)
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.

src/hardware/hp-3457a/api.c
src/hardware/hp-3457a/protocol.c
src/hardware/hp-3457a/protocol.h

index d19e0827571e46b308ab3783bc6c729cbea17f83..1b652bdd9a0deaf13462da67fd7352c023b4690b 100644 (file)
@@ -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:
index fca9e24b1faff20f91b0c2b0513af424ca744c68..bfc7902575bc92699a59f2ea7991968ed3b35435 100644 (file)
 #include <scpi.h>
 #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);
index 407756eb76428fb8a20e9d5f1c6a5cae52bc975f..64abadfd9fe55b4447dc4c6f36a820f06b0ae659 100644 (file)
@@ -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