]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds1xx2/api.c
rigol-ds1xx2: newer Linux kernels have USBTMC in /sys/class/usbmisc
[libsigrok.git] / hardware / rigol-ds1xx2 / 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>
f4816ac6
ML
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
e0b7d23c
ML
21#include <fcntl.h>
22#include <unistd.h>
23#include <stdlib.h>
24#include <string.h>
f4816ac6
ML
25#include <glib.h>
26#include "libsigrok.h"
27#include "libsigrok-internal.h"
28#include "protocol.h"
29
d62d7ad1
BV
30#define NUM_TIMEBASE 12
31#define NUM_VDIV 8
32
ca55277c
ML
33static const int32_t hwopts[] = {
34 SR_CONF_CONN,
35};
36
f6a0ac9f 37static const int32_t hwcaps[] = {
1953564a 38 SR_CONF_OSCILLOSCOPE,
1953564a
BV
39 SR_CONF_TIMEBASE,
40 SR_CONF_TRIGGER_SOURCE,
41 SR_CONF_TRIGGER_SLOPE,
42 SR_CONF_HORIZ_TRIGGERPOS,
43 SR_CONF_VDIV,
44 SR_CONF_COUPLING,
d62d7ad1
BV
45 SR_CONF_NUM_TIMEBASE,
46 SR_CONF_NUM_VDIV,
e0b7d23c
ML
47};
48
f6a0ac9f 49static const uint64_t timebases[][2] = {
e0b7d23c
ML
50 /* nanoseconds */
51 { 2, 1000000000 },
52 { 5, 1000000000 },
53 { 10, 1000000000 },
54 { 20, 1000000000 },
55 { 50, 1000000000 },
56 { 100, 1000000000 },
57 { 500, 1000000000 },
58 /* microseconds */
59 { 1, 1000000 },
60 { 2, 1000000 },
61 { 5, 1000000 },
62 { 10, 1000000 },
63 { 20, 1000000 },
64 { 50, 1000000 },
65 { 100, 1000000 },
66 { 200, 1000000 },
67 { 500, 1000000 },
68 /* milliseconds */
69 { 1, 1000 },
70 { 2, 1000 },
71 { 5, 1000 },
72 { 10, 1000 },
73 { 20, 1000 },
74 { 50, 1000 },
75 { 100, 1000 },
76 { 200, 1000 },
77 { 500, 1000 },
78 /* seconds */
79 { 1, 1 },
80 { 2, 1 },
81 { 5, 1 },
82 { 10, 1 },
83 { 20, 1 },
84 { 50, 1 },
e0b7d23c
ML
85};
86
f6a0ac9f 87static const uint64_t vdivs[][2] = {
e0b7d23c
ML
88 /* millivolts */
89 { 2, 1000 },
90 { 5, 1000 },
91 { 10, 1000 },
92 { 20, 1000 },
93 { 50, 1000 },
94 { 100, 1000 },
95 { 200, 1000 },
96 { 500, 1000 },
97 /* volts */
98 { 1, 1 },
99 { 2, 1 },
100 { 5, 1 },
101 { 10, 1 },
e0b7d23c
ML
102};
103
104static const char *trigger_sources[] = {
105 "CH1",
106 "CH2",
107 "EXT",
108 "AC Line",
6bb192bc
ML
109 "D0",
110 "D1",
111 "D2",
112 "D3",
113 "D4",
114 "D5",
115 "D6",
116 "D7",
117 "D8",
118 "D9",
119 "D10",
120 "D11",
121 "D12",
122 "D13",
123 "D14",
124 "D15",
e0b7d23c
ML
125};
126
127static const char *coupling[] = {
128 "AC",
129 "DC",
130 "GND",
e0b7d23c
ML
131};
132
512bb890
BV
133static const char *supported_models[] = {
134 "DS1052E",
135 "DS1102E",
136 "DS1052D",
333bf022 137 "DS1102D",
512bb890
BV
138};
139
f4816ac6
ML
140SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
141static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
142
fa85f376 143static void clear_helper(void *priv)
f4816ac6 144{
f4816ac6 145 struct dev_context *devc;
f4816ac6 146
fa85f376 147 devc = priv;
f4816ac6 148
fa85f376
UH
149 g_free(devc->coupling[0]);
150 g_free(devc->coupling[1]);
151 g_free(devc->trigger_source);
152 g_free(devc->trigger_slope);
153}
f4816ac6 154
3b412e3a 155static int dev_clear(void)
fa85f376
UH
156{
157 return std_dev_clear(di, clear_helper);
f4816ac6
ML
158}
159
254dd102
BV
160static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
161{
254dd102
BV
162 va_list args;
163 char buf[256];
164
254dd102
BV
165 va_start(args, format);
166 vsnprintf(buf, 255, format, args);
167 va_end(args);
9bd4c956 168 if (rigol_ds1xx2_send(sdi, buf) != SR_OK)
254dd102
BV
169 return SR_ERR;
170
171 /* When setting a bunch of parameters in a row, the DS1052E scrambles
172 * some of them unless there is at least 100ms delay in between. */
8f35be72 173 sr_spew("delay %dms", 100);
e31d410d 174 g_usleep(100000);
254dd102
BV
175
176 return SR_OK;
177}
178
6078d2c9 179static int init(struct sr_context *sr_ctx)
f4816ac6 180{
f6beaac5 181 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
182}
183
cc9fd2d2 184static int probe_port(const char *port, GSList **devices)
f4816ac6 185{
cc9fd2d2
BV
186 struct dev_context *devc;
187 struct sr_dev_inst *sdi;
9bd4c956 188 struct sr_serial_dev_inst *serial;
cc9fd2d2 189 struct sr_probe *probe;
f6a0ac9f 190 unsigned int i;
9bd4c956 191 int len, num_tokens;
cc9fd2d2 192 gboolean matched, has_digital;
512bb890 193 const char *manufacturer, *model, *version;
fb6e5ba8 194 char buf[256];
cc9fd2d2 195 gchar **tokens, *channel_name;
fb6e5ba8 196
46a743c1 197 *devices = NULL;
cc9fd2d2 198 if (!(serial = sr_serial_dev_inst_new(port, NULL)))
9bd4c956
ML
199 return SR_ERR_MALLOC;
200
201 if (serial_open(serial, SERIAL_RDWR) != SR_OK)
202 return SR_ERR;
cc9fd2d2 203 len = serial_write(serial, "*IDN?", 5);
9bd4c956
ML
204 len = serial_read(serial, buf, sizeof(buf));
205 if (serial_close(serial) != SR_OK)
206 return SR_ERR;
207
208 sr_serial_dev_inst_free(serial);
209
ca55277c
ML
210 if (len == 0)
211 return SR_ERR_NA;
f4816ac6 212
ca55277c 213 buf[len] = 0;
cc9fd2d2
BV
214 tokens = g_strsplit(buf, ",", 0);
215 sr_dbg("response: %s [%s]", port, buf);
4b97c74e 216
ca55277c 217 for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
e0b7d23c 218
ca55277c
ML
219 if (num_tokens < 4) {
220 g_strfreev(tokens);
221 return SR_ERR_NA;
222 }
e0b7d23c 223
ca55277c
ML
224 manufacturer = tokens[0];
225 model = tokens[1];
226 version = tokens[3];
fb6e5ba8 227
ca55277c
ML
228 if (strcmp(manufacturer, "Rigol Technologies")) {
229 g_strfreev(tokens);
230 return SR_ERR_NA;
231 }
fb6e5ba8 232
46a743c1 233 matched = has_digital = FALSE;
ca55277c
ML
234 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
235 if (!strcmp(model, supported_models[i])) {
cc9fd2d2 236 matched = TRUE;
ca55277c
ML
237 has_digital = g_str_has_suffix(model, "D");
238 break;
fb6e5ba8 239 }
ca55277c 240 }
fb6e5ba8 241
ca55277c
ML
242 if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
243 manufacturer, model, version))) {
244 g_strfreev(tokens);
245 return SR_ERR_NA;
246 }
fb6e5ba8 247
ca55277c 248 g_strfreev(tokens);
fb6e5ba8 249
cc9fd2d2 250 if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
ca55277c 251 return SR_ERR_MALLOC;
cc9fd2d2 252 sdi->driver = di;
fa85f376 253 sdi->inst_type = SR_INST_SERIAL;
512bb890 254
cc9fd2d2 255 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
ca55277c 256 return SR_ERR_MALLOC;
cc9fd2d2 257 devc->limit_frames = 0;
ca55277c 258 devc->has_digital = has_digital;
512bb890 259
ca55277c
ML
260 for (i = 0; i < 2; i++) {
261 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
262 i == 0 ? "CH1" : "CH2")))
263 return SR_ERR_MALLOC;
264 sdi->probes = g_slist_append(sdi->probes, probe);
265 }
512bb890 266
ca55277c
ML
267 if (devc->has_digital) {
268 for (i = 0; i < 16; i++) {
269 if (!(channel_name = g_strdup_printf("D%d", i)))
270 return SR_ERR_MALLOC;
271 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
272 g_free(channel_name);
273 if (!probe)
274 return SR_ERR_MALLOC;
275 sdi->probes = g_slist_append(sdi->probes, probe);
512bb890 276 }
ca55277c 277 }
cc9fd2d2
BV
278 sdi->priv = devc;
279
280 *devices = g_slist_append(NULL, sdi);
512bb890 281
ca55277c
ML
282 return SR_OK;
283}
512bb890 284
6078d2c9 285static GSList *scan(GSList *options)
ca55277c
ML
286{
287 struct drv_context *drvc;
ca55277c 288 struct sr_config *src;
cc9fd2d2 289 GSList *l, *devices;
ca55277c 290 GDir *dir;
ca55277c 291 int ret;
cc9fd2d2
BV
292 const gchar *dev_name;
293 gchar *port = NULL;
fb6e5ba8 294
ca55277c 295 drvc = di->priv;
d2e0b1fa 296
ca55277c
ML
297 for (l = options; l; l = l->next) {
298 src = l->data;
299 if (src->key == SR_CONF_CONN) {
cc9fd2d2 300 port = (char *)g_variant_get_string(src->data, NULL);
ca55277c 301 break;
fb6e5ba8 302 }
ca55277c 303 }
fb6e5ba8 304
46a743c1 305 devices = NULL;
cc9fd2d2
BV
306 if (port) {
307 if (probe_port(port, &devices) == SR_ERR_MALLOC)
ca55277c 308 return NULL;
ca55277c 309 } else {
da970d24
BV
310 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
311 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
312 return NULL;
ca55277c 313 while ((dev_name = g_dir_read_name(dir))) {
cc9fd2d2 314 if (strncmp(dev_name, "usbtmc", 6))
ca55277c 315 continue;
cc9fd2d2
BV
316 port = g_strconcat("/dev/", dev_name, NULL);
317 ret = probe_port(port, &devices);
318 g_free(port);
ca55277c
ML
319 if (ret == SR_ERR_MALLOC) {
320 g_dir_close(dir);
ca55277c 321 return NULL;
6bb192bc
ML
322 }
323 }
ca55277c
ML
324 g_dir_close(dir);
325 }
f4816ac6 326
46a743c1
BV
327 /* Tack a copy of the newly found devices onto the driver list. */
328 l = g_slist_copy(devices);
329 drvc->instances = g_slist_concat(drvc->instances, l);
cc9fd2d2 330
f4816ac6
ML
331 return devices;
332}
333
6078d2c9 334static GSList *dev_list(void)
f4816ac6 335{
0e94d524 336 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
337}
338
6078d2c9 339static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 340{
9bd4c956
ML
341
342 if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
e0b7d23c 343 return SR_ERR;
e0b7d23c 344
254dd102 345 if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
254dd102 346 return SR_ERR;
f4816ac6 347
46a743c1 348 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 349
f4816ac6
ML
350 return SR_OK;
351}
352
6078d2c9 353static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 354{
cc9fd2d2 355 struct sr_serial_dev_inst *serial;
e0b7d23c 356
cc9fd2d2
BV
357 serial = sdi->conn;
358 if (serial && serial->fd != -1) {
359 serial_close(serial);
360 sdi->status = SR_ST_INACTIVE;
361 }
f4816ac6
ML
362
363 return SR_OK;
364}
365
6078d2c9 366static int cleanup(void)
f4816ac6 367{
3b412e3a 368 return dev_clear();
f4816ac6
ML
369}
370
d62d7ad1
BV
371static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
372{
373
374 (void)sdi;
375
376 switch (id) {
377 case SR_CONF_NUM_TIMEBASE:
378 *data = g_variant_new_int32(NUM_TIMEBASE);
379 break;
380 case SR_CONF_NUM_VDIV:
381 *data = g_variant_new_int32(NUM_VDIV);
382 break;
383 default:
bd6fbf62 384 return SR_ERR_NA;
d62d7ad1
BV
385 }
386
387 return SR_OK;
388}
389
f6a0ac9f 390static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
f4816ac6 391{
29d957ce 392 struct dev_context *devc;
f6a0ac9f 393 uint64_t tmp_u64, p, q;
254dd102 394 double t_dbl;
f6a0ac9f 395 unsigned int i;
254dd102
BV
396 int ret;
397 const char *tmp_str;
f4816ac6 398
29d957ce
UH
399 devc = sdi->priv;
400
e73ffd42
BV
401 if (sdi->status != SR_ST_ACTIVE)
402 return SR_ERR_DEV_CLOSED;
f4816ac6
ML
403
404 ret = SR_OK;
035a1078 405 switch (id) {
1953564a 406 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 407 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 408 break;
1953564a 409 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 410 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
411 if (tmp_u64 != 0 && tmp_u64 != 1)
412 return SR_ERR;
413 g_free(devc->trigger_slope);
414 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
415 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 416 break;
1953564a 417 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
418 t_dbl = g_variant_get_double(data);
419 if (t_dbl < 0.0 || t_dbl > 1.0)
420 return SR_ERR;
421 devc->horiz_triggerpos = t_dbl;
422 /* We have the trigger offset as a percentage of the frame, but
423 * need to express this in seconds. */
424 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
425 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
e0b7d23c 426 break;
1953564a 427 case SR_CONF_TIMEBASE:
f6a0ac9f 428 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
429 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
430 if (timebases[i][0] == p && timebases[i][1] == q) {
254dd102
BV
431 devc->timebase = (float)p / q;
432 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
f6a0ac9f
BV
433 break;
434 }
435 }
254dd102
BV
436 if (i == ARRAY_SIZE(timebases))
437 ret = SR_ERR_ARG;
e0b7d23c 438 break;
1953564a 439 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 440 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
441 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
442 if (!strcmp(trigger_sources[i], tmp_str)) {
443 g_free(devc->trigger_source);
444 devc->trigger_source = g_strdup(trigger_sources[i]);
445 if (!strcmp(devc->trigger_source, "AC Line"))
446 tmp_str = "ACL";
447 else if (!strcmp(devc->trigger_source, "CH1"))
448 tmp_str = "CHAN1";
449 else if (!strcmp(devc->trigger_source, "CH2"))
450 tmp_str = "CHAN2";
451 else
452 tmp_str = (char *)devc->trigger_source;
453 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
454 break;
455 }
4e108ace 456 }
254dd102
BV
457 if (i == ARRAY_SIZE(trigger_sources))
458 ret = SR_ERR_ARG;
e0b7d23c 459 break;
1953564a 460 case SR_CONF_VDIV:
f6a0ac9f 461 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
462 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
463 if (vdivs[i][0] != p || vdivs[i][1] != q)
464 continue;
254dd102
BV
465 devc->vdiv[0] = devc->vdiv[1] = (float)p / q;
466 set_cfg(sdi, ":CHAN1:SCAL %.3f", devc->vdiv[0]);
467 ret = set_cfg(sdi, ":CHAN2:SCAL %.3f", devc->vdiv[1]);
f6a0ac9f 468 break;
e0b7d23c 469 }
f6a0ac9f 470 if (i == ARRAY_SIZE(vdivs))
e0b7d23c
ML
471 ret = SR_ERR_ARG;
472 break;
1953564a 473 case SR_CONF_COUPLING:
e0b7d23c 474 /* TODO: Not supporting coupling per channel yet. */
f6a0ac9f
BV
475 tmp_str = g_variant_get_string(data, NULL);
476 for (i = 0; i < ARRAY_SIZE(coupling); i++) {
477 if (!strcmp(tmp_str, coupling[i])) {
254dd102
BV
478 g_free(devc->coupling[0]);
479 g_free(devc->coupling[1]);
480 devc->coupling[0] = g_strdup(coupling[i]);
481 devc->coupling[1] = g_strdup(coupling[i]);
482 set_cfg(sdi, ":CHAN1:COUP %s", devc->coupling[0]);
483 ret = set_cfg(sdi, ":CHAN2:COUP %s", devc->coupling[1]);
e0b7d23c
ML
484 break;
485 }
486 }
f6a0ac9f 487 if (i == ARRAY_SIZE(coupling))
e0b7d23c
ML
488 ret = SR_ERR_ARG;
489 break;
f4816ac6 490 default:
bd6fbf62 491 ret = SR_ERR_NA;
29d957ce 492 break;
f4816ac6
ML
493 }
494
495 return ret;
496}
497
f6a0ac9f 498static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
a1c743fc 499{
861c447b
BV
500 GVariant *tuple, *rational[2];
501 GVariantBuilder gvb;
502 unsigned int i;
a7be14ad 503 struct dev_context *devc;
a1c743fc
BV
504
505 switch (key) {
ca55277c
ML
506 case SR_CONF_SCAN_OPTIONS:
507 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
508 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
509 break;
9a6517d1 510 case SR_CONF_DEVICE_OPTIONS:
f6a0ac9f
BV
511 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
512 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 513 break;
2a7b113d 514 case SR_CONF_COUPLING:
169dbe85
UH
515 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
516 break;
e4f2b2ad 517 case SR_CONF_VDIV:
861c447b
BV
518 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
519 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
520 rational[0] = g_variant_new_uint64(vdivs[i][0]);
521 rational[1] = g_variant_new_uint64(vdivs[i][1]);
522 tuple = g_variant_new_tuple(rational, 2);
523 g_variant_builder_add_value(&gvb, tuple);
524 }
525 *data = g_variant_builder_end(&gvb);
e4f2b2ad 526 break;
41f5bd09 527 case SR_CONF_TIMEBASE:
861c447b
BV
528 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
529 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
530 rational[0] = g_variant_new_uint64(timebases[i][0]);
531 rational[1] = g_variant_new_uint64(timebases[i][1]);
532 tuple = g_variant_new_tuple(rational, 2);
533 g_variant_builder_add_value(&gvb, tuple);
534 }
535 *data = g_variant_builder_end(&gvb);
41f5bd09 536 break;
328bafab 537 case SR_CONF_TRIGGER_SOURCE:
a7be14ad
BV
538 if (!sdi || !sdi->priv)
539 /* Can't know this until we have the exact model. */
540 return SR_ERR_ARG;
541 devc = sdi->priv;
f6a0ac9f 542 *data = g_variant_new_strv(trigger_sources,
6bb192bc 543 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 544 break;
a1c743fc 545 default:
bd6fbf62 546 return SR_ERR_NA;
a1c743fc
BV
547 }
548
549 return SR_OK;
550}
551
254dd102 552static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 553{
9bd4c956 554 struct sr_serial_dev_inst *serial;
29d957ce 555 struct dev_context *devc;
254dd102
BV
556 struct sr_probe *probe;
557 GSList *l;
254dd102 558 char cmd[256];
29d957ce 559
e73ffd42
BV
560 if (sdi->status != SR_ST_ACTIVE)
561 return SR_ERR_DEV_CLOSED;
e0b7d23c 562
9bd4c956 563 serial = sdi->conn;
29d957ce
UH
564 devc = sdi->priv;
565
254dd102
BV
566 for (l = sdi->probes; l; l = l->next) {
567 probe = l->data;
6bb192bc
ML
568 sr_dbg("handling probe %s", probe->name);
569 if (probe->type == SR_PROBE_ANALOG) {
570 if (probe->enabled)
571 devc->enabled_analog_probes = g_slist_append(
572 devc->enabled_analog_probes, probe);
573 if (probe->enabled != devc->analog_channels[probe->index]) {
574 /* Enabled channel is currently disabled, or vice versa. */
575 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
576 probe->enabled ? "ON" : "OFF");
9bd4c956 577 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
578 return SR_ERR;
579 }
580 } else if (probe->type == SR_PROBE_LOGIC) {
581 if (probe->enabled)
582 devc->enabled_digital_probes = g_slist_append(
583 devc->enabled_digital_probes, probe);
584 if (probe->enabled != devc->digital_channels[probe->index]) {
585 /* Enabled channel is currently disabled, or vice versa. */
586 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
587 probe->enabled ? "ON" : "OFF");
9bd4c956 588 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
589 return SR_ERR;
590 }
254dd102
BV
591 }
592 }
6bb192bc 593 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 594 return SR_ERR;
e0b7d23c 595
9bd4c956 596 sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
e0b7d23c
ML
597
598 /* Send header packet to the session bus. */
29a27196 599 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 600
254dd102 601 /* Fetch the first frame. */
6bb192bc
ML
602 if (devc->enabled_analog_probes) {
603 devc->channel_frame = devc->enabled_analog_probes->data;
9bd4c956 604 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
6bb192bc
ML
605 devc->channel_frame->index + 1) != SR_OK)
606 return SR_ERR;
607 } else {
608 devc->channel_frame = devc->enabled_digital_probes->data;
9bd4c956 609 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
6bb192bc
ML
610 return SR_ERR;
611 }
f4816ac6 612
ee7e9bee
ML
613 devc->num_frame_bytes = 0;
614
f4816ac6
ML
615 return SR_OK;
616}
617
254dd102 618static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 619{
29d957ce 620 struct dev_context *devc;
cc9fd2d2 621 struct sr_serial_dev_inst *serial;
29d957ce 622
f4816ac6
ML
623 (void)cb_data;
624
29d957ce
UH
625 devc = sdi->priv;
626
f4816ac6
ML
627 if (sdi->status != SR_ST_ACTIVE) {
628 sr_err("Device inactive, can't stop acquisition.");
629 return SR_ERR;
630 }
631
6bb192bc
ML
632 g_slist_free(devc->enabled_analog_probes);
633 g_slist_free(devc->enabled_digital_probes);
634 devc->enabled_analog_probes = NULL;
635 devc->enabled_digital_probes = NULL;
cc9fd2d2
BV
636 serial = sdi->conn;
637 sr_source_remove(serial->fd);
f4816ac6
ML
638
639 return SR_OK;
640}
641
642SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
643 .name = "rigol-ds1xx2",
644 .longname = "Rigol DS1xx2",
645 .api_version = 1,
6078d2c9
UH
646 .init = init,
647 .cleanup = cleanup,
648 .scan = scan,
649 .dev_list = dev_list,
3b412e3a 650 .dev_clear = dev_clear,
d62d7ad1 651 .config_get = config_get,
035a1078 652 .config_set = config_set,
a1c743fc 653 .config_list = config_list,
6078d2c9
UH
654 .dev_open = dev_open,
655 .dev_close = dev_close,
254dd102
BV
656 .dev_acquisition_start = dev_acquisition_start,
657 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
658 .priv = NULL,
659};