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