return SR_OK;
}
+/* Elektro Automatik PS 20xx series */
+static const uint32_t ea_ps_20xx_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 ea_ps_20xx_devopts_cg[] = {
+ SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD | SR_CONF_SET | SR_CONF_LIST,
+ SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD | SR_CONF_SET | SR_CONF_LIST,
+ SR_CONF_VOLTAGE | SR_CONF_GET,
+ SR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
+ SR_CONF_CURRENT | SR_CONF_GET,
+ SR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,
+ SR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,
+};
+
+static const struct channel_group_spec ea_ps_20xx_cg[] = {
+ { "1", CH_IDX(0), PPS_OVP | PPS_OCP, SR_MQFLAG_DC },
+};
+
+static int ea_ps_20xx_probe_channels(struct sr_dev_inst *sdi,
+ struct sr_scpi_hw_info *hw_info,
+ struct channel_spec **channels, unsigned int *num_channels,
+ struct channel_group_spec **channel_groups,
+ unsigned int *num_channel_groups)
+{
+ struct sr_scpi_dev_inst *scpi;
+ int ret;
+ float nom_volt, nom_curr, nom_pow;
+ char *response;
+
+ scpi = sdi->conn;
+
+ /* Get nominal voltage */
+ ret = sr_scpi_get_string(scpi, ":SYST:NOM:VOLT?", &response);
+ if ((ret != SR_OK) && (!response)) {
+ sr_err("Failed to get nominal voltage.");
+ return ret;
+ }
+ /* Remove unit */
+ response[ret] = 0;
+ if (sr_atof_ascii(response, &nom_volt) != SR_OK) {
+ sr_err("Failed to convert nominal voltage from: '%s'", response);
+ return SR_ERR_DATA;
+ }
+ if (nom_volt < 0) {
+ sr_err("Suspicious nominal voltage %f, ignoring.", nom_volt);
+ return SR_ERR_DATA;
+ }
+
+ /* Get nominal current */
+ ret = sr_scpi_get_string(scpi, ":SYST:NOM:CURR?", &response);
+ if (ret != SR_OK && !response) {
+ sr_err("Failed to get nominal current.");
+ return ret;
+ }
+ /* Remove unit */
+ response[ret] = 0;
+ if (sr_atof_ascii(response, &nom_curr) != SR_OK) {
+ sr_err("Failed to convert nominal current from: '%s'", response);
+ return SR_ERR_DATA;
+ }
+ if (nom_curr < 0) {
+ sr_err("Suspicious nominal current %f, ignoring.", nom_volt);
+ return SR_ERR_DATA;
+ }
+
+ /* Get nominal power */
+ ret = sr_scpi_get_string(scpi, ":SYST:NOM:POW?", &response);
+ if (ret != SR_OK && !response) {
+ sr_err("Failed to get nominal power.");
+ return ret;
+ }
+ /* Remove unit */
+ response[ret] = 0;
+ if (sr_atof_ascii(response, &nom_pow) != SR_OK) {
+ sr_err("Failed to convert nominal power from: '%s'", response);
+ return SR_ERR_DATA;
+ }
+ if (nom_pow < 0) {
+ sr_err("Suspicious nominal power %f, ignoring.", nom_volt);
+ return SR_ERR_DATA;
+ }
+
+ *channels = g_malloc0(sizeof(struct channel_spec));
+ *channel_groups = g_malloc0(sizeof(struct channel_group_spec));
+ **channel_groups = ea_ps_20xx_cg[0];
+ *num_channel_groups = 1;
+
+ (*channels)[0].name = "1";
+
+ (*channels)[0].current[0] = 0.0;
+ (*channels)[0].current[1] = nom_curr;
+ (*channels)[0].current[2] = 0.01; /* Programming resolution. */
+ (*channels)[0].current[3] = 2; /* Spec digits. */
+ (*channels)[0].current[4] = 2; /* Encoding digits. */
+
+ (*channels)[0].voltage[0] = 0.0;
+ (*channels)[0].voltage[1] = nom_volt;
+ (*channels)[0].voltage[2] = 0.01; /* Programming resolution. */
+ (*channels)[0].voltage[3] = 2; /* Spec digits. */
+ (*channels)[0].voltage[4] = 2; /* Encoding digits. */
+
+ (*channels)[0].power[0] = 0.0;
+ (*channels)[0].power[1] = nom_pow;
+ (*channels)[0].power[2] = 0; /* Programming resolution. */
+ (*channels)[0].power[3] = 2; /* Spec digits. */
+ (*channels)[0].power[4] = 2; /* Encoding digits. */
+ *num_channels = 1;
+
+ return SR_OK;
+}
+
+static const struct scpi_command ea_ps_20xx_cmd[] = {
+ { SCPI_CMD_REMOTE, "SYST:LOCK 1" },
+ { SCPI_CMD_LOCAL, "SYST:LOCK 0" },
+ { SCPI_CMD_GET_MEAS_VOLTAGE, ":MEAS:VOLT?" },
+ { SCPI_CMD_GET_MEAS_CURRENT, ":MEAS:CURR?" },
+ { SCPI_CMD_GET_MEAS_POWER, ":MEAS:POW?" },
+ { SCPI_CMD_GET_VOLTAGE_TARGET, ":VOLT?" },
+ { SCPI_CMD_SET_VOLTAGE_TARGET, ":VOLT %.2f" },
+ { SCPI_CMD_GET_CURRENT_LIMIT, ":CURR?" },
+ { SCPI_CMD_SET_CURRENT_LIMIT, ":CURR %.2f" },
+ { SCPI_CMD_GET_OUTPUT_ENABLED, ":OUTP?" },
+ { SCPI_CMD_SET_OUTPUT_ENABLE, ":OUTP 1" },
+ { SCPI_CMD_SET_OUTPUT_DISABLE, ":OUTP 0" },
+ { SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, ":VOLT:PROT %.2f" },
+ { SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, ":CURR:PROT %.2f" },
+ ALL_ZERO
+};
+
+static int ea_ps_20xx_update_status(const struct sr_dev_inst *sdi)
+{
+ struct sr_scpi_dev_inst *scpi;
+ int ret;
+ int response;
+ gboolean cv, cc;
+ gboolean regulation_changed;
+ char *regulation;
+
+ scpi = sdi->conn;
+
+ ret = sr_scpi_get_int(scpi, "STAT:QUES?", &response);
+ if (ret != SR_OK)
+ return ret;
+
+ /* OVP */
+ if (response & (1 << 0))
+ sr_session_send_meta(sdi, SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE,
+ g_variant_new_boolean(response & (1 << 0)));
+
+ /* OCP */
+ if (response & (1 << 1))
+ sr_session_send_meta(sdi, SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE,
+ g_variant_new_boolean(response & (1 << 1)));
+
+ /* OTP */
+ if (response & (1 << 3))
+ sr_session_send_meta(sdi, SR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE,
+ g_variant_new_boolean(response & (1 << 3)));
+
+ ret = sr_scpi_get_int(scpi, "STAT:OPER?", &response);
+ if (ret != SR_OK)
+ return ret;
+
+ /* CV */
+ cv = (response & (1 << 8));
+ regulation_changed = (response & (1 << 8));
+ /* CC */
+ cc = (response & (1 << 9));
+ regulation_changed = (response & (1 << 9)) | regulation_changed;
+
+ if (regulation_changed) {
+ if (cv && !cc)
+ regulation = "CV";
+ else if (cc && !cv)
+ regulation = "CC";
+ else if (!cv && !cc)
+ regulation = "";
+ else {
+ sr_dbg("Undefined regulation for EA PS 20xx "
+ "(CV=%i, CC=%i).", cv, cc);
+ return FALSE;
+ }
+ sr_session_send_meta(sdi, SR_CONF_REGULATION,
+ g_variant_new_string(regulation));
+ }
+
+ return SR_OK;
+}
+
/* Envox EEZ PSU Series */
static const uint32_t eez_psu_devopts[] = {
SR_CONF_CONTINUOUS,
.update_status = NULL,
},
+ /* Elektro Automatik PS 20xx series*/
+ { "EA Elektro-Automatik GmbH & Co. KG", "PS 20(42|84)-", SCPI_DIALECT_UNKNOWN, 0,
+ ARRAY_AND_SIZE(ea_ps_20xx_devopts),
+ ARRAY_AND_SIZE(ea_ps_20xx_devopts_cg),
+ NULL, 0,
+ NULL, 0,
+ ea_ps_20xx_cmd,
+ .probe_channels = ea_ps_20xx_probe_channels,
+ .init_acquisition = NULL,
+ .update_status = ea_ps_20xx_update_status,
+ },
+
/*
* Envox EEZ PSU Series
* The documented identification strings disagree with the behavior