From: Kota Ando Date: Tue, 5 Jul 2022 12:10:33 +0000 (+0900) Subject: scpi-pps: Add Keysight E36300A X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=00bd95160e07700c9c10f6d82aeffcb629da11d1;p=libsigrok.git scpi-pps: Add Keysight E36300A - Add E36311A, E36312A, and E36313A - Tested using E36312A via LAN and smuview --- diff --git a/src/hardware/scpi-pps/api.c b/src/hardware/scpi-pps/api.c index 116a5d46..ea31ecff 100644 --- a/src/hardware/scpi-pps/api.c +++ b/src/hardware/scpi-pps/api.c @@ -342,7 +342,7 @@ static int config_get(uint32_t key, GVariant **data, int cmd, ret; const char *s; int reg; - gboolean is_hmp_sqii; + gboolean is_hmp_sqii, is_keysight_e36300a; if (!sdi) return SR_ERR_ARG; @@ -453,7 +453,8 @@ static int config_get(uint32_t key, GVariant **data, case SR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE: if (devc->device->dialect == SCPI_DIALECT_HP_66XXB || devc->device->dialect == SCPI_DIALECT_HP_COMP || - devc->device->dialect == SCPI_DIALECT_HMP) + devc->device->dialect == SCPI_DIALECT_HMP || + devc->device->dialect == SCPI_DIALECT_KEYSIGHT_E36300A) gvtype = G_VARIANT_TYPE_STRING; else gvtype = G_VARIANT_TYPE_BOOLEAN; @@ -480,7 +481,13 @@ static int config_get(uint32_t key, GVariant **data, is_hmp_sqii |= cmd == SCPI_CMD_GET_OUTPUT_REGULATION; is_hmp_sqii |= cmd == SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION_ACTIVE; is_hmp_sqii &= devc->device->dialect == SCPI_DIALECT_HMP; - if (is_hmp_sqii) { + + is_keysight_e36300a = FALSE; + is_keysight_e36300a |= cmd == SCPI_CMD_GET_OUTPUT_REGULATION; + is_keysight_e36300a |= cmd == SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION_ACTIVE; + is_keysight_e36300a &= devc->device->dialect == SCPI_DIALECT_KEYSIGHT_E36300A; + + if (is_hmp_sqii || is_keysight_e36300a) { if (!cg) { /* STAT:QUES:INST:ISUMx query requires channel spec. */ sr_err("Need a channel group for regulation or OTP-active query."); @@ -555,6 +562,23 @@ static int config_get(uint32_t key, GVariant **data, else *data = g_variant_new_string("UR"); } + if (devc->device->dialect == SCPI_DIALECT_KEYSIGHT_E36300A) { + /* Evaluate Condition Status Register from a Keysight E36300A series device. */ + s = g_variant_get_string(*data, NULL); + sr_atoi(s, ®); + reg &= 0x03u; + g_variant_unref(*data); + if (reg == 0x01u) + *data = g_variant_new_string("CC"); + else if (reg == 0x02u) + *data = g_variant_new_string("CV"); + else if (reg == 0x03u) + /* 2 LSBs == 11: HW Failure*/ + *data = g_variant_new_string(""); + else + /* 2 LSBs == 00: Unregulated */ + *data = g_variant_new_string("UR"); + } s = g_variant_get_string(*data, NULL); if (g_strcmp0(s, "CV") && g_strcmp0(s, "CC") && g_strcmp0(s, "CC-") && @@ -608,8 +632,12 @@ static int config_get(uint32_t key, GVariant **data, *data = g_variant_new_boolean(reg & (1 << 4)); } if (devc->device->dialect == SCPI_DIALECT_HP_66XXB || - devc->device->dialect == SCPI_DIALECT_HMP) { + devc->device->dialect == SCPI_DIALECT_HMP || + devc->device->dialect == SCPI_DIALECT_KEYSIGHT_E36300A) { /* Evaluate Questionable Status Register bit 4 from a HP 66xxB. */ + /* For Keysight E36300A, the queried register is the Questionable Instrument Summary register, */ + /* but the bit position is the same as an HP 66xxB's Questionable Status Register. */ + s = g_variant_get_string(*data, NULL); sr_atoi(s, ®); g_variant_unref(*data); diff --git a/src/hardware/scpi-pps/profiles.c b/src/hardware/scpi-pps/profiles.c index ae59a86f..aa113179 100644 --- a/src/hardware/scpi-pps/profiles.c +++ b/src/hardware/scpi-pps/profiles.c @@ -1008,6 +1008,89 @@ static int hp_6630b_update_status(const struct sr_dev_inst *sdi) return SR_OK; } + +/* Keysight E36300A series */ + +static const uint32_t keysight_e36300a_devopts[] = { + SR_CONF_CONTINUOUS, + SR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET, + SR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET, +}; + +static const uint32_t keysight_e36300a_devopts_cg[] = { + SR_CONF_ENABLED | SR_CONF_SET, + SR_CONF_VOLTAGE | SR_CONF_GET, + SR_CONF_CURRENT | SR_CONF_GET, + SR_CONF_VOLTAGE_TARGET | SR_CONF_SET | SR_CONF_LIST, + SR_CONF_CURRENT_LIMIT | SR_CONF_SET | SR_CONF_LIST, + SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE | SR_CONF_GET, + SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD | SR_CONF_SET | SR_CONF_LIST, + SR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_SET | SR_CONF_GET, + SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE | SR_CONF_GET, + SR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE | SR_CONF_GET, + SR_CONF_REGULATION | SR_CONF_GET, +}; + +/* NOT TESTED; estimated from the E36312A results and data sheet. */ +/* The measurement resolution of CHs 2 and 3 of E36311A is 10mV, different from 1mV in E36312A, */ +/* but the data sheet does not provide us with the programming resolution. */ +static const struct channel_spec keysight_e36311a_ch[] = { + { "1", { 0, 6.18, 0.001, 3, 8 }, { 2e-3, 5.15, 0.001, 3, 8 }, { 0, 31.827 }, FREQ_DC_ONLY, { 0.5, 6.6 , 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, + { "2", { 0, 25.75, 0.001, 3, 8 }, { 1e-3, 1.03, 0.001, 3, 8 }, { 0, 26.5225 }, FREQ_DC_ONLY, { 0.5, 27.5, 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, + { "3", { -25.75, 0, 0.001, 3, 8 }, { 1e-3, 1.03, 0.001, 3, 8 }, { 0, 26.5225 }, FREQ_DC_ONLY, { 0.5, 27.5, 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, +}; + +/* fetched from the equipment using the ':SOUR:VOLT? MAX,(@N)' command (where N=1,2,3) */ +static const struct channel_spec keysight_e36312a_ch[] = { + { "1", { 0, 6.18, 0.001, 3, 8 }, { 2e-3, 5.15, 0.001, 3, 8 }, { 0, 31.827 }, FREQ_DC_ONLY, { 0.5, 6.6 , 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, + { "2", { 0, 25.75, 0.001, 3, 8 }, { 1e-3, 1.03, 0.001, 3, 8 }, { 0, 26.5225 }, FREQ_DC_ONLY, { 0.5, 27.5, 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, + { "3", { 0, 25.75, 0.001, 3, 8 }, { 1e-3, 1.03, 0.001, 3, 8 }, { 0, 26.5225 }, FREQ_DC_ONLY, { 0.5, 27.5, 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, +}; + +/* NOT TESTED; estimated from the E36312A results and data sheet. */ +static const struct channel_spec keysight_e36313a_ch[] = { + { "1", { 0, 6.18, 0.001, 3, 8 }, { 2e-3, 10.3, 0.001, 3, 8 }, { 0, 63.654 }, FREQ_DC_ONLY, { 0.5, 6.6 , 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, + { "2", { 0, 25.75, 0.001, 3, 8 }, { 1e-3, 2.06, 0.001, 3, 8 }, { 0, 53.045 }, FREQ_DC_ONLY, { 0.5, 27.5, 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, + { "3", { 0, 25.75, 0.001, 3, 8 }, { 1e-3, 2.06, 0.001, 3, 8 }, { 0, 53.045 }, FREQ_DC_ONLY, { 0.5, 27.5, 0.001 }, NO_OCP_LIMITS, NO_OCP_DELAY }, +}; + +static const struct channel_group_spec keysight_e36300a_cg[] = { + { "1", CH_IDX(0), PPS_OVP | PPS_OCP | PPS_OTP, SR_MQFLAG_DC }, + { "2", CH_IDX(1), PPS_OVP | PPS_OCP | PPS_OTP, SR_MQFLAG_DC }, + { "3", CH_IDX(2), PPS_OVP | PPS_OCP | PPS_OTP, SR_MQFLAG_DC }, +}; + +static const struct scpi_command keysight_e36300a_cmd[] = { + /* + * Only tested on an E36312A connected via LAN. + * E36311A, E36312A, and E36313A support the USB connection + * while E36312A and E36313A also support GPIB with an optional interface card, + * but these are not tested. + */ + { SCPI_CMD_REMOTE, "SYST:REM" }, + { SCPI_CMD_LOCAL, "SYST:LOC" }, + { SCPI_CMD_SELECT_CHANNEL, ":INST:NSEL %s" }, + { SCPI_CMD_GET_OUTPUT_ENABLED, "OUTP:STAT?" }, + { SCPI_CMD_SET_OUTPUT_ENABLE, "OUTP:STAT ON" }, + { SCPI_CMD_SET_OUTPUT_DISABLE, "OUTP:STAT OFF" }, + { SCPI_CMD_GET_MEAS_VOLTAGE, ":MEAS:VOLT?" }, + { SCPI_CMD_GET_MEAS_CURRENT, ":MEAS:CURR?" }, + { SCPI_CMD_GET_VOLTAGE_TARGET, ":SOUR:VOLT?" }, + { SCPI_CMD_SET_VOLTAGE_TARGET, ":SOUR:VOLT %.6f" }, + { SCPI_CMD_GET_CURRENT_LIMIT, ":SOUR:CURR?" }, + { SCPI_CMD_SET_CURRENT_LIMIT, ":SOUR:CURR %.6f" }, + { SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ENABLED, ":CURR:PROT:STAT?" }, + { SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLE, ":CURR:PROT:STAT 1" }, + { SCPI_CMD_SET_OVER_CURRENT_PROTECTION_DISABLE, ":CURR:PROT:STAT 0" }, + { SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE, ":CURR:PROT:TRIP?" }, + { SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ACTIVE, ":VOLT:PROT:TRIP?" }, + { SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_THRESHOLD, ":VOLT:PROT?" }, + { SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, ":VOLT:PROT %.6f" }, + { SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION_ACTIVE, ":STAT:QUES:INST:ISUM%s:COND?" }, + { SCPI_CMD_GET_OUTPUT_REGULATION, ":STAT:QUES:INST:ISUM%s:COND?" }, + ALL_ZERO +}; + /* Owon P4000 series */ static const uint32_t owon_p4000_devopts[] = { SR_CONF_CONTINUOUS, @@ -1701,6 +1784,42 @@ SR_PRIV const struct scpi_pps pps_profiles[] = { hp_6630b_update_status, }, + /* Keysight E36311A; NOT TESTED*/ + { "Keysight", "E36311A", SCPI_DIALECT_KEYSIGHT_E36300A, 0, + ARRAY_AND_SIZE(keysight_e36300a_devopts), + ARRAY_AND_SIZE(keysight_e36300a_devopts_cg), + ARRAY_AND_SIZE(keysight_e36311a_ch), + ARRAY_AND_SIZE(keysight_e36300a_cg), + keysight_e36300a_cmd, + .probe_channels = NULL, + .init_acquisition=NULL, + .update_status=NULL, + }, + + /* Keysight E36312A */ + { "Keysight", "E36312A", SCPI_DIALECT_KEYSIGHT_E36300A, 0, + ARRAY_AND_SIZE(keysight_e36300a_devopts), + ARRAY_AND_SIZE(keysight_e36300a_devopts_cg), + ARRAY_AND_SIZE(keysight_e36312a_ch), + ARRAY_AND_SIZE(keysight_e36300a_cg), + keysight_e36300a_cmd, + .probe_channels = NULL, + .init_acquisition=NULL, + .update_status=NULL, + }, + + /* Keysight E36313A; NOT TESTED*/ + { "Keysight", "E36313A", SCPI_DIALECT_KEYSIGHT_E36300A, 0, + ARRAY_AND_SIZE(keysight_e36300a_devopts), + ARRAY_AND_SIZE(keysight_e36300a_devopts_cg), + ARRAY_AND_SIZE(keysight_e36313a_ch), + ARRAY_AND_SIZE(keysight_e36300a_cg), + keysight_e36300a_cmd, + .probe_channels = NULL, + .init_acquisition=NULL, + .update_status=NULL, + }, + /* Rigol DP700 series */ { "Rigol", "^DP711$", SCPI_DIALECT_UNKNOWN, 0, ARRAY_AND_SIZE(rigol_dp700_devopts), diff --git a/src/hardware/scpi-pps/protocol.h b/src/hardware/scpi-pps/protocol.h index b75feb2e..a6adf19c 100644 --- a/src/hardware/scpi-pps/protocol.h +++ b/src/hardware/scpi-pps/protocol.h @@ -77,6 +77,7 @@ enum pps_scpi_dialect { SCPI_DIALECT_HP_66XXB, SCPI_DIALECT_PHILIPS, SCPI_DIALECT_HMP, + SCPI_DIALECT_KEYSIGHT_E36300A, }; /*