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