]> sigrok.org Git - libsigrok.git/blame_incremental - hardware/rigol-ds/api.c
scpi: add VXI transport support
[libsigrok.git] / hardware / rigol-ds / api.c
... / ...
CommitLineData
1/*
2 * This file is part of the libsigrok project.
3 *
4 * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
5 * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6 * Copyright (C) 2013 Mathias Grimmberger <mgri@zaphod.sax.de>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
26#include <glib.h>
27#include "libsigrok.h"
28#include "libsigrok-internal.h"
29#include "protocol.h"
30
31static const int32_t hwopts[] = {
32 SR_CONF_CONN,
33 SR_CONF_SERIALCOMM
34};
35
36static const int32_t hwcaps[] = {
37 SR_CONF_OSCILLOSCOPE,
38 SR_CONF_TIMEBASE,
39 SR_CONF_TRIGGER_SOURCE,
40 SR_CONF_TRIGGER_SLOPE,
41 SR_CONF_HORIZ_TRIGGERPOS,
42 SR_CONF_NUM_TIMEBASE,
43};
44
45static const int32_t analog_hwcaps[] = {
46 SR_CONF_NUM_VDIV,
47 SR_CONF_VDIV,
48 SR_CONF_COUPLING,
49 SR_CONF_DATA_SOURCE,
50};
51
52static const uint64_t timebases[][2] = {
53 /* nanoseconds */
54 { 2, 1000000000 },
55 { 5, 1000000000 },
56 { 10, 1000000000 },
57 { 20, 1000000000 },
58 { 50, 1000000000 },
59 { 100, 1000000000 },
60 { 500, 1000000000 },
61 /* microseconds */
62 { 1, 1000000 },
63 { 2, 1000000 },
64 { 5, 1000000 },
65 { 10, 1000000 },
66 { 20, 1000000 },
67 { 50, 1000000 },
68 { 100, 1000000 },
69 { 200, 1000000 },
70 { 500, 1000000 },
71 /* milliseconds */
72 { 1, 1000 },
73 { 2, 1000 },
74 { 5, 1000 },
75 { 10, 1000 },
76 { 20, 1000 },
77 { 50, 1000 },
78 { 100, 1000 },
79 { 200, 1000 },
80 { 500, 1000 },
81 /* seconds */
82 { 1, 1 },
83 { 2, 1 },
84 { 5, 1 },
85 { 10, 1 },
86 { 20, 1 },
87 { 50, 1 },
88 { 100, 1 },
89 { 200, 1 },
90 { 500, 1 },
91 /* { 1000, 1 }, Confuses other code? */
92};
93
94static const uint64_t vdivs[][2] = {
95 /* microvolts */
96 { 500, 1000000 },
97 /* millivolts */
98 { 1, 1000 },
99 { 2, 1000 },
100 { 5, 1000 },
101 { 10, 1000 },
102 { 20, 1000 },
103 { 50, 1000 },
104 { 100, 1000 },
105 { 200, 1000 },
106 { 500, 1000 },
107 /* volts */
108 { 1, 1 },
109 { 2, 1 },
110 { 5, 1 },
111 { 10, 1 },
112};
113
114#define NUM_TIMEBASE ARRAY_SIZE(timebases)
115#define NUM_VDIV ARRAY_SIZE(vdivs)
116
117static const char *trigger_sources[] = {
118 "CH1",
119 "CH2",
120 "CH3",
121 "CH4",
122 "EXT",
123 "AC Line",
124 "D0",
125 "D1",
126 "D2",
127 "D3",
128 "D4",
129 "D5",
130 "D6",
131 "D7",
132 "D8",
133 "D9",
134 "D10",
135 "D11",
136 "D12",
137 "D13",
138 "D14",
139 "D15",
140};
141
142static const char *coupling[] = {
143 "AC",
144 "DC",
145 "GND",
146};
147
148/* Do not change the order of entries */
149static const char *data_sources[] = {
150 "Live",
151 "Memory",
152 "Segmented",
153};
154
155/*
156 * name, series, protocol flavor, min timebase, max timebase, min vdiv,
157 * digital channels, number of horizontal divs
158 */
159
160#define RIGOL "Rigol Technologies"
161#define AGILENT "Agilent Technologies"
162
163static const struct rigol_ds_model supported_models[] = {
164 {RIGOL, "DS1052E", RIGOL_DS1000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
165 {RIGOL, "DS1102E", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
166 {RIGOL, "DS1152E", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
167 {RIGOL, "DS1052D", RIGOL_DS1000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
168 {RIGOL, "DS1102D", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
169 {RIGOL, "DS1152D", RIGOL_DS1000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
170 {RIGOL, "DS2072", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
171 {RIGOL, "DS2102", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
172 {RIGOL, "DS2202", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
173 {RIGOL, "DS2302", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
174 {RIGOL, "DS2072A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
175 {RIGOL, "DS2102A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
176 {RIGOL, "DS2202A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
177 {RIGOL, "DS2302A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
178 {RIGOL, "VS5022", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
179 {RIGOL, "VS5022D", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
180 {RIGOL, "VS5042", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
181 {RIGOL, "VS5042D", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
182 {RIGOL, "VS5062", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
183 {RIGOL, "VS5062D", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
184 {RIGOL, "VS5102", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
185 {RIGOL, "VS5102D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
186 {RIGOL, "VS5202", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
187 {RIGOL, "VS5202D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
188 {AGILENT, "DSO1002A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
189 {AGILENT, "DSO1004A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
190 {AGILENT, "DSO1012A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
191 {AGILENT, "DSO1014A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
192 {AGILENT, "DSO1022A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
193 {AGILENT, "DSO1024A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
194};
195
196SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
197static struct sr_dev_driver *di = &rigol_ds_driver_info;
198
199static void clear_helper(void *priv)
200{
201 struct dev_context *devc;
202
203 devc = priv;
204 g_free(devc->data);
205 g_free(devc->buffer);
206 g_free(devc->coupling[0]);
207 g_free(devc->coupling[1]);
208 g_free(devc->trigger_source);
209 g_free(devc->trigger_slope);
210 g_slist_free(devc->analog_groups[0].probes);
211 g_slist_free(devc->analog_groups[1].probes);
212 g_slist_free(devc->digital_group.probes);
213}
214
215static int dev_clear(void)
216{
217 return std_dev_clear(di, clear_helper);
218}
219
220static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
221{
222 va_list args;
223 int ret;
224
225 va_start(args, format);
226 ret = sr_scpi_send_variadic(sdi->conn, format, args);
227 va_end(args);
228
229 if (ret != SR_OK)
230 return SR_ERR;
231
232 /* When setting a bunch of parameters in a row, the DS1052E scrambles
233 * some of them unless there is at least 100ms delay in between. */
234 sr_spew("delay %dms", 100);
235 g_usleep(100000);
236
237 return SR_OK;
238}
239
240static int init(struct sr_context *sr_ctx)
241{
242 return std_init(sr_ctx, di, LOG_PREFIX);
243}
244
245static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
246{
247 struct dev_context *devc;
248 struct sr_dev_inst *sdi;
249 const char *usbtmc_prefix = "/dev/usbtmc";
250 const char *tcp_prefix = "tcp/";
251 const char *vxi_prefix = "vxi/";
252 gchar **tokens, *address, *port, *instrument;
253 struct sr_scpi_dev_inst *scpi;
254 struct sr_scpi_hw_info *hw_info;
255 struct sr_probe *probe;
256 unsigned int i;
257 const struct rigol_ds_model *model = NULL;
258 gchar *channel_name;
259
260 *devices = NULL;
261
262 if (strncmp(resource, usbtmc_prefix, strlen(usbtmc_prefix)) == 0) {
263 sr_dbg("Opening USBTMC device %s.", resource);
264 if (!(scpi = scpi_usbtmc_dev_inst_new(resource)))
265 return SR_ERR_MALLOC;
266 } else if (strncmp(resource, tcp_prefix, strlen(tcp_prefix)) == 0) {
267 sr_dbg("Opening TCP connection %s.", resource);
268 tokens = g_strsplit(resource + strlen(tcp_prefix), "/", 0);
269 address = tokens[0];
270 port = tokens[1];
271 if (!address || !port || tokens[2]) {
272 sr_err("Invalid parameters.");
273 g_strfreev(tokens);
274 return SR_ERR_ARG;
275 }
276 scpi = scpi_tcp_dev_inst_new(address, port);
277 g_strfreev(tokens);
278 if (!scpi)
279 return SR_ERR_MALLOC;
280 } else if (HAVE_RPC && !strncmp(resource, vxi_prefix, strlen(vxi_prefix))) {
281 sr_dbg("Opening VXI connection %s.", resource);
282 tokens = g_strsplit(resource + strlen(tcp_prefix), "/", 0);
283 address = tokens[0];
284 instrument = tokens[1];
285 if (!address) {
286 sr_err("Invalid parameters.");
287 g_strfreev(tokens);
288 return SR_ERR_ARG;
289 }
290 scpi = scpi_vxi_dev_inst_new(address, instrument);
291 g_strfreev(tokens);
292 if (!scpi)
293 return SR_ERR_MALLOC;
294 } else {
295 sr_dbg("Opening serial device %s.", resource);
296 if (!(scpi = scpi_serial_dev_inst_new(resource, serialcomm)))
297 return SR_ERR_MALLOC;
298 }
299
300 if (sr_scpi_open(scpi) != SR_OK) {
301 sr_info("Couldn't open SCPI device.");
302 sr_scpi_free(scpi);
303 return SR_ERR;
304 };
305
306 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
307 sr_info("Couldn't get IDN response.");
308 sr_scpi_close(scpi);
309 sr_scpi_free(scpi);
310 return SR_ERR;
311 }
312
313 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
314 if (!strcasecmp(hw_info->manufacturer, supported_models[i].vendor) &&
315 !strcmp(hw_info->model, supported_models[i].name)) {
316 model = &supported_models[i];
317 break;
318 }
319 }
320
321 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
322 hw_info->manufacturer, hw_info->model,
323 hw_info->firmware_version))) {
324 sr_scpi_hw_info_free(hw_info);
325 sr_scpi_close(scpi);
326 sr_scpi_free(scpi);
327 return SR_ERR_NA;
328 }
329
330 sr_scpi_hw_info_free(hw_info);
331 sr_scpi_close(scpi);
332
333 sdi->conn = scpi;
334
335 sdi->driver = di;
336 sdi->inst_type = SR_INST_SCPI;
337
338 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
339 return SR_ERR_MALLOC;
340
341 devc->limit_frames = 0;
342 devc->model = model;
343
344 for (i = 0; i < model->analog_channels; i++) {
345 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
346 return SR_ERR_MALLOC;
347 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
348 sdi->probes = g_slist_append(sdi->probes, probe);
349 devc->analog_groups[i].name = channel_name;
350 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
351 sdi->probe_groups = g_slist_append(sdi->probe_groups,
352 &devc->analog_groups[i]);
353 }
354
355 if (devc->model->has_digital) {
356 for (i = 0; i < 16; i++) {
357 if (!(channel_name = g_strdup_printf("D%d", i)))
358 return SR_ERR_MALLOC;
359 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
360 g_free(channel_name);
361 if (!probe)
362 return SR_ERR_MALLOC;
363 sdi->probes = g_slist_append(sdi->probes, probe);
364 devc->digital_group.probes = g_slist_append(
365 devc->digital_group.probes, probe);
366 }
367 devc->digital_group.name = "LA";
368 sdi->probe_groups = g_slist_append(sdi->probe_groups,
369 &devc->digital_group);
370 }
371
372 for (i = 0; i < NUM_TIMEBASE; i++) {
373 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
374 devc->timebases = &timebases[i];
375 if (!memcmp(&devc->model->max_timebase, &timebases[i], sizeof(uint64_t[2])))
376 devc->num_timebases = &timebases[i] - devc->timebases + 1;
377 }
378
379 for (i = 0; i < NUM_VDIV; i++)
380 if (!memcmp(&devc->model->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
381 devc->vdivs = &vdivs[i];
382
383 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
384 return SR_ERR_MALLOC;
385 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
386 return SR_ERR_MALLOC;
387
388 devc->data_source = DATA_SOURCE_LIVE;
389
390 sdi->priv = devc;
391
392 *devices = g_slist_append(NULL, sdi);
393
394 return SR_OK;
395}
396
397static GSList *scan(GSList *options)
398{
399 struct drv_context *drvc;
400 struct sr_config *src;
401 GSList *l, *devices;
402 GDir *dir;
403 int ret;
404 const gchar *dev_name;
405 gchar *port = NULL;
406 gchar *serialcomm = NULL;
407
408 drvc = di->priv;
409
410 for (l = options; l; l = l->next) {
411 src = l->data;
412 switch (src->key) {
413 case SR_CONF_CONN:
414 port = (char *)g_variant_get_string(src->data, NULL);
415 break;
416 case SR_CONF_SERIALCOMM:
417 serialcomm = (char *)g_variant_get_string(src->data, NULL);
418 break;
419 }
420 }
421
422 devices = NULL;
423 if (port) {
424 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
425 g_free(port);
426 if (serialcomm)
427 g_free(serialcomm);
428 return NULL;
429 }
430 } else {
431 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
432 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
433 return NULL;
434 while ((dev_name = g_dir_read_name(dir))) {
435 if (strncmp(dev_name, "usbtmc", 6))
436 continue;
437 port = g_strconcat("/dev/", dev_name, NULL);
438 ret = probe_port(port, serialcomm, &devices);
439 g_free(port);
440 if (serialcomm)
441 g_free(serialcomm);
442 if (ret == SR_ERR_MALLOC) {
443 g_dir_close(dir);
444 return NULL;
445 }
446 }
447 g_dir_close(dir);
448 }
449
450 /* Tack a copy of the newly found devices onto the driver list. */
451 l = g_slist_copy(devices);
452 drvc->instances = g_slist_concat(drvc->instances, l);
453
454 return devices;
455}
456
457static GSList *dev_list(void)
458{
459 return ((struct drv_context *)(di->priv))->instances;
460}
461
462static int dev_open(struct sr_dev_inst *sdi)
463{
464 struct sr_scpi_dev_inst *scpi = sdi->conn;
465
466 if (sr_scpi_open(scpi) < 0)
467 return SR_ERR;
468
469 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
470 return SR_ERR;
471
472 sdi->status = SR_ST_ACTIVE;
473
474 return SR_OK;
475}
476
477static int dev_close(struct sr_dev_inst *sdi)
478{
479 struct sr_scpi_dev_inst *scpi;
480
481 scpi = sdi->conn;
482
483 if (scpi) {
484 if (sr_scpi_close(scpi) < 0)
485 return SR_ERR;
486 sdi->status = SR_ST_INACTIVE;
487 }
488
489 return SR_OK;
490}
491
492static int cleanup(void)
493{
494 return dev_clear();
495}
496
497static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
498 const struct sr_probe_group *probe_group)
499{
500 struct dev_context *devc;
501
502 if (!sdi || !(devc = sdi->priv))
503 return SR_ERR_ARG;
504
505 /* If a probe group is specified, it must be a valid one. */
506 if (probe_group) {
507 if (probe_group != &devc->analog_groups[0]
508 && probe_group != &devc->analog_groups[1]) {
509 sr_err("Invalid probe group specified.");
510 return SR_ERR;
511 }
512 }
513
514 switch (id) {
515 case SR_CONF_NUM_TIMEBASE:
516 *data = g_variant_new_int32(devc->model->num_horizontal_divs);
517 break;
518 case SR_CONF_NUM_VDIV:
519 *data = g_variant_new_int32(8);
520 case SR_CONF_DATA_SOURCE:
521 if (devc->data_source == DATA_SOURCE_LIVE)
522 *data = g_variant_new_string("Live");
523 else if (devc->data_source == DATA_SOURCE_MEMORY)
524 *data = g_variant_new_string("Memory");
525 else
526 *data = g_variant_new_string("Segmented");
527 break;
528 default:
529 return SR_ERR_NA;
530 }
531
532 return SR_OK;
533}
534
535static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
536 const struct sr_probe_group *probe_group)
537{
538 struct dev_context *devc;
539 uint64_t tmp_u64, p, q;
540 double t_dbl;
541 unsigned int i, j;
542 int ret;
543 const char *tmp_str;
544
545 if (!(devc = sdi->priv))
546 return SR_ERR_ARG;
547
548 if (sdi->status != SR_ST_ACTIVE)
549 return SR_ERR_DEV_CLOSED;
550
551 /* If a probe group is specified, it must be a valid one. */
552 if (probe_group) {
553 if (probe_group != &devc->analog_groups[0]
554 && probe_group != &devc->analog_groups[1]) {
555 sr_err("Invalid probe group specified.");
556 return SR_ERR;
557 }
558 }
559
560 ret = SR_OK;
561 switch (id) {
562 case SR_CONF_LIMIT_FRAMES:
563 devc->limit_frames = g_variant_get_uint64(data);
564 break;
565 case SR_CONF_TRIGGER_SLOPE:
566 tmp_u64 = g_variant_get_uint64(data);
567 if (tmp_u64 != 0 && tmp_u64 != 1)
568 return SR_ERR;
569 g_free(devc->trigger_slope);
570 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
571 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
572 break;
573 case SR_CONF_HORIZ_TRIGGERPOS:
574 t_dbl = g_variant_get_double(data);
575 if (t_dbl < 0.0 || t_dbl > 1.0)
576 return SR_ERR;
577 devc->horiz_triggerpos = t_dbl;
578 /* We have the trigger offset as a percentage of the frame, but
579 * need to express this in seconds. */
580 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
581 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
582 break;
583 case SR_CONF_TIMEBASE:
584 g_variant_get(data, "(tt)", &p, &q);
585 for (i = 0; i < devc->num_timebases; i++) {
586 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
587 devc->timebase = (float)p / q;
588 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
589 break;
590 }
591 }
592 if (i == devc->num_timebases)
593 ret = SR_ERR_ARG;
594 break;
595 case SR_CONF_TRIGGER_SOURCE:
596 tmp_str = g_variant_get_string(data, NULL);
597 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
598 if (!strcmp(trigger_sources[i], tmp_str)) {
599 g_free(devc->trigger_source);
600 devc->trigger_source = g_strdup(trigger_sources[i]);
601 if (!strcmp(devc->trigger_source, "AC Line"))
602 tmp_str = "ACL";
603 else if (!strcmp(devc->trigger_source, "CH1"))
604 tmp_str = "CHAN1";
605 else if (!strcmp(devc->trigger_source, "CH2"))
606 tmp_str = "CHAN2";
607 else if (!strcmp(devc->trigger_source, "CH3"))
608 tmp_str = "CHAN3";
609 else if (!strcmp(devc->trigger_source, "CH4"))
610 tmp_str = "CHAN4";
611 else
612 tmp_str = (char *)devc->trigger_source;
613 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
614 break;
615 }
616 }
617 if (i == ARRAY_SIZE(trigger_sources))
618 ret = SR_ERR_ARG;
619 break;
620 case SR_CONF_VDIV:
621 if (!probe_group) {
622 sr_err("No probe group specified.");
623 return SR_ERR_PROBE_GROUP;
624 }
625 g_variant_get(data, "(tt)", &p, &q);
626 for (i = 0; i < 2; i++) {
627 if (probe_group == &devc->analog_groups[i]) {
628 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
629 if (vdivs[j][0] != p || vdivs[j][1] != q)
630 continue;
631 devc->vdiv[i] = (float)p / q;
632 return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
633 devc->vdiv[i]);
634 }
635 return SR_ERR_ARG;
636 }
637 }
638 return SR_ERR_NA;
639 case SR_CONF_COUPLING:
640 if (!probe_group) {
641 sr_err("No probe group specified.");
642 return SR_ERR_PROBE_GROUP;
643 }
644 tmp_str = g_variant_get_string(data, NULL);
645 for (i = 0; i < 2; i++) {
646 if (probe_group == &devc->analog_groups[i]) {
647 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
648 if (!strcmp(tmp_str, coupling[j])) {
649 g_free(devc->coupling[i]);
650 devc->coupling[i] = g_strdup(coupling[j]);
651 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
652 devc->coupling[i]);
653 }
654 }
655 return SR_ERR_ARG;
656 }
657 }
658 return SR_ERR_NA;
659 case SR_CONF_DATA_SOURCE:
660 tmp_str = g_variant_get_string(data, NULL);
661 if (!strcmp(tmp_str, "Live"))
662 devc->data_source = DATA_SOURCE_LIVE;
663 else if (!strcmp(tmp_str, "Memory"))
664 devc->data_source = DATA_SOURCE_MEMORY;
665 else if (devc->model->protocol == PROTOCOL_IEEE488_2
666 && !strcmp(tmp_str, "Segmented"))
667 devc->data_source = DATA_SOURCE_SEGMENTED;
668 else
669 return SR_ERR;
670 break;
671 default:
672 ret = SR_ERR_NA;
673 break;
674 }
675
676 return ret;
677}
678
679static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
680 const struct sr_probe_group *probe_group)
681{
682 GVariant *tuple, *rational[2];
683 GVariantBuilder gvb;
684 unsigned int i;
685 struct dev_context *devc = NULL;
686
687 if (sdi)
688 devc = sdi->priv;
689
690 if (key == SR_CONF_SCAN_OPTIONS) {
691 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
692 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
693 return SR_OK;
694 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
695 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
696 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
697 return SR_OK;
698 }
699
700 /* Every other option requires a valid device instance. */
701 if (!sdi || !(devc = sdi->priv))
702 return SR_ERR_ARG;
703
704 /* If a probe group is specified, it must be a valid one. */
705 if (probe_group) {
706 if (probe_group != &devc->analog_groups[0]
707 && probe_group != &devc->analog_groups[1]) {
708 sr_err("Invalid probe group specified.");
709 return SR_ERR;
710 }
711 }
712
713 switch (key) {
714 break;
715 case SR_CONF_DEVICE_OPTIONS:
716 if (!probe_group) {
717 sr_err("No probe group specified.");
718 return SR_ERR_PROBE_GROUP;
719 }
720 if (probe_group == &devc->digital_group) {
721 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
722 NULL, 0, sizeof(int32_t));
723 return SR_OK;
724 } else {
725 for (i = 0; i < 2; i++) {
726 if (probe_group == &devc->analog_groups[i]) {
727 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
728 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
729 return SR_OK;
730 }
731 }
732 return SR_ERR_NA;
733 }
734 break;
735 case SR_CONF_COUPLING:
736 if (!probe_group) {
737 sr_err("No probe group specified.");
738 return SR_ERR_PROBE_GROUP;
739 }
740 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
741 break;
742 case SR_CONF_VDIV:
743 if (!devc)
744 /* Can't know this until we have the exact model. */
745 return SR_ERR_ARG;
746 if (!probe_group) {
747 sr_err("No probe group specified.");
748 return SR_ERR_PROBE_GROUP;
749 }
750 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
751 for (i = 0; i < NUM_VDIV; i++) {
752 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
753 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
754 tuple = g_variant_new_tuple(rational, 2);
755 g_variant_builder_add_value(&gvb, tuple);
756 }
757 *data = g_variant_builder_end(&gvb);
758 break;
759 case SR_CONF_TIMEBASE:
760 if (!devc)
761 /* Can't know this until we have the exact model. */
762 return SR_ERR_ARG;
763 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
764 for (i = 0; i < devc->num_timebases; i++) {
765 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
766 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
767 tuple = g_variant_new_tuple(rational, 2);
768 g_variant_builder_add_value(&gvb, tuple);
769 }
770 *data = g_variant_builder_end(&gvb);
771 break;
772 case SR_CONF_TRIGGER_SOURCE:
773 if (!devc)
774 /* Can't know this until we have the exact model. */
775 return SR_ERR_ARG;
776 *data = g_variant_new_strv(trigger_sources,
777 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
778 break;
779 case SR_CONF_DATA_SOURCE:
780 if (!devc)
781 /* Can't know this until we have the exact model. */
782 return SR_ERR_ARG;
783 /* This needs tweaking by series/model! */
784 if (devc->model->series == RIGOL_DS2000)
785 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
786 else
787 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
788 break;
789 default:
790 return SR_ERR_NA;
791 }
792
793 return SR_OK;
794}
795
796static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
797{
798 struct sr_scpi_dev_inst *scpi;
799 struct dev_context *devc;
800 struct sr_probe *probe;
801 GSList *l;
802
803 if (sdi->status != SR_ST_ACTIVE)
804 return SR_ERR_DEV_CLOSED;
805
806 scpi = sdi->conn;
807 devc = sdi->priv;
808
809 for (l = sdi->probes; l; l = l->next) {
810 probe = l->data;
811 sr_dbg("handling probe %s", probe->name);
812 if (probe->type == SR_PROBE_ANALOG) {
813 if (probe->enabled)
814 devc->enabled_analog_probes = g_slist_append(
815 devc->enabled_analog_probes, probe);
816 if (probe->enabled != devc->analog_channels[probe->index]) {
817 /* Enabled channel is currently disabled, or vice versa. */
818 if (set_cfg(sdi, ":CHAN%d:DISP %s", probe->index + 1,
819 probe->enabled ? "ON" : "OFF") != SR_OK)
820 return SR_ERR;
821 }
822 } else if (probe->type == SR_PROBE_LOGIC) {
823 if (probe->enabled)
824 devc->enabled_digital_probes = g_slist_append(
825 devc->enabled_digital_probes, probe);
826 if (probe->enabled != devc->digital_channels[probe->index]) {
827 /* Enabled channel is currently disabled, or vice versa. */
828 if (set_cfg(sdi, ":DIG%d:TURN %s", probe->index,
829 probe->enabled ? "ON" : "OFF") != SR_OK)
830 return SR_ERR;
831 }
832 }
833 }
834
835 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
836 return SR_ERR;
837
838 if (devc->data_source == DATA_SOURCE_LIVE) {
839 if (set_cfg(sdi, ":RUN") != SR_OK)
840 return SR_ERR;
841 } else if (devc->data_source == DATA_SOURCE_MEMORY) {
842 if (devc->model->series != RIGOL_DS2000) {
843 sr_err("Data source 'Memory' not supported for this device");
844 return SR_ERR;
845 }
846 } else if (devc->data_source == DATA_SOURCE_SEGMENTED) {
847 sr_err("Data source 'Segmented' not yet supported");
848 return SR_ERR;
849 }
850
851 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
852
853 /* Send header packet to the session bus. */
854 std_session_send_df_header(cb_data, LOG_PREFIX);
855
856 if (devc->enabled_analog_probes)
857 devc->channel_entry = devc->enabled_analog_probes;
858 else
859 devc->channel_entry = devc->enabled_digital_probes;
860
861 if (devc->model->protocol == PROTOCOL_LEGACY) {
862 devc->analog_frame_size = (devc->model->series == RIGOL_VS5000 ?
863 VS5000_ANALOG_LIVE_WAVEFORM_SIZE :
864 DS1000_ANALOG_LIVE_WAVEFORM_SIZE);
865 /* Fetch the first frame. */
866 if (rigol_ds_channel_start(sdi) != SR_OK)
867 return SR_ERR;
868 } else {
869 if (devc->enabled_analog_probes) {
870 if (devc->data_source == DATA_SOURCE_MEMORY)
871 {
872 if (g_slist_length(devc->enabled_analog_probes) == 1)
873 devc->analog_frame_size = DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
874 else
875 devc->analog_frame_size = DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
876 /* Apparently for the DS2000 the memory
877 * depth can only be set in Running state -
878 * this matches the behaviour of the UI. */
879 if (set_cfg(sdi, ":RUN") != SR_OK)
880 return SR_ERR;
881 if (set_cfg(sdi, "ACQ:MDEP %d", devc->analog_frame_size) != SR_OK)
882 return SR_ERR;
883 if (set_cfg(sdi, ":STOP") != SR_OK)
884 return SR_ERR;
885 } else {
886 if (devc->model->series == AGILENT_DSO1000)
887 devc->analog_frame_size = DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
888 else
889 devc->analog_frame_size = DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
890 }
891 if (rigol_ds_capture_start(sdi) != SR_OK)
892 return SR_ERR;
893 }
894 }
895
896 return SR_OK;
897}
898
899static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
900{
901 struct dev_context *devc;
902 struct sr_scpi_dev_inst *scpi;
903
904 (void)cb_data;
905
906 devc = sdi->priv;
907
908 if (sdi->status != SR_ST_ACTIVE) {
909 sr_err("Device inactive, can't stop acquisition.");
910 return SR_ERR;
911 }
912
913 g_slist_free(devc->enabled_analog_probes);
914 g_slist_free(devc->enabled_digital_probes);
915 devc->enabled_analog_probes = NULL;
916 devc->enabled_digital_probes = NULL;
917 scpi = sdi->conn;
918 sr_scpi_source_remove(scpi);
919
920 return SR_OK;
921}
922
923SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
924 .name = "rigol-ds",
925 .longname = "Rigol DS",
926 .api_version = 1,
927 .init = init,
928 .cleanup = cleanup,
929 .scan = scan,
930 .dev_list = dev_list,
931 .dev_clear = dev_clear,
932 .config_get = config_get,
933 .config_set = config_set,
934 .config_list = config_list,
935 .dev_open = dev_open,
936 .dev_close = dev_close,
937 .dev_acquisition_start = dev_acquisition_start,
938 .dev_acquisition_stop = dev_acquisition_stop,
939 .priv = NULL,
940};