]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds1xx2/api.c
s/clear_instances/dev_clear/.
[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
ML
309 } else {
310 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
311 return NULL;
312 while ((dev_name = g_dir_read_name(dir))) {
cc9fd2d2 313 if (strncmp(dev_name, "usbtmc", 6))
ca55277c 314 continue;
cc9fd2d2
BV
315 port = g_strconcat("/dev/", dev_name, NULL);
316 ret = probe_port(port, &devices);
317 g_free(port);
ca55277c
ML
318 if (ret == SR_ERR_MALLOC) {
319 g_dir_close(dir);
ca55277c 320 return NULL;
6bb192bc
ML
321 }
322 }
ca55277c
ML
323 g_dir_close(dir);
324 }
f4816ac6 325
46a743c1
BV
326 /* Tack a copy of the newly found devices onto the driver list. */
327 l = g_slist_copy(devices);
328 drvc->instances = g_slist_concat(drvc->instances, l);
cc9fd2d2 329
f4816ac6
ML
330 return devices;
331}
332
6078d2c9 333static GSList *dev_list(void)
f4816ac6 334{
0e94d524 335 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
336}
337
6078d2c9 338static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 339{
9bd4c956
ML
340
341 if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
e0b7d23c 342 return SR_ERR;
e0b7d23c 343
254dd102 344 if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
254dd102 345 return SR_ERR;
f4816ac6 346
46a743c1 347 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 348
f4816ac6
ML
349 return SR_OK;
350}
351
6078d2c9 352static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 353{
cc9fd2d2 354 struct sr_serial_dev_inst *serial;
e0b7d23c 355
cc9fd2d2
BV
356 serial = sdi->conn;
357 if (serial && serial->fd != -1) {
358 serial_close(serial);
359 sdi->status = SR_ST_INACTIVE;
360 }
f4816ac6
ML
361
362 return SR_OK;
363}
364
6078d2c9 365static int cleanup(void)
f4816ac6 366{
3b412e3a 367 return dev_clear();
f4816ac6
ML
368}
369
d62d7ad1
BV
370static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
371{
372
373 (void)sdi;
374
375 switch (id) {
376 case SR_CONF_NUM_TIMEBASE:
377 *data = g_variant_new_int32(NUM_TIMEBASE);
378 break;
379 case SR_CONF_NUM_VDIV:
380 *data = g_variant_new_int32(NUM_VDIV);
381 break;
382 default:
bd6fbf62 383 return SR_ERR_NA;
d62d7ad1
BV
384 }
385
386 return SR_OK;
387}
388
f6a0ac9f 389static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
f4816ac6 390{
29d957ce 391 struct dev_context *devc;
f6a0ac9f 392 uint64_t tmp_u64, p, q;
254dd102 393 double t_dbl;
f6a0ac9f 394 unsigned int i;
254dd102
BV
395 int ret;
396 const char *tmp_str;
f4816ac6 397
29d957ce
UH
398 devc = sdi->priv;
399
e73ffd42
BV
400 if (sdi->status != SR_ST_ACTIVE)
401 return SR_ERR_DEV_CLOSED;
f4816ac6
ML
402
403 ret = SR_OK;
035a1078 404 switch (id) {
1953564a 405 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 406 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 407 break;
1953564a 408 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 409 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
410 if (tmp_u64 != 0 && tmp_u64 != 1)
411 return SR_ERR;
412 g_free(devc->trigger_slope);
413 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
414 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 415 break;
1953564a 416 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
417 t_dbl = g_variant_get_double(data);
418 if (t_dbl < 0.0 || t_dbl > 1.0)
419 return SR_ERR;
420 devc->horiz_triggerpos = t_dbl;
421 /* We have the trigger offset as a percentage of the frame, but
422 * need to express this in seconds. */
423 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
424 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
e0b7d23c 425 break;
1953564a 426 case SR_CONF_TIMEBASE:
f6a0ac9f 427 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
428 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
429 if (timebases[i][0] == p && timebases[i][1] == q) {
254dd102
BV
430 devc->timebase = (float)p / q;
431 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
f6a0ac9f
BV
432 break;
433 }
434 }
254dd102
BV
435 if (i == ARRAY_SIZE(timebases))
436 ret = SR_ERR_ARG;
e0b7d23c 437 break;
1953564a 438 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 439 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
440 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
441 if (!strcmp(trigger_sources[i], tmp_str)) {
442 g_free(devc->trigger_source);
443 devc->trigger_source = g_strdup(trigger_sources[i]);
444 if (!strcmp(devc->trigger_source, "AC Line"))
445 tmp_str = "ACL";
446 else if (!strcmp(devc->trigger_source, "CH1"))
447 tmp_str = "CHAN1";
448 else if (!strcmp(devc->trigger_source, "CH2"))
449 tmp_str = "CHAN2";
450 else
451 tmp_str = (char *)devc->trigger_source;
452 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
453 break;
454 }
4e108ace 455 }
254dd102
BV
456 if (i == ARRAY_SIZE(trigger_sources))
457 ret = SR_ERR_ARG;
e0b7d23c 458 break;
1953564a 459 case SR_CONF_VDIV:
f6a0ac9f 460 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
461 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
462 if (vdivs[i][0] != p || vdivs[i][1] != q)
463 continue;
254dd102
BV
464 devc->vdiv[0] = devc->vdiv[1] = (float)p / q;
465 set_cfg(sdi, ":CHAN1:SCAL %.3f", devc->vdiv[0]);
466 ret = set_cfg(sdi, ":CHAN2:SCAL %.3f", devc->vdiv[1]);
f6a0ac9f 467 break;
e0b7d23c 468 }
f6a0ac9f 469 if (i == ARRAY_SIZE(vdivs))
e0b7d23c
ML
470 ret = SR_ERR_ARG;
471 break;
1953564a 472 case SR_CONF_COUPLING:
e0b7d23c 473 /* TODO: Not supporting coupling per channel yet. */
f6a0ac9f
BV
474 tmp_str = g_variant_get_string(data, NULL);
475 for (i = 0; i < ARRAY_SIZE(coupling); i++) {
476 if (!strcmp(tmp_str, coupling[i])) {
254dd102
BV
477 g_free(devc->coupling[0]);
478 g_free(devc->coupling[1]);
479 devc->coupling[0] = g_strdup(coupling[i]);
480 devc->coupling[1] = g_strdup(coupling[i]);
481 set_cfg(sdi, ":CHAN1:COUP %s", devc->coupling[0]);
482 ret = set_cfg(sdi, ":CHAN2:COUP %s", devc->coupling[1]);
e0b7d23c
ML
483 break;
484 }
485 }
f6a0ac9f 486 if (i == ARRAY_SIZE(coupling))
e0b7d23c
ML
487 ret = SR_ERR_ARG;
488 break;
f4816ac6 489 default:
bd6fbf62 490 ret = SR_ERR_NA;
29d957ce 491 break;
f4816ac6
ML
492 }
493
494 return ret;
495}
496
f6a0ac9f 497static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
a1c743fc 498{
861c447b
BV
499 GVariant *tuple, *rational[2];
500 GVariantBuilder gvb;
501 unsigned int i;
a7be14ad 502 struct dev_context *devc;
a1c743fc
BV
503
504 switch (key) {
ca55277c
ML
505 case SR_CONF_SCAN_OPTIONS:
506 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
507 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
508 break;
9a6517d1 509 case SR_CONF_DEVICE_OPTIONS:
f6a0ac9f
BV
510 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
511 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 512 break;
2a7b113d 513 case SR_CONF_COUPLING:
169dbe85
UH
514 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
515 break;
e4f2b2ad 516 case SR_CONF_VDIV:
861c447b
BV
517 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
518 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
519 rational[0] = g_variant_new_uint64(vdivs[i][0]);
520 rational[1] = g_variant_new_uint64(vdivs[i][1]);
521 tuple = g_variant_new_tuple(rational, 2);
522 g_variant_builder_add_value(&gvb, tuple);
523 }
524 *data = g_variant_builder_end(&gvb);
e4f2b2ad 525 break;
41f5bd09 526 case SR_CONF_TIMEBASE:
861c447b
BV
527 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
528 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
529 rational[0] = g_variant_new_uint64(timebases[i][0]);
530 rational[1] = g_variant_new_uint64(timebases[i][1]);
531 tuple = g_variant_new_tuple(rational, 2);
532 g_variant_builder_add_value(&gvb, tuple);
533 }
534 *data = g_variant_builder_end(&gvb);
41f5bd09 535 break;
328bafab 536 case SR_CONF_TRIGGER_SOURCE:
a7be14ad
BV
537 if (!sdi || !sdi->priv)
538 /* Can't know this until we have the exact model. */
539 return SR_ERR_ARG;
540 devc = sdi->priv;
f6a0ac9f 541 *data = g_variant_new_strv(trigger_sources,
6bb192bc 542 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 543 break;
a1c743fc 544 default:
bd6fbf62 545 return SR_ERR_NA;
a1c743fc
BV
546 }
547
548 return SR_OK;
549}
550
254dd102 551static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 552{
9bd4c956 553 struct sr_serial_dev_inst *serial;
29d957ce 554 struct dev_context *devc;
254dd102
BV
555 struct sr_probe *probe;
556 GSList *l;
254dd102 557 char cmd[256];
29d957ce 558
e73ffd42
BV
559 if (sdi->status != SR_ST_ACTIVE)
560 return SR_ERR_DEV_CLOSED;
e0b7d23c 561
9bd4c956 562 serial = sdi->conn;
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");
9bd4c956 576 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
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");
9bd4c956 587 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
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
9bd4c956 595 sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
e0b7d23c
ML
596
597 /* Send header packet to the session bus. */
29a27196 598 std_session_send_df_header(cb_data, LOG_PREFIX);
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;
9bd4c956 603 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
6bb192bc
ML
604 devc->channel_frame->index + 1) != SR_OK)
605 return SR_ERR;
606 } else {
607 devc->channel_frame = devc->enabled_digital_probes->data;
9bd4c956 608 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
6bb192bc
ML
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 619 struct dev_context *devc;
cc9fd2d2 620 struct sr_serial_dev_inst *serial;
29d957ce 621
f4816ac6
ML
622 (void)cb_data;
623
29d957ce
UH
624 devc = sdi->priv;
625
f4816ac6
ML
626 if (sdi->status != SR_ST_ACTIVE) {
627 sr_err("Device inactive, can't stop acquisition.");
628 return SR_ERR;
629 }
630
6bb192bc
ML
631 g_slist_free(devc->enabled_analog_probes);
632 g_slist_free(devc->enabled_digital_probes);
633 devc->enabled_analog_probes = NULL;
634 devc->enabled_digital_probes = NULL;
cc9fd2d2
BV
635 serial = sdi->conn;
636 sr_source_remove(serial->fd);
f4816ac6
ML
637
638 return SR_OK;
639}
640
641SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
642 .name = "rigol-ds1xx2",
643 .longname = "Rigol DS1xx2",
644 .api_version = 1,
6078d2c9
UH
645 .init = init,
646 .cleanup = cleanup,
647 .scan = scan,
648 .dev_list = dev_list,
3b412e3a 649 .dev_clear = dev_clear,
d62d7ad1 650 .config_get = config_get,
035a1078 651 .config_set = config_set,
a1c743fc 652 .config_list = config_list,
6078d2c9
UH
653 .dev_open = dev_open,
654 .dev_close = dev_close,
254dd102
BV
655 .dev_acquisition_start = dev_acquisition_start,
656 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
657 .priv = NULL,
658};