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