X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fscpi-dmm%2Fapi.c;h=cdd4d7cdf2c14dee75e50ca6f36089ac30c3c260;hb=868fc65ec3acc575fee335a991aaae8177099de2;hp=1b62fb4385dcb11e045d10fcbf81379e16136f01;hpb=a16198316fc68440783ad1040ac8ddd9b918e67b;p=libsigrok.git diff --git a/src/hardware/scpi-dmm/api.c b/src/hardware/scpi-dmm/api.c index 1b62fb43..cdd4d7cd 100644 --- a/src/hardware/scpi-dmm/api.c +++ b/src/hardware/scpi-dmm/api.c @@ -50,18 +50,21 @@ static const struct scpi_command cmdset_agilent[] = { }; /* - * cmdset_hp is used for the 34401A, which was added to this code after the + * cmdset_hp is used for the 34401A, which was added to this code after the * 34405A and 34465A. It differs in starting the measurement with INIT: using * MEAS without a trailing '?' (as used for the 34405A) is not valid for the - * 34401A and gives an error. - * I'm surprised the same instruction sequence doesn't work and INIT may - * work for both, but I don't have the others to re-test. + * 34401A and gives an error. + * I'm surprised the same instruction sequence doesn't work and INIT may + * work for both, but I don't have the others to re-test. * - * On the 34401A, - * MEAS ? configures, arms, triggers and waits + * cmdset_hp also works well for the 34410A, using cmdset_agilent throws an + * error on 'MEAS' without a '?'. + * + * On the 34401A, + * MEAS ? configures, arms, triggers and waits * for a reading * CONF configures - * INIT prepares for triggering (trigger mode is not set, assumed + * INIT prepares for triggering (trigger mode is not set, assumed * internal - external might time out) * *OPC waits for completion, and * READ? retrieves the result @@ -77,6 +80,28 @@ static const struct scpi_command cmdset_hp[] = { ALL_ZERO, }; +static const struct scpi_command cmdset_gwinstek[] = { + { DMM_CMD_SETUP_REMOTE, "SYST:REM", }, + { DMM_CMD_SETUP_FUNC, "CONF:%s", }, + { DMM_CMD_QUERY_FUNC, "CONF:STAT:FUNC?", }, + { DMM_CMD_START_ACQ, "*CLS;SYST:REM", }, + { DMM_CMD_STOP_ACQ, "SYST:LOC", }, + { DMM_CMD_QUERY_VALUE, "VAL1?", }, + { DMM_CMD_QUERY_PREC, "SENS:DET:RATE?", }, + ALL_ZERO, +}; + +static const struct scpi_command cmdset_gwinstek_906x[] = { + { DMM_CMD_SETUP_REMOTE, "SYST:REM", }, + { DMM_CMD_SETUP_FUNC, "CONF:%s", }, + { DMM_CMD_QUERY_FUNC, "CONF?", }, + { DMM_CMD_START_ACQ, "*CLS;SYST:REM", }, + { DMM_CMD_STOP_ACQ, "SYST:LOC", }, + { DMM_CMD_QUERY_VALUE, "VAL1?", }, + { DMM_CMD_QUERY_PREC, "SENS:DET:RATE?", }, + ALL_ZERO, +}; + static const struct mqopt_item mqopts_agilent_34405a[] = { { SR_MQ_VOLTAGE, SR_MQFLAG_DC, "VOLT:DC", "VOLT ", NO_DFLT_PREC, }, { SR_MQ_VOLTAGE, SR_MQFLAG_AC, "VOLT:AC", "VOLT:AC ", NO_DFLT_PREC, }, @@ -103,20 +128,59 @@ static const struct mqopt_item mqopts_agilent_34401a[] = { { SR_MQ_TIME, 0, "PER", "PER ", NO_DFLT_PREC, }, }; +static const struct mqopt_item mqopts_gwinstek_gdm8200a[] = { + { SR_MQ_VOLTAGE, SR_MQFLAG_DC, "VOLT:DC", "01", NO_DFLT_PREC, }, + { SR_MQ_VOLTAGE, SR_MQFLAG_AC, "VOLT:AC", "02", NO_DFLT_PREC, }, + { SR_MQ_CURRENT, SR_MQFLAG_DC, "CURR:DC", "03", NO_DFLT_PREC, }, + { SR_MQ_CURRENT, SR_MQFLAG_AC, "CURR:AC", "04", NO_DFLT_PREC, }, + { SR_MQ_CURRENT, SR_MQFLAG_DC, "CURR:DC", "05", NO_DFLT_PREC, }, /* mA */ + { SR_MQ_CURRENT, SR_MQFLAG_AC, "CURR:AC", "06", NO_DFLT_PREC, }, /* mA */ + { SR_MQ_RESISTANCE, 0, "RES", "07", NO_DFLT_PREC, }, + { SR_MQ_RESISTANCE, SR_MQFLAG_FOUR_WIRE, "FRES", "16", NO_DFLT_PREC, }, + { SR_MQ_CONTINUITY, 0, "CONT", "13", -1, }, + { SR_MQ_VOLTAGE, SR_MQFLAG_DC | SR_MQFLAG_DIODE, "DIOD", "17", -4, }, + { SR_MQ_TEMPERATURE, 0, "TEMP", "09", NO_DFLT_PREC, }, /* Celsius */ + { SR_MQ_TEMPERATURE, 0, "TEMP", "15", NO_DFLT_PREC, }, /* Fahrenheit */ + { SR_MQ_FREQUENCY, 0, "FREQ", "08", NO_DFLT_PREC, }, + { SR_MQ_TIME, 0, "PER", "14", NO_DFLT_PREC, }, +}; + +static const struct mqopt_item mqopts_gwinstek_gdm906x[] = { + { SR_MQ_VOLTAGE, SR_MQFLAG_DC, "VOLT:DC", "VOLT ", NO_DFLT_PREC, }, + { SR_MQ_VOLTAGE, SR_MQFLAG_AC, "VOLT:AC", "VOLT:AC", NO_DFLT_PREC, }, + { SR_MQ_CURRENT, SR_MQFLAG_DC, "CURR:DC", "CURR ", NO_DFLT_PREC, }, + { SR_MQ_CURRENT, SR_MQFLAG_AC, "CURR:AC", "CURR:AC", NO_DFLT_PREC, }, + { SR_MQ_RESISTANCE, 0, "RES", "RES", NO_DFLT_PREC, }, + { SR_MQ_RESISTANCE, SR_MQFLAG_FOUR_WIRE, "FRES", "FRES", NO_DFLT_PREC, }, + { SR_MQ_CONTINUITY, 0, "CONT", "CONT", -1, }, + { SR_MQ_VOLTAGE, SR_MQFLAG_DC | SR_MQFLAG_DIODE, "DIOD", "DIOD", -4, }, + { SR_MQ_TEMPERATURE, 0, "TEMP", "TEMP", NO_DFLT_PREC, }, + { SR_MQ_FREQUENCY, 0, "FREQ", "FREQ", NO_DFLT_PREC, }, + { SR_MQ_TIME, 0, "PER", "PER", NO_DFLT_PREC, }, + { SR_MQ_CAPACITANCE, 0, "CAP", "CAP", NO_DFLT_PREC, }, +}; + SR_PRIV const struct scpi_dmm_model models[] = { { "Agilent", "34405A", 1, 5, cmdset_agilent, ARRAY_AND_SIZE(mqopts_agilent_34405a), scpi_dmm_get_meas_agilent, ARRAY_AND_SIZE(devopts_generic), - 0, + 0, + }, + { + "Agilent", "34410A", + 1, 6, cmdset_hp, ARRAY_AND_SIZE(mqopts_agilent_34405a), + scpi_dmm_get_meas_agilent, + ARRAY_AND_SIZE(devopts_generic), + 0, }, { "Keysight", "34465A", 1, 5, cmdset_agilent, ARRAY_AND_SIZE(mqopts_agilent_34405a), scpi_dmm_get_meas_agilent, ARRAY_AND_SIZE(devopts_generic), - 0, + 0, }, { "HP", "34401A", @@ -124,7 +188,35 @@ SR_PRIV const struct scpi_dmm_model models[] = { scpi_dmm_get_meas_agilent, ARRAY_AND_SIZE(devopts_generic), /* 34401A: typ. 1020ms for AC readings (default is 1000ms). */ - 1000 * 1500, + 1000 * 1500, + }, + { + "GW", "GDM8251A", + 1, 6, cmdset_gwinstek, ARRAY_AND_SIZE(mqopts_gwinstek_gdm8200a), + scpi_dmm_get_meas_gwinstek, + ARRAY_AND_SIZE(devopts_generic), + 1000 * 2500, + }, + { + "GW", "GDM8255A", + 1, 6, cmdset_gwinstek, ARRAY_AND_SIZE(mqopts_gwinstek_gdm8200a), + scpi_dmm_get_meas_gwinstek, + ARRAY_AND_SIZE(devopts_generic), + 1000 * 2500, + }, + { + "GWInstek", "GDM9060", + 1, 6, cmdset_gwinstek_906x, ARRAY_AND_SIZE(mqopts_gwinstek_gdm906x), + scpi_dmm_get_meas_agilent, + ARRAY_AND_SIZE(devopts_generic), + 0, + }, + { + "GWInstek", "GDM9061", + 1, 6, cmdset_gwinstek_906x, ARRAY_AND_SIZE(mqopts_gwinstek_gdm906x), + scpi_dmm_get_meas_agilent, + ARRAY_AND_SIZE(devopts_generic), + 0, }, }; @@ -180,13 +272,14 @@ static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi) sdi->driver = &scpi_dmm_driver_info; sdi->inst_type = SR_INST_SCPI; sr_scpi_hw_info_free(hw_info); - if (model->read_timeout_us) /* non-default read timeout */ + if (model->read_timeout_us) /* non-default read timeout */ scpi->read_timeout_us = model->read_timeout_us; devc = g_malloc0(sizeof(*devc)); sdi->priv = devc; devc->num_channels = model->num_channels; devc->cmdset = model->cmdset; devc->model = model; + devc->precision = NULL; for (i = 0; i < devc->num_channels; i++) { channel_name = g_strdup_printf("P%zu", i + 1); @@ -280,6 +373,7 @@ 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); + g_variant_unref(tuple_child); tuple_child = g_variant_get_child_value(data, 1); mqflag = g_variant_get_uint64(tuple_child); g_variant_unref(tuple_child); @@ -336,6 +430,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) int ret; const struct mqopt_item *item; const char *command; + char *response; scpi = sdi->conn; devc = sdi->priv; @@ -345,6 +440,26 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi) if (ret != SR_OK) return ret; + /* + * Query for current precision if DMM supports the command + */ + command = sr_scpi_cmd_get(devc->cmdset, DMM_CMD_QUERY_PREC); + if (command && *command) { + scpi_dmm_cmd_delay(scpi); + ret = sr_scpi_get_string(scpi, command, &response); + if (ret == SR_OK) { + g_strstrip(response); + if (devc->precision) + g_free(devc->precision); + devc->precision=g_strdup(response); + g_free(response); + sr_dbg("%s: Precision: '%s'", __func__, devc->precision); + } else { + sr_info("%s: Precision query ('%s') failed: %d", + __func__, command, ret); + } + } + command = sr_scpi_cmd_get(devc->cmdset, DMM_CMD_START_ACQ); if (command && *command) { scpi_dmm_cmd_delay(scpi); @@ -384,6 +499,11 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi) std_session_send_df_end(sdi); + if (devc->precision) { + g_free(devc->precision); + devc->precision = NULL; + } + return SR_OK; }