]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds1xx2/api.c
mic-985xx: Use sr_dev_inst to store connection handle.
[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
f6a0ac9f 33static const int32_t hwcaps[] = {
1953564a 34 SR_CONF_OSCILLOSCOPE,
1953564a
BV
35 SR_CONF_TIMEBASE,
36 SR_CONF_TRIGGER_SOURCE,
37 SR_CONF_TRIGGER_SLOPE,
38 SR_CONF_HORIZ_TRIGGERPOS,
39 SR_CONF_VDIV,
40 SR_CONF_COUPLING,
d62d7ad1
BV
41 SR_CONF_NUM_TIMEBASE,
42 SR_CONF_NUM_VDIV,
e0b7d23c
ML
43};
44
f6a0ac9f 45static const uint64_t timebases[][2] = {
e0b7d23c
ML
46 /* nanoseconds */
47 { 2, 1000000000 },
48 { 5, 1000000000 },
49 { 10, 1000000000 },
50 { 20, 1000000000 },
51 { 50, 1000000000 },
52 { 100, 1000000000 },
53 { 500, 1000000000 },
54 /* microseconds */
55 { 1, 1000000 },
56 { 2, 1000000 },
57 { 5, 1000000 },
58 { 10, 1000000 },
59 { 20, 1000000 },
60 { 50, 1000000 },
61 { 100, 1000000 },
62 { 200, 1000000 },
63 { 500, 1000000 },
64 /* milliseconds */
65 { 1, 1000 },
66 { 2, 1000 },
67 { 5, 1000 },
68 { 10, 1000 },
69 { 20, 1000 },
70 { 50, 1000 },
71 { 100, 1000 },
72 { 200, 1000 },
73 { 500, 1000 },
74 /* seconds */
75 { 1, 1 },
76 { 2, 1 },
77 { 5, 1 },
78 { 10, 1 },
79 { 20, 1 },
80 { 50, 1 },
e0b7d23c
ML
81};
82
f6a0ac9f 83static const uint64_t vdivs[][2] = {
e0b7d23c
ML
84 /* millivolts */
85 { 2, 1000 },
86 { 5, 1000 },
87 { 10, 1000 },
88 { 20, 1000 },
89 { 50, 1000 },
90 { 100, 1000 },
91 { 200, 1000 },
92 { 500, 1000 },
93 /* volts */
94 { 1, 1 },
95 { 2, 1 },
96 { 5, 1 },
97 { 10, 1 },
e0b7d23c
ML
98};
99
100static const char *trigger_sources[] = {
101 "CH1",
102 "CH2",
103 "EXT",
104 "AC Line",
6bb192bc
ML
105 "D0",
106 "D1",
107 "D2",
108 "D3",
109 "D4",
110 "D5",
111 "D6",
112 "D7",
113 "D8",
114 "D9",
115 "D10",
116 "D11",
117 "D12",
118 "D13",
119 "D14",
120 "D15",
e0b7d23c
ML
121};
122
123static const char *coupling[] = {
124 "AC",
125 "DC",
126 "GND",
e0b7d23c
ML
127};
128
512bb890
BV
129static const char *supported_models[] = {
130 "DS1052E",
131 "DS1102E",
132 "DS1052D",
333bf022 133 "DS1102D",
512bb890
BV
134};
135
f4816ac6
ML
136SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
137static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
138
139/* Properly close and free all devices. */
140static int clear_instances(void)
141{
142 struct sr_dev_inst *sdi;
143 struct drv_context *drvc;
144 struct dev_context *devc;
145 GSList *l;
146
147 if (!(drvc = di->priv))
148 return SR_OK;
149
150 for (l = drvc->instances; l; l = l->next) {
151 if (!(sdi = l->data))
152 continue;
153 if (!(devc = sdi->priv))
154 continue;
155
fb6e5ba8 156 g_free(devc->device);
254dd102
BV
157 g_free(devc->coupling[0]);
158 g_free(devc->coupling[1]);
159 g_free(devc->trigger_source);
160 g_free(devc->trigger_slope);
e0b7d23c 161 close(devc->fd);
f4816ac6
ML
162
163 sr_dev_inst_free(sdi);
164 }
165
166 g_slist_free(drvc->instances);
167 drvc->instances = NULL;
168
169 return SR_OK;
170}
171
254dd102
BV
172static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
173{
174 struct dev_context *devc;
254dd102
BV
175 va_list args;
176 char buf[256];
177
178 devc = sdi->priv;
179
180 va_start(args, format);
181 vsnprintf(buf, 255, format, args);
182 va_end(args);
183 if (rigol_ds1xx2_send(devc, buf) != SR_OK)
184 return SR_ERR;
185
186 /* When setting a bunch of parameters in a row, the DS1052E scrambles
187 * some of them unless there is at least 100ms delay in between. */
8f35be72 188 sr_spew("delay %dms", 100);
e31d410d 189 g_usleep(100000);
254dd102
BV
190
191 return SR_OK;
192}
193
e0b7d23c 194static int hw_init(struct sr_context *sr_ctx)
f4816ac6 195{
063e7aef 196 return std_hw_init(sr_ctx, di, DRIVER_LOG_DOMAIN);
f4816ac6
ML
197}
198
199static GSList *hw_scan(GSList *options)
200{
201 struct drv_context *drvc;
e0b7d23c
ML
202 struct sr_dev_inst *sdi;
203 struct dev_context *devc;
204 struct sr_probe *probe;
f4816ac6 205 GSList *devices;
fb6e5ba8
ML
206 GDir *dir;
207 const gchar *dev_name;
208 const gchar *dev_dir = "/dev/";
209 const gchar *prefix = "usbtmc";
210 gchar *device;
211 const gchar *idn_query = "*IDN?";
f6a0ac9f
BV
212 unsigned int i;
213 int len, num_tokens, fd;
fb6e5ba8
ML
214 const gchar *delimiter = ",";
215 gchar **tokens;
512bb890 216 const char *manufacturer, *model, *version;
512bb890 217 gboolean matched = FALSE;
6bb192bc 218 gboolean has_digital = FALSE;
fb6e5ba8 219 char buf[256];
6bb192bc 220 gchar *channel_name;
fb6e5ba8 221
f4816ac6
ML
222 (void)options;
223
f4816ac6
ML
224 drvc = di->priv;
225 drvc->instances = NULL;
226
4b97c74e
UH
227 devices = NULL;
228
fb6e5ba8 229 dir = g_dir_open("/sys/class/usb/", 0, NULL);
e0b7d23c 230
fb6e5ba8
ML
231 if (dir == NULL)
232 return NULL;
e0b7d23c 233
29d957ce 234 while ((dev_name = g_dir_read_name(dir)) != NULL) {
fb6e5ba8
ML
235 if (strncmp(dev_name, prefix, strlen(prefix)))
236 continue;
237
238 device = g_strconcat(dev_dir, dev_name, NULL);
239
240 fd = open(device, O_RDWR);
241 len = write(fd, idn_query, strlen(idn_query));
242 len = read(fd, buf, sizeof(buf));
243 close(fd);
29d957ce 244 if (len == 0) {
fb6e5ba8 245 g_free(device);
d2e0b1fa 246 continue;
fb6e5ba8
ML
247 }
248
249 buf[len] = 0;
250 tokens = g_strsplit(buf, delimiter, 0);
251 close(fd);
512bb890 252 sr_dbg("response: %s %d [%s]", device, len, buf);
fb6e5ba8
ML
253
254 for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
255
512bb890 256 if (num_tokens < 4) {
fb6e5ba8
ML
257 g_strfreev(tokens);
258 g_free(device);
d2e0b1fa 259 continue;
fb6e5ba8 260 }
512bb890
BV
261
262 manufacturer = tokens[0];
263 model = tokens[1];
264 version = tokens[3];
265
266 if (strcmp(manufacturer, "Rigol Technologies")) {
267 g_strfreev(tokens);
268 g_free(device);
d2e0b1fa 269 continue;
512bb890
BV
270 }
271
333bf022 272 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
512bb890
BV
273 if (!strcmp(model, supported_models[i])) {
274 matched = 1;
6bb192bc 275 has_digital = g_str_has_suffix(model, "D");
512bb890
BV
276 break;
277 }
278 }
279
280 if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
281 manufacturer, model, version))) {
282 g_strfreev(tokens);
283 g_free(device);
d2e0b1fa 284 continue;
512bb890
BV
285 }
286
fb6e5ba8
ML
287 g_strfreev(tokens);
288
29d957ce
UH
289 if (!(devc = g_try_malloc0(sizeof(struct dev_context)))) {
290 sr_err("Device context malloc failed.");
fb6e5ba8 291 g_free(device);
d2e0b1fa 292 goto hw_scan_abort;
fb6e5ba8 293 }
d2e0b1fa 294
254dd102 295 devc->limit_frames = 0;
fb6e5ba8 296 devc->device = device;
6bb192bc 297 devc->has_digital = has_digital;
fb6e5ba8
ML
298 sdi->priv = devc;
299 sdi->driver = di;
d2e0b1fa
ML
300 drvc->instances = g_slist_append(drvc->instances, sdi);
301 devices = g_slist_append(devices, sdi);
fb6e5ba8 302
29d957ce 303 for (i = 0; i < 2; i++) {
6bb192bc 304 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
d2e0b1fa
ML
305 i == 0 ? "CH1" : "CH2")))
306 goto hw_scan_abort;
fb6e5ba8
ML
307 sdi->probes = g_slist_append(sdi->probes, probe);
308 }
309
6bb192bc
ML
310 if (devc->has_digital) {
311 for (i = 0; i < 16; i++) {
312 if (!(channel_name = g_strdup_printf("D%d", i)))
d2e0b1fa 313 goto hw_scan_abort;
6bb192bc
ML
314 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
315 g_free(channel_name);
316 if (!probe)
d2e0b1fa 317 goto hw_scan_abort;
6bb192bc
ML
318 sdi->probes = g_slist_append(sdi->probes, probe);
319 }
320 }
e0b7d23c 321 }
fb6e5ba8
ML
322
323 g_dir_close(dir);
f4816ac6
ML
324
325 return devices;
d2e0b1fa
ML
326
327hw_scan_abort:
328 g_dir_close(dir);
329 g_slist_free(devices);
330 clear_instances();
331 return NULL;
f4816ac6
ML
332}
333
334static GSList *hw_dev_list(void)
335{
0e94d524 336 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
337}
338
339static int hw_dev_open(struct sr_dev_inst *sdi)
340{
29d957ce
UH
341 struct dev_context *devc;
342 int fd;
fb6e5ba8 343
29d957ce 344 devc = sdi->priv;
e0b7d23c 345
29d957ce 346 if ((fd = open(devc->device, O_RDWR)) == -1)
e0b7d23c 347 return SR_ERR;
e0b7d23c
ML
348 devc->fd = fd;
349
254dd102
BV
350 if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
351 /* TODO: force configuration? */
352 return SR_ERR;
f4816ac6
ML
353
354 return SR_OK;
355}
356
357static int hw_dev_close(struct sr_dev_inst *sdi)
358{
29d957ce
UH
359 struct dev_context *devc;
360
361 devc = sdi->priv;
e0b7d23c
ML
362
363 close(devc->fd);
f4816ac6
ML
364
365 return SR_OK;
366}
367
368static int hw_cleanup(void)
369{
370 clear_instances();
371
f4816ac6
ML
372 return SR_OK;
373}
374
d62d7ad1
BV
375static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
376{
377
378 (void)sdi;
379
380 switch (id) {
381 case SR_CONF_NUM_TIMEBASE:
382 *data = g_variant_new_int32(NUM_TIMEBASE);
383 break;
384 case SR_CONF_NUM_VDIV:
385 *data = g_variant_new_int32(NUM_VDIV);
386 break;
387 default:
bd6fbf62 388 return SR_ERR_NA;
d62d7ad1
BV
389 }
390
391 return SR_OK;
392}
393
f6a0ac9f 394static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
f4816ac6 395{
29d957ce 396 struct dev_context *devc;
f6a0ac9f 397 uint64_t tmp_u64, p, q;
254dd102 398 double t_dbl;
f6a0ac9f 399 unsigned int i;
254dd102
BV
400 int ret;
401 const char *tmp_str;
f4816ac6 402
29d957ce
UH
403 devc = sdi->priv;
404
f4816ac6
ML
405 if (sdi->status != SR_ST_ACTIVE) {
406 sr_err("Device inactive, can't set config options.");
407 return SR_ERR;
408 }
409
410 ret = SR_OK;
035a1078 411 switch (id) {
1953564a 412 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 413 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 414 break;
1953564a 415 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 416 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
417 if (tmp_u64 != 0 && tmp_u64 != 1)
418 return SR_ERR;
419 g_free(devc->trigger_slope);
420 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
421 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 422 break;
1953564a 423 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
424 t_dbl = g_variant_get_double(data);
425 if (t_dbl < 0.0 || t_dbl > 1.0)
426 return SR_ERR;
427 devc->horiz_triggerpos = t_dbl;
428 /* We have the trigger offset as a percentage of the frame, but
429 * need to express this in seconds. */
430 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
431 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
e0b7d23c 432 break;
1953564a 433 case SR_CONF_TIMEBASE:
f6a0ac9f 434 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
435 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
436 if (timebases[i][0] == p && timebases[i][1] == q) {
254dd102
BV
437 devc->timebase = (float)p / q;
438 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
f6a0ac9f
BV
439 break;
440 }
441 }
254dd102
BV
442 if (i == ARRAY_SIZE(timebases))
443 ret = SR_ERR_ARG;
e0b7d23c 444 break;
1953564a 445 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 446 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
447 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
448 if (!strcmp(trigger_sources[i], tmp_str)) {
449 g_free(devc->trigger_source);
450 devc->trigger_source = g_strdup(trigger_sources[i]);
451 if (!strcmp(devc->trigger_source, "AC Line"))
452 tmp_str = "ACL";
453 else if (!strcmp(devc->trigger_source, "CH1"))
454 tmp_str = "CHAN1";
455 else if (!strcmp(devc->trigger_source, "CH2"))
456 tmp_str = "CHAN2";
457 else
458 tmp_str = (char *)devc->trigger_source;
459 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
460 break;
461 }
4e108ace 462 }
254dd102
BV
463 if (i == ARRAY_SIZE(trigger_sources))
464 ret = SR_ERR_ARG;
e0b7d23c 465 break;
1953564a 466 case SR_CONF_VDIV:
f6a0ac9f 467 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
468 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
469 if (vdivs[i][0] != p || vdivs[i][1] != q)
470 continue;
254dd102
BV
471 devc->vdiv[0] = devc->vdiv[1] = (float)p / q;
472 set_cfg(sdi, ":CHAN1:SCAL %.3f", devc->vdiv[0]);
473 ret = set_cfg(sdi, ":CHAN2:SCAL %.3f", devc->vdiv[1]);
f6a0ac9f 474 break;
e0b7d23c 475 }
f6a0ac9f 476 if (i == ARRAY_SIZE(vdivs))
e0b7d23c
ML
477 ret = SR_ERR_ARG;
478 break;
1953564a 479 case SR_CONF_COUPLING:
e0b7d23c 480 /* TODO: Not supporting coupling per channel yet. */
f6a0ac9f
BV
481 tmp_str = g_variant_get_string(data, NULL);
482 for (i = 0; i < ARRAY_SIZE(coupling); i++) {
483 if (!strcmp(tmp_str, coupling[i])) {
254dd102
BV
484 g_free(devc->coupling[0]);
485 g_free(devc->coupling[1]);
486 devc->coupling[0] = g_strdup(coupling[i]);
487 devc->coupling[1] = g_strdup(coupling[i]);
488 set_cfg(sdi, ":CHAN1:COUP %s", devc->coupling[0]);
489 ret = set_cfg(sdi, ":CHAN2:COUP %s", devc->coupling[1]);
e0b7d23c
ML
490 break;
491 }
492 }
f6a0ac9f 493 if (i == ARRAY_SIZE(coupling))
e0b7d23c
ML
494 ret = SR_ERR_ARG;
495 break;
f4816ac6 496 default:
bd6fbf62 497 ret = SR_ERR_NA;
29d957ce 498 break;
f4816ac6
ML
499 }
500
501 return ret;
502}
503
f6a0ac9f 504static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
a1c743fc 505{
861c447b
BV
506 GVariant *tuple, *rational[2];
507 GVariantBuilder gvb;
508 unsigned int i;
a7be14ad 509 struct dev_context *devc;
a1c743fc
BV
510
511 switch (key) {
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{
29d957ce 556 struct dev_context *devc;
254dd102
BV
557 struct sr_probe *probe;
558 GSList *l;
254dd102 559 char cmd[256];
29d957ce 560
e0b7d23c
ML
561 (void)cb_data;
562
29d957ce
UH
563 devc = sdi->priv;
564
254dd102
BV
565 for (l = sdi->probes; l; l = l->next) {
566 probe = l->data;
6bb192bc
ML
567 sr_dbg("handling probe %s", probe->name);
568 if (probe->type == SR_PROBE_ANALOG) {
569 if (probe->enabled)
570 devc->enabled_analog_probes = g_slist_append(
571 devc->enabled_analog_probes, probe);
572 if (probe->enabled != devc->analog_channels[probe->index]) {
573 /* Enabled channel is currently disabled, or vice versa. */
574 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
575 probe->enabled ? "ON" : "OFF");
576 if (rigol_ds1xx2_send(devc, cmd) != SR_OK)
577 return SR_ERR;
578 }
579 } else if (probe->type == SR_PROBE_LOGIC) {
580 if (probe->enabled)
581 devc->enabled_digital_probes = g_slist_append(
582 devc->enabled_digital_probes, probe);
583 if (probe->enabled != devc->digital_channels[probe->index]) {
584 /* Enabled channel is currently disabled, or vice versa. */
585 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
586 probe->enabled ? "ON" : "OFF");
587 if (rigol_ds1xx2_send(devc, cmd) != SR_OK)
588 return SR_ERR;
589 }
254dd102
BV
590 }
591 }
6bb192bc 592 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 593 return SR_ERR;
e0b7d23c 594
254dd102 595 sr_source_add(devc->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
e0b7d23c
ML
596
597 /* Send header packet to the session bus. */
4afdfd46 598 std_session_send_df_header(cb_data, DRIVER_LOG_DOMAIN);
e0b7d23c 599
254dd102 600 /* Fetch the first frame. */
6bb192bc
ML
601 if (devc->enabled_analog_probes) {
602 devc->channel_frame = devc->enabled_analog_probes->data;
603 if (rigol_ds1xx2_send(devc, ":WAV:DATA? CHAN%d",
604 devc->channel_frame->index + 1) != SR_OK)
605 return SR_ERR;
606 } else {
607 devc->channel_frame = devc->enabled_digital_probes->data;
608 if (rigol_ds1xx2_send(devc, ":WAV:DATA? DIG") != SR_OK)
609 return SR_ERR;
610 }
f4816ac6 611
ee7e9bee
ML
612 devc->num_frame_bytes = 0;
613
f4816ac6
ML
614 return SR_OK;
615}
616
254dd102 617static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 618{
29d957ce
UH
619 struct dev_context *devc;
620
f4816ac6
ML
621 (void)cb_data;
622
29d957ce
UH
623 devc = sdi->priv;
624
f4816ac6
ML
625 if (sdi->status != SR_ST_ACTIVE) {
626 sr_err("Device inactive, can't stop acquisition.");
627 return SR_ERR;
628 }
629
6bb192bc
ML
630 g_slist_free(devc->enabled_analog_probes);
631 g_slist_free(devc->enabled_digital_probes);
632 devc->enabled_analog_probes = NULL;
633 devc->enabled_digital_probes = NULL;
e0b7d23c 634 sr_source_remove(devc->fd);
f4816ac6
ML
635
636 return SR_OK;
637}
638
639SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
640 .name = "rigol-ds1xx2",
641 .longname = "Rigol DS1xx2",
642 .api_version = 1,
643 .init = hw_init,
644 .cleanup = hw_cleanup,
645 .scan = hw_scan,
646 .dev_list = hw_dev_list,
647 .dev_clear = clear_instances,
d62d7ad1 648 .config_get = config_get,
035a1078 649 .config_set = config_set,
a1c743fc 650 .config_list = config_list,
f4816ac6
ML
651 .dev_open = hw_dev_open,
652 .dev_close = hw_dev_close,
254dd102
BV
653 .dev_acquisition_start = dev_acquisition_start,
654 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
655 .priv = NULL,
656};