]> sigrok.org Git - libsigrok.git/blob - src/hardware/scpi-pps/api.c
785deabb798525a06a3ff2b275900ac297cd2913
[libsigrok.git] / src / hardware / scpi-pps / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2014 Bert Vermeulen <bert@biot.com>
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include <config.h>
21 #include <string.h>
22 #include <strings.h>
23 #include "scpi.h"
24 #include "protocol.h"
25
26 SR_PRIV struct sr_dev_driver scpi_pps_driver_info;
27
28 static const uint32_t scanopts[] = {
29         SR_CONF_CONN,
30         SR_CONF_SERIALCOMM,
31 };
32
33 static const uint32_t drvopts[] = {
34         SR_CONF_POWER_SUPPLY,
35 };
36
37 static const struct pps_channel_instance pci[] = {
38         { SR_MQ_VOLTAGE, SCPI_CMD_GET_MEAS_VOLTAGE, "V" },
39         { SR_MQ_CURRENT, SCPI_CMD_GET_MEAS_CURRENT, "I" },
40         { SR_MQ_POWER, SCPI_CMD_GET_MEAS_POWER, "P" },
41         { SR_MQ_FREQUENCY, SCPI_CMD_GET_MEAS_FREQUENCY, "F" },
42 };
43
44 static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
45 {
46         struct dev_context *devc;
47         struct sr_dev_inst *sdi;
48         struct sr_scpi_hw_info *hw_info;
49         struct sr_channel_group *cg;
50         struct sr_channel *ch;
51         const struct scpi_pps *device;
52         struct pps_channel *pch;
53         struct channel_spec *channels;
54         struct channel_group_spec *channel_groups, *cgs;
55         struct pps_channel_group *pcg;
56         GRegex *model_re;
57         GMatchInfo *model_mi;
58         GSList *l;
59         uint64_t mask;
60         unsigned int num_channels, num_channel_groups, ch_num, ch_idx, i, j;
61         int ret;
62         const char *vendor;
63         char ch_name[16];
64
65         if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
66                 sr_info("Couldn't get IDN response.");
67                 return NULL;
68         }
69
70         device = NULL;
71         for (i = 0; i < num_pps_profiles; i++) {
72                 vendor = sr_vendor_alias(hw_info->manufacturer);
73                 if (g_ascii_strcasecmp(vendor, pps_profiles[i].vendor))
74                         continue;
75                 model_re = g_regex_new(pps_profiles[i].model, 0, 0, NULL);
76                 if (g_regex_match(model_re, hw_info->model, 0, &model_mi))
77                         device = &pps_profiles[i];
78                 g_match_info_unref(model_mi);
79                 g_regex_unref(model_re);
80                 if (device)
81                         break;
82         }
83         if (!device) {
84                 sr_scpi_hw_info_free(hw_info);
85                 return NULL;
86         }
87
88         sdi = g_malloc0(sizeof(struct sr_dev_inst));
89         sdi->vendor = g_strdup(vendor);
90         sdi->model = g_strdup(hw_info->model);
91         sdi->version = g_strdup(hw_info->firmware_version);
92         sdi->conn = scpi;
93         sdi->driver = &scpi_pps_driver_info;
94         sdi->inst_type = SR_INST_SCPI;
95         sdi->serial_num = g_strdup(hw_info->serial_number);
96
97         devc = g_malloc0(sizeof(struct dev_context));
98         devc->device = device;
99         sdi->priv = devc;
100
101         if (device->num_channels) {
102                 /* Static channels and groups. */
103                 channels = (struct channel_spec *)device->channels;
104                 num_channels = device->num_channels;
105                 channel_groups = (struct channel_group_spec *)device->channel_groups;
106                 num_channel_groups = device->num_channel_groups;
107         } else {
108                 /* Channels and groups need to be probed. */
109                 ret = device->probe_channels(sdi, hw_info, &channels, &num_channels,
110                                 &channel_groups, &num_channel_groups);
111                 if (ret != SR_OK) {
112                         sr_err("Failed to probe for channels.");
113                         return NULL;
114                 }
115                 /*
116                  * Since these were dynamically allocated, we'll need to free them
117                  * later.
118                  */
119                 devc->channels = channels;
120                 devc->channel_groups = channel_groups;
121         }
122
123         ch_idx = 0;
124         for (ch_num = 0; ch_num < num_channels; ch_num++) {
125                 /* Create one channel per measurable output unit. */
126                 for (i = 0; i < ARRAY_SIZE(pci); i++) {
127                         if (!scpi_cmd_get(devc->device->commands, pci[i].command))
128                                 continue;
129                         g_snprintf(ch_name, 16, "%s%s", pci[i].prefix,
130                                         channels[ch_num].name);
131                         ch = sr_channel_new(sdi, ch_idx++, SR_CHANNEL_ANALOG, TRUE,
132                                         ch_name);
133                         pch = g_malloc0(sizeof(struct pps_channel));
134                         pch->hw_output_idx = ch_num;
135                         pch->hwname = channels[ch_num].name;
136                         pch->mq = pci[i].mq;
137                         ch->priv = pch;
138                 }
139         }
140
141         for (i = 0; i < num_channel_groups; i++) {
142                 cgs = &channel_groups[i];
143                 cg = g_malloc0(sizeof(struct sr_channel_group));
144                 cg->name = g_strdup(cgs->name);
145                 for (j = 0, mask = 1; j < 64; j++, mask <<= 1) {
146                         if (cgs->channel_index_mask & mask) {
147                                 for (l = sdi->channels; l; l = l->next) {
148                                         ch = l->data;
149                                         pch = ch->priv;
150                                         if (pch->hw_output_idx == j)
151                                                 cg->channels = g_slist_append(cg->channels, ch);
152                                 }
153                         }
154                 }
155                 pcg = g_malloc0(sizeof(struct pps_channel_group));
156                 pcg->features = cgs->features;
157                 cg->priv = pcg;
158                 sdi->channel_groups = g_slist_append(sdi->channel_groups, cg);
159         }
160
161         sr_scpi_hw_info_free(hw_info);
162         hw_info = NULL;
163
164         scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
165
166         return sdi;
167 }
168
169 static GSList *scan(struct sr_dev_driver *di, GSList *options)
170 {
171         return sr_scpi_scan(di->context, options, probe_device);
172 }
173
174 static int dev_open(struct sr_dev_inst *sdi)
175 {
176         struct dev_context *devc;
177         struct sr_scpi_dev_inst *scpi;
178         GVariant *beeper;
179
180         if (sdi->status != SR_ST_INACTIVE)
181                 return SR_ERR;
182
183         scpi = sdi->conn;
184         if (sr_scpi_open(scpi) < 0)
185                 return SR_ERR;
186
187         sdi->status = SR_ST_ACTIVE;
188
189         devc = sdi->priv;
190         scpi_cmd(sdi, devc->device->commands, SCPI_CMD_REMOTE);
191         devc->beeper_was_set = FALSE;
192         if (scpi_cmd_resp(sdi, devc->device->commands, &beeper,
193                         G_VARIANT_TYPE_BOOLEAN, SCPI_CMD_BEEPER) == SR_OK) {
194                 if (g_variant_get_boolean(beeper)) {
195                         devc->beeper_was_set = TRUE;
196                         scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_DISABLE);
197                 }
198                 g_variant_unref(beeper);
199         }
200
201         return SR_OK;
202 }
203
204 static int dev_close(struct sr_dev_inst *sdi)
205 {
206         struct sr_scpi_dev_inst *scpi;
207         struct dev_context *devc;
208
209         if (sdi->status != SR_ST_ACTIVE)
210                 return SR_ERR_DEV_CLOSED;
211
212         devc = sdi->priv;
213         scpi = sdi->conn;
214         if (scpi) {
215                 if (devc->beeper_was_set)
216                         scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_ENABLE);
217                 scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
218                 sr_scpi_close(scpi);
219                 sdi->status = SR_ST_INACTIVE;
220         }
221
222         return SR_OK;
223 }
224
225 static void clear_helper(void *priv)
226 {
227         struct dev_context *devc;
228
229         devc = priv;
230         g_free(devc->channels);
231         g_free(devc->channel_groups);
232         g_free(devc);
233 }
234
235 static int dev_clear(const struct sr_dev_driver *di)
236 {
237         return std_dev_clear(di, clear_helper);
238 }
239
240 static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
241                 const struct sr_channel_group *cg)
242 {
243         struct dev_context *devc;
244         const GVariantType *gvtype;
245         unsigned int i;
246         int cmd, ret;
247         const char *s;
248
249         if (!sdi)
250                 return SR_ERR_ARG;
251
252         devc = sdi->priv;
253
254         if (cg) {
255                 /*
256                  * These options only apply to channel groups with a single
257                  * channel -- they're per-channel settings for the device.
258                  */
259
260                 /*
261                  * Config keys are handled below depending on whether a channel
262                  * group was provided by the frontend. However some of these
263                  * take a CG on one PPS but not on others. Check the device's
264                  * profile for that here, and NULL out the channel group as needed.
265                  */
266                 for (i = 0; i < devc->device->num_devopts; i++) {
267                         if (devc->device->devopts[i] == key) {
268                                 cg = NULL;
269                                 break;
270                         }
271                 }
272         }
273
274         gvtype = NULL;
275         cmd = -1;
276         switch (key) {
277         case SR_CONF_ENABLED:
278                 gvtype = G_VARIANT_TYPE_BOOLEAN;
279                 cmd = SCPI_CMD_GET_OUTPUT_ENABLED;
280                 break;
281         case SR_CONF_VOLTAGE:
282                 gvtype = G_VARIANT_TYPE_DOUBLE;
283                 cmd = SCPI_CMD_GET_MEAS_VOLTAGE;
284                 break;
285         case SR_CONF_VOLTAGE_TARGET:
286                 gvtype = G_VARIANT_TYPE_DOUBLE;
287                 cmd = SCPI_CMD_GET_VOLTAGE_TARGET;
288                 break;
289         case SR_CONF_OUTPUT_FREQUENCY:
290                 gvtype = G_VARIANT_TYPE_DOUBLE;
291                 cmd = SCPI_CMD_GET_MEAS_FREQUENCY;
292                 break;
293         case SR_CONF_OUTPUT_FREQUENCY_TARGET:
294                 gvtype = G_VARIANT_TYPE_DOUBLE;
295                 cmd = SCPI_CMD_GET_FREQUENCY_TARGET;
296                 break;
297         case SR_CONF_CURRENT:
298                 gvtype = G_VARIANT_TYPE_DOUBLE;
299                 cmd = SCPI_CMD_GET_MEAS_CURRENT;
300                 break;
301         case SR_CONF_CURRENT_LIMIT:
302                 gvtype = G_VARIANT_TYPE_DOUBLE;
303                 cmd = SCPI_CMD_GET_CURRENT_LIMIT;
304                 break;
305         case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
306                 gvtype = G_VARIANT_TYPE_BOOLEAN;
307                 cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ENABLED;
308                 break;
309         case SR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE:
310                 gvtype = G_VARIANT_TYPE_BOOLEAN;
311                 cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_ACTIVE;
312                 break;
313         case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
314                 gvtype = G_VARIANT_TYPE_DOUBLE;
315                 cmd = SCPI_CMD_GET_OVER_VOLTAGE_PROTECTION_THRESHOLD;
316                 break;
317         case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
318                 gvtype = G_VARIANT_TYPE_BOOLEAN;
319                 cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ENABLED;
320                 break;
321         case SR_CONF_OVER_CURRENT_PROTECTION_ACTIVE:
322                 gvtype = G_VARIANT_TYPE_BOOLEAN;
323                 cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_ACTIVE;
324                 break;
325         case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
326                 gvtype = G_VARIANT_TYPE_DOUBLE;
327                 cmd = SCPI_CMD_GET_OVER_CURRENT_PROTECTION_THRESHOLD;
328                 break;
329         case SR_CONF_OVER_TEMPERATURE_PROTECTION:
330                 gvtype = G_VARIANT_TYPE_BOOLEAN;
331                 cmd = SCPI_CMD_GET_OVER_TEMPERATURE_PROTECTION;
332                 break;
333         case SR_CONF_REGULATION:
334                 gvtype = G_VARIANT_TYPE_STRING;
335                 cmd = SCPI_CMD_GET_OUTPUT_REGULATION;
336         }
337         if (!gvtype)
338                 return SR_ERR_NA;
339
340         if (cg)
341                 select_channel(sdi, cg->channels->data);
342         ret = scpi_cmd_resp(sdi, devc->device->commands, data, gvtype, cmd);
343
344         if (cmd == SCPI_CMD_GET_OUTPUT_REGULATION) {
345                 /*
346                  * The Rigol DP800 series return CV/CC/UR, Philips PM2800
347                  * return VOLT/CURR. We always return a GVariant string in
348                  * the Rigol notation.
349                  */
350                 s = g_variant_get_string(*data, NULL);
351                 if (!strcmp(s, "VOLT")) {
352                         g_variant_unref(*data);
353                         *data = g_variant_new_string("CV");
354                 } else if (!strcmp(s, "CURR")) {
355                         g_variant_unref(*data);
356                         *data = g_variant_new_string("CC");
357                 }
358
359                 s = g_variant_get_string(*data, NULL);
360                 if (strcmp(s, "CV") && strcmp(s, "CC") && strcmp(s, "UR")) {
361                         sr_dbg("Unknown response to SCPI_CMD_GET_OUTPUT_REGULATION: %s", s);
362                         ret = SR_ERR_DATA;
363                 }
364         }
365
366         return ret;
367 }
368
369 static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
370                 const struct sr_channel_group *cg)
371 {
372         struct dev_context *devc;
373         double d;
374         int ret;
375
376         if (!sdi)
377                 return SR_ERR_ARG;
378
379         if (sdi->status != SR_ST_ACTIVE)
380                 return SR_ERR_DEV_CLOSED;
381
382         if (cg)
383                 /* Channel group specified. */
384                 select_channel(sdi, cg->channels->data);
385
386         devc = sdi->priv;
387
388         switch (key) {
389         case SR_CONF_ENABLED:
390                 if (g_variant_get_boolean(data))
391                         ret = scpi_cmd(sdi, devc->device->commands,
392                                         SCPI_CMD_SET_OUTPUT_ENABLE);
393                 else
394                         ret = scpi_cmd(sdi, devc->device->commands,
395                                         SCPI_CMD_SET_OUTPUT_DISABLE);
396                 break;
397         case SR_CONF_VOLTAGE_TARGET:
398                 d = g_variant_get_double(data);
399                 ret = scpi_cmd(sdi, devc->device->commands,
400                                 SCPI_CMD_SET_VOLTAGE_TARGET, d);
401                 break;
402         case SR_CONF_OUTPUT_FREQUENCY_TARGET:
403                 d = g_variant_get_double(data);
404                 ret = scpi_cmd(sdi, devc->device->commands,
405                                 SCPI_CMD_SET_FREQUENCY_TARGET, d);
406                 break;
407         case SR_CONF_CURRENT_LIMIT:
408                 d = g_variant_get_double(data);
409                 ret = scpi_cmd(sdi, devc->device->commands,
410                                 SCPI_CMD_SET_CURRENT_LIMIT, d);
411                 break;
412         case SR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED:
413                 if (g_variant_get_boolean(data))
414                         ret = scpi_cmd(sdi, devc->device->commands,
415                                         SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_ENABLE);
416                 else
417                         ret = scpi_cmd(sdi, devc->device->commands,
418                                         SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_DISABLE);
419                 break;
420         case SR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD:
421                 d = g_variant_get_double(data);
422                 ret = scpi_cmd(sdi, devc->device->commands,
423                                 SCPI_CMD_SET_OVER_VOLTAGE_PROTECTION_THRESHOLD, d);
424                 break;
425         case SR_CONF_OVER_CURRENT_PROTECTION_ENABLED:
426                 if (g_variant_get_boolean(data))
427                         ret = scpi_cmd(sdi, devc->device->commands,
428                                         SCPI_CMD_SET_OVER_CURRENT_PROTECTION_ENABLE);
429                 else
430                         ret = scpi_cmd(sdi, devc->device->commands,
431                                         SCPI_CMD_SET_OVER_CURRENT_PROTECTION_DISABLE);
432                 break;
433         case SR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD:
434                 d = g_variant_get_double(data);
435                 ret = scpi_cmd(sdi, devc->device->commands,
436                                 SCPI_CMD_SET_OVER_CURRENT_PROTECTION_THRESHOLD, d);
437                 break;
438         case SR_CONF_OVER_TEMPERATURE_PROTECTION:
439                 if (g_variant_get_boolean(data))
440                         ret = scpi_cmd(sdi, devc->device->commands,
441                                         SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_ENABLE);
442                 else
443                         ret = scpi_cmd(sdi, devc->device->commands,
444                                         SCPI_CMD_SET_OVER_TEMPERATURE_PROTECTION_DISABLE);
445                 break;
446         default:
447                 ret = SR_ERR_NA;
448         }
449
450         return ret;
451 }
452
453 static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
454                 const struct sr_channel_group *cg)
455 {
456         struct dev_context *devc;
457         struct sr_channel *ch;
458         const struct channel_spec *ch_spec;
459         GVariant *gvar;
460         GVariantBuilder gvb;
461         int ret, i;
462         const char *s[16];
463
464         /* Always available, even without sdi. */
465         if (key == SR_CONF_SCAN_OPTIONS) {
466                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
467                                 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
468                 return SR_OK;
469         } else if (key == SR_CONF_DEVICE_OPTIONS && !sdi) {
470                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
471                                 drvopts, ARRAY_SIZE(drvopts), sizeof(uint32_t));
472                 return SR_OK;
473         }
474
475         if (!sdi)
476                 return SR_ERR_ARG;
477         devc = sdi->priv;
478
479         ret = SR_OK;
480         if (!cg) {
481                 /* No channel group: global options. */
482                 switch (key) {
483                 case SR_CONF_DEVICE_OPTIONS:
484                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
485                                         devc->device->devopts, devc->device->num_devopts,
486                                         sizeof(uint32_t));
487                         break;
488                 case SR_CONF_CHANNEL_CONFIG:
489                         /* Not used. */
490                         i = 0;
491                         if (devc->device->features & PPS_INDEPENDENT)
492                                 s[i++] = "Independent";
493                         if (devc->device->features & PPS_SERIES)
494                                 s[i++] = "Series";
495                         if (devc->device->features & PPS_PARALLEL)
496                                 s[i++] = "Parallel";
497                         if (i == 0) {
498                                 /*
499                                  * Shouldn't happen: independent-only devices
500                                  * shouldn't advertise this option at all.
501                                  */
502                                 return SR_ERR_NA;
503                         }
504                         *data = g_variant_new_strv(s, i);
505                         break;
506                 default:
507                         return SR_ERR_NA;
508                 }
509         } else {
510                 /* Channel group specified. */
511                 /*
512                  * Per-channel-group options depending on a channel are actually
513                  * done with the first channel. Channel groups in PPS can have
514                  * more than one channel, but they will typically be of equal
515                  * specification for use in series or parallel mode.
516                  */
517                 ch = cg->channels->data;
518
519                 switch (key) {
520                 case SR_CONF_DEVICE_OPTIONS:
521                         *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
522                                         devc->device->devopts_cg, devc->device->num_devopts_cg,
523                                         sizeof(uint32_t));
524                         break;
525                 case SR_CONF_VOLTAGE_TARGET:
526                         ch_spec = &(devc->device->channels[ch->index]);
527                         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
528                         /* Min, max, write resolution. */
529                         for (i = 0; i < 3; i++) {
530                                 gvar = g_variant_new_double(ch_spec->voltage[i]);
531                                 g_variant_builder_add_value(&gvb, gvar);
532                         }
533                         *data = g_variant_builder_end(&gvb);
534                         break;
535                 case SR_CONF_OUTPUT_FREQUENCY_TARGET:
536                         ch_spec = &(devc->device->channels[ch->index]);
537                         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
538                         /* Min, max, write resolution. */
539                         for (i = 0; i < 3; i++) {
540                                 gvar = g_variant_new_double(ch_spec->frequency[i]);
541                                 g_variant_builder_add_value(&gvb, gvar);
542                         }
543                         *data = g_variant_builder_end(&gvb);
544                         break;
545                 case SR_CONF_CURRENT_LIMIT:
546                         g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
547                         /* Min, max, step. */
548                         for (i = 0; i < 3; i++) {
549                                 ch_spec = &(devc->device->channels[ch->index]);
550                                 gvar = g_variant_new_double(ch_spec->current[i]);
551                                 g_variant_builder_add_value(&gvb, gvar);
552                         }
553                         *data = g_variant_builder_end(&gvb);
554                         break;
555                 default:
556                         return SR_ERR_NA;
557                 }
558         }
559
560         return ret;
561 }
562
563 static int dev_acquisition_start(const struct sr_dev_inst *sdi)
564 {
565         struct dev_context *devc;
566         struct sr_scpi_dev_inst *scpi;
567         struct sr_channel *ch;
568         struct pps_channel *pch;
569         int cmd, ret;
570
571         if (sdi->status != SR_ST_ACTIVE)
572                 return SR_ERR_DEV_CLOSED;
573
574         devc = sdi->priv;
575         scpi = sdi->conn;
576
577         if ((ret = sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 10,
578                         scpi_pps_receive_data, (void *)sdi)) != SR_OK)
579                 return ret;
580         std_session_send_df_header(sdi, LOG_PREFIX);
581
582         /* Prime the pipe with the first channel's fetch. */
583         ch = sr_next_enabled_channel(sdi, NULL);
584         pch = ch->priv;
585         if ((ret = select_channel(sdi, ch)) < 0)
586                 return ret;
587         if (pch->mq == SR_MQ_VOLTAGE)
588                 cmd = SCPI_CMD_GET_MEAS_VOLTAGE;
589         else if (pch->mq == SR_MQ_FREQUENCY)
590                 cmd = SCPI_CMD_GET_MEAS_FREQUENCY;
591         else if (pch->mq == SR_MQ_CURRENT)
592                 cmd = SCPI_CMD_GET_MEAS_CURRENT;
593         else if (pch->mq == SR_MQ_POWER)
594                 cmd = SCPI_CMD_GET_MEAS_POWER;
595         else
596                 return SR_ERR;
597         scpi_cmd(sdi, devc->device->commands, cmd, pch->hwname);
598
599         return SR_OK;
600 }
601
602 static int dev_acquisition_stop(struct sr_dev_inst *sdi)
603 {
604         struct sr_scpi_dev_inst *scpi;
605         float f;
606
607         if (sdi->status != SR_ST_ACTIVE)
608                 return SR_ERR_DEV_CLOSED;
609
610         scpi = sdi->conn;
611
612         /*
613          * A requested value is certainly on the way. Retrieve it now,
614          * to avoid leaving the device in a state where it's not expecting
615          * commands.
616          */
617         sr_scpi_get_float(scpi, NULL, &f);
618         sr_scpi_source_remove(sdi->session, scpi);
619
620         std_session_send_df_end(sdi, LOG_PREFIX);
621
622         return SR_OK;
623 }
624
625 SR_PRIV struct sr_dev_driver scpi_pps_driver_info = {
626         .name = "scpi-pps",
627         .longname = "SCPI PPS",
628         .api_version = 1,
629         .init = std_init,
630         .cleanup = std_cleanup,
631         .scan = scan,
632         .dev_list = std_dev_list,
633         .dev_clear = dev_clear,
634         .config_get = config_get,
635         .config_set = config_set,
636         .config_list = config_list,
637         .dev_open = dev_open,
638         .dev_close = dev_close,
639         .dev_acquisition_start = dev_acquisition_start,
640         .dev_acquisition_stop = dev_acquisition_stop,
641         .context = NULL,
642 };