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