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