2 * This file is part of the libsigrok project.
4 * Copyright (C) 2014 Bert Vermeulen <bert@biot.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 SR_PRIV struct sr_dev_driver scpi_pps_driver_info;
24 static struct sr_dev_driver *di = &scpi_pps_driver_info;
25 SR_PRIV const struct scpi_pps pps_profiles[] = {};
26 unsigned int num_pps_profiles;
28 static const int32_t scanopts[] = {
33 static int init(struct sr_context *sr_ctx)
35 return std_init(sr_ctx, di, LOG_PREFIX);
38 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
40 struct dev_context *devc;
41 struct sr_dev_inst *sdi;
42 struct sr_scpi_hw_info *hw_info;
43 struct sr_channel_group *cg;
44 struct sr_channel *ch;
45 const struct scpi_pps *device;
46 const struct channel_group_spec *cgs;
47 struct pps_channel_group *pcg;
51 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
52 sr_info("Couldn't get IDN response.");
57 for (i = 0; i < num_pps_profiles; i++) {
58 if (!strcasecmp(hw_info->manufacturer, pps_profiles[i].idn_vendor) &&
59 !strcmp(hw_info->model, pps_profiles[i].idn_model)) {
60 device = &pps_profiles[i];
65 sr_scpi_hw_info_free(hw_info);
69 sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, device->vendor, device->idn_model,
70 hw_info->firmware_version);
73 sdi->inst_type = SR_INST_SCPI;
74 devc = g_malloc0(sizeof(struct dev_context));
75 devc->device = device;
78 for (i = 0; i < device->num_channels; i++) {
79 ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE,
80 device->channels[i].name);
81 sdi->channels = g_slist_append(sdi->channels, ch);
84 for (i = 0; i < device->num_channel_groups; i++) {
85 cgs = &device->channel_groups[i];
86 cg = g_malloc0(sizeof(struct sr_channel_group));
87 cg->name = g_strdup(cgs->name);
88 for (j = 0, mask = 1; j < 64; j++, mask <<= 1) {
89 if (cgs->channel_index_mask & mask) {
90 ch = g_slist_nth_data(sdi->channels, j);
91 cg->channels = g_slist_append(cg->channels, ch);
94 pcg = g_malloc0(sizeof(struct pps_channel_group));
95 pcg->features = cgs->features;
97 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
100 /* SCPI devices commonly lock the panel keys when accessed remotely. */
101 scpi_cmd(sdi, SCPI_CMD_KEY_UNLOCK);
107 static GSList *scan(GSList *options)
109 return sr_scpi_scan(di->priv, options, probe_device);
112 static GSList *dev_list(void)
114 return ((struct drv_context *)(di->priv))->instances;
117 static int dev_clear(void)
119 return std_dev_clear(di, NULL);
122 static int dev_open(struct sr_dev_inst *sdi)
124 struct sr_scpi_dev_inst *scpi;
126 if (sdi->status != SR_ST_ACTIVE)
130 if (sr_scpi_open(scpi) < 0)
133 sdi->status = SR_ST_ACTIVE;
138 static int dev_close(struct sr_dev_inst *sdi)
140 struct sr_scpi_dev_inst *scpi;
142 if (sdi->status != SR_ST_ACTIVE)
143 return SR_ERR_DEV_CLOSED;
147 scpi_cmd(sdi, SCPI_CMD_KEY_UNLOCK);
149 sdi->status = SR_ST_INACTIVE;
155 static int cleanup(void)
160 static int config_get(int key, GVariant **data, const struct sr_dev_inst *sdi,
161 const struct sr_channel_group *cg)
163 struct dev_context *devc;
164 struct sr_scpi_dev_inst *scpi;
165 struct sr_channel *ch;
178 /* No channel group: global options. */
180 case SR_CONF_OVER_TEMPERATURE_PROTECTION:
182 if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION) == SR_OK) {
183 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
184 *data = g_variant_new_boolean(!strcmp(s, "ON"));
191 case SR_CONF_OUTPUT_CHANNEL_CONFIG:
193 if (scpi_cmd(sdi, SCPI_CMD_GET_OUTPUT_CHANNEL_CONFIG) == SR_OK) {
194 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
195 *data = g_variant_new_string(s);
206 * These options only apply to channel groups with a single
207 * channel -- they're per-channel settings for the device.
209 if (g_slist_length(cg->channels) > 1)
211 ch = cg->channels->data;
214 case SR_CONF_OUTPUT_REGULATION:
216 if (scpi_cmd(sdi, SCPI_CMD_GET_OUTPUT_REGULATION, ch->name) == SR_OK) {
217 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
218 if (strcmp(s, "CC") && strcmp(s, "CV") && strcmp(s, "UR")) {
219 sr_dbg("Unknown response to SCPI_CMD_GET_OUTPUT_REGULATION: %s", s);
221 *data = g_variant_new_string(s);
228 case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
230 if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ENABLED,
231 ch->name) == SR_OK) {
232 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
233 *data = g_variant_new_boolean(!strcmp(s, "ON"));
238 case SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE:
240 if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ACTIVE,
241 ch->name) == SR_OK) {
242 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
243 *data = g_variant_new_boolean(!strcmp(s, "YES"));
248 case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
250 if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_THRESHOLD,
251 ch->name) == SR_OK) {
252 if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) {
253 *data = g_variant_new_double(d);
258 case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
260 if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ENABLED,
261 ch->name) == SR_OK) {
262 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
263 *data = g_variant_new_boolean(!strcmp(s, "ON"));
268 case SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE:
270 if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE,
271 ch->name) == SR_OK) {
272 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
273 *data = g_variant_new_boolean(!strcmp(s, "YES"));
278 case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
280 if (scpi_cmd(sdi, SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD,
281 ch->name) == SR_OK) {
282 if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) {
283 *data = g_variant_new_double(d);
288 case SR_CONF_OUTPUT_VOLTAGE:
290 if (scpi_cmd(sdi, SCPI_CMD_GET_MEAS_VOLTAGE, ch->name) == SR_OK) {
291 if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) {
292 *data = g_variant_new_double(d);
297 case SR_CONF_OUTPUT_VOLTAGE_MAX:
299 if (scpi_cmd(sdi, SCPI_CMD_GET_VOLTAGE_MAX, ch->name) == SR_OK) {
300 if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) {
301 *data = g_variant_new_double(d);
306 case SR_CONF_OUTPUT_CURRENT:
308 if (scpi_cmd(sdi, SCPI_CMD_GET_MEAS_CURRENT, ch->name) == SR_OK) {
309 if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) {
310 *data = g_variant_new_double(d);
315 case SR_CONF_OUTPUT_CURRENT_MAX:
317 if (scpi_cmd(sdi, SCPI_CMD_GET_CURRENT_MAX, ch->name) == SR_OK) {
318 if (sr_scpi_get_double(scpi, NULL, &d) == SR_OK) {
319 *data = g_variant_new_double(d);
324 case SR_CONF_OUTPUT_ENABLED:
326 if (scpi_cmd(sdi, SCPI_CMD_GET_OUTPUT_ENABLED, ch->name) == SR_OK) {
327 if (sr_scpi_get_string(scpi, NULL, &s) == SR_OK) {
328 *data = g_variant_new_boolean(!strcmp(s, "ON"));
341 static int config_set(int key, GVariant *data, const struct sr_dev_inst *sdi,
342 const struct sr_channel_group *cg)
344 struct sr_channel *ch;
349 if (sdi->status != SR_ST_ACTIVE)
350 return SR_ERR_DEV_CLOSED;
356 /* No channel group: global options. */
357 case SR_CONF_OVER_TEMPERATURE_PROTECTION:
358 s = g_variant_get_boolean(data) ? "ON" : "OFF";
359 if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION, s) < 0)
362 case SR_CONF_OUTPUT_CHANNEL_CONFIG:
363 s = g_variant_get_string(data, NULL);
364 if (scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_CHANNEL_CONFIG, s) < 0)
371 /* Channel group specified. */
374 if (g_slist_length(cg->channels) > 1)
376 ch = cg->channels->data;
378 case SR_CONF_OUTPUT_VOLTAGE_MAX:
379 d = g_variant_get_double(data);
380 if (scpi_cmd(sdi, SCPI_CMD_SET_VOLTAGE_MAX, ch->name, d) < 0)
383 case SR_CONF_OUTPUT_CURRENT_MAX:
384 d = g_variant_get_double(data);
385 if (scpi_cmd(sdi, SCPI_CMD_SET_CURRENT_MAX, ch->name, d) < 0)
388 case SR_CONF_OUTPUT_ENABLED:
389 s = g_variant_get_boolean(data) ? "ON" : "OFF";
390 if (scpi_cmd(sdi, SCPI_CMD_SET_OUTPUT_ENABLED, ch->name, s) < 0)
393 case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
394 s = g_variant_get_boolean(data) ? "ON" : "OFF";
395 if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_ENABLED,
399 case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
400 d = g_variant_get_double(data);
401 if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD,
405 case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
406 s = g_variant_get_boolean(data) ? "ON" : "OFF";
407 if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLED,
411 case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
412 d = g_variant_get_double(data);
413 if (scpi_cmd(sdi, SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD,
425 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
426 const struct sr_channel_group *cg)
428 struct dev_context *devc;
429 struct sr_channel *ch;
430 struct channel_spec *ch_spec;
436 /* Always available, even without sdi. */
437 if (key == SR_CONF_SCAN_OPTIONS) {
438 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
439 scanopts, ARRAY_SIZE(scanopts), sizeof(int32_t));
449 /* No channel group: global options. */
451 case SR_CONF_DEVICE_OPTIONS:
452 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
453 devc->device->devopts, devc->device->num_devopts,
456 case SR_CONF_OUTPUT_CHANNEL_CONFIG:
458 if (devc->device->features & PPS_INDEPENDENT)
459 s[i++] = "Independent";
460 if (devc->device->features & PPS_SERIES)
462 if (devc->device->features & PPS_PARALLEL)
466 * Shouldn't happen: independent-only devices
467 * shouldn't advertise this option at all.
471 *data = g_variant_new_strv(s, i);
477 /* Channel group specified. */
481 * Per-channel-group options depending on a channel are actually
482 * done with the first channel. Channel groups in PPS can have
483 * more than one channel, but they will typically be of equal
484 * specification for use in series or parallel mode. Drop requests
485 * for groups with more than one channel just to make sure.
487 if (g_slist_length(cg->channels) > 1)
489 ch = cg->channels->data;
492 case SR_CONF_DEVICE_OPTIONS:
493 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
494 devc->device->devopts_cg, devc->device->num_devopts_cg,
497 case SR_CONF_OUTPUT_VOLTAGE_MAX:
498 ch_spec = &(devc->device->channels[ch->index]);
499 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
500 /* Min, max, write resolution. */
501 for (i = 0; i < 3; i++) {
502 gvar = g_variant_new_double(ch_spec->voltage[i]);
503 g_variant_builder_add_value(&gvb, gvar);
505 *data = g_variant_builder_end(&gvb);
507 case SR_CONF_OUTPUT_CURRENT_MAX:
508 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
509 /* Min, max, step. */
510 for (i = 0; i < 3; i++) {
511 ch_spec = &(devc->device->channels[ch->index]);
512 gvar = g_variant_new_double(ch_spec->current[i]);
513 g_variant_builder_add_value(&gvb, gvar);
515 *data = g_variant_builder_end(&gvb);
525 static int dev_acquisition_start(const struct sr_dev_inst *sdi,
528 struct dev_context *devc;
529 struct sr_scpi_dev_inst *scpi;
530 struct sr_channel *ch;
533 if (sdi->status != SR_ST_ACTIVE)
534 return SR_ERR_DEV_CLOSED;
538 devc->cb_data = cb_data;
540 if ((ret = sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 100,
541 scpi_pps_receive_data, (void *)sdi)) != SR_OK)
543 std_session_send_df_header(sdi, LOG_PREFIX);
545 /* Prime the pipe. */
546 devc->state = STATE_VOLTAGE;
547 ch = sdi->channels->data;
548 devc->cur_channel = ch;
549 scpi_cmd(sdi, SCPI_CMD_GET_MEAS_VOLTAGE, ch->name);
554 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
556 struct dev_context *devc;
557 struct sr_scpi_dev_inst *scpi;
562 if (sdi->status != SR_ST_ACTIVE)
563 return SR_ERR_DEV_CLOSED;
569 * A requested value is certainly on the way. Retrieve it now,
570 * to avoid leaving the device in a state where it's not expecting
573 sr_scpi_get_float(scpi, NULL, &f);
574 sr_scpi_source_remove(sdi->session, scpi);
576 /* Just in case something is queued up. */
577 devc->state = STATE_STOP;
582 SR_PRIV struct sr_dev_driver scpi_pps_driver_info = {
584 .longname = "SCPI PPS",
589 .dev_list = dev_list,
590 .dev_clear = dev_clear,
591 .config_get = config_get,
592 .config_set = config_set,
593 .config_list = config_list,
594 .dev_open = dev_open,
595 .dev_close = dev_close,
596 .dev_acquisition_start = dev_acquisition_start,
597 .dev_acquisition_stop = dev_acquisition_stop,