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