]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds1xx2/api.c
probe_groups: API changes required to implement probe groups.
[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
8f996b89
ML
373static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
374 const struct sr_probe_group *probe_group)
d62d7ad1
BV
375{
376
377 (void)sdi;
8f996b89 378 (void)probe_group;
d62d7ad1
BV
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
8f996b89
ML
394static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
395 const struct sr_probe_group *probe_group)
f4816ac6 396{
29d957ce 397 struct dev_context *devc;
f6a0ac9f 398 uint64_t tmp_u64, p, q;
254dd102 399 double t_dbl;
f6a0ac9f 400 unsigned int i;
254dd102
BV
401 int ret;
402 const char *tmp_str;
f4816ac6 403
8f996b89
ML
404 (void)probe_group;
405
29d957ce
UH
406 devc = sdi->priv;
407
e73ffd42
BV
408 if (sdi->status != SR_ST_ACTIVE)
409 return SR_ERR_DEV_CLOSED;
f4816ac6
ML
410
411 ret = SR_OK;
035a1078 412 switch (id) {
1953564a 413 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 414 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 415 break;
1953564a 416 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 417 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
418 if (tmp_u64 != 0 && tmp_u64 != 1)
419 return SR_ERR;
420 g_free(devc->trigger_slope);
421 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
422 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 423 break;
1953564a 424 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
425 t_dbl = g_variant_get_double(data);
426 if (t_dbl < 0.0 || t_dbl > 1.0)
427 return SR_ERR;
428 devc->horiz_triggerpos = t_dbl;
429 /* We have the trigger offset as a percentage of the frame, but
430 * need to express this in seconds. */
431 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
432 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
e0b7d23c 433 break;
1953564a 434 case SR_CONF_TIMEBASE:
f6a0ac9f 435 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
436 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
437 if (timebases[i][0] == p && timebases[i][1] == q) {
254dd102
BV
438 devc->timebase = (float)p / q;
439 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
f6a0ac9f
BV
440 break;
441 }
442 }
254dd102
BV
443 if (i == ARRAY_SIZE(timebases))
444 ret = SR_ERR_ARG;
e0b7d23c 445 break;
1953564a 446 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 447 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
448 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
449 if (!strcmp(trigger_sources[i], tmp_str)) {
450 g_free(devc->trigger_source);
451 devc->trigger_source = g_strdup(trigger_sources[i]);
452 if (!strcmp(devc->trigger_source, "AC Line"))
453 tmp_str = "ACL";
454 else if (!strcmp(devc->trigger_source, "CH1"))
455 tmp_str = "CHAN1";
456 else if (!strcmp(devc->trigger_source, "CH2"))
457 tmp_str = "CHAN2";
458 else
459 tmp_str = (char *)devc->trigger_source;
460 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
461 break;
462 }
4e108ace 463 }
254dd102
BV
464 if (i == ARRAY_SIZE(trigger_sources))
465 ret = SR_ERR_ARG;
e0b7d23c 466 break;
1953564a 467 case SR_CONF_VDIV:
f6a0ac9f 468 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
469 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
470 if (vdivs[i][0] != p || vdivs[i][1] != q)
471 continue;
254dd102
BV
472 devc->vdiv[0] = devc->vdiv[1] = (float)p / q;
473 set_cfg(sdi, ":CHAN1:SCAL %.3f", devc->vdiv[0]);
474 ret = set_cfg(sdi, ":CHAN2:SCAL %.3f", devc->vdiv[1]);
f6a0ac9f 475 break;
e0b7d23c 476 }
f6a0ac9f 477 if (i == ARRAY_SIZE(vdivs))
e0b7d23c
ML
478 ret = SR_ERR_ARG;
479 break;
1953564a 480 case SR_CONF_COUPLING:
e0b7d23c 481 /* TODO: Not supporting coupling per channel yet. */
f6a0ac9f
BV
482 tmp_str = g_variant_get_string(data, NULL);
483 for (i = 0; i < ARRAY_SIZE(coupling); i++) {
484 if (!strcmp(tmp_str, coupling[i])) {
254dd102
BV
485 g_free(devc->coupling[0]);
486 g_free(devc->coupling[1]);
487 devc->coupling[0] = g_strdup(coupling[i]);
488 devc->coupling[1] = g_strdup(coupling[i]);
489 set_cfg(sdi, ":CHAN1:COUP %s", devc->coupling[0]);
490 ret = set_cfg(sdi, ":CHAN2:COUP %s", devc->coupling[1]);
e0b7d23c
ML
491 break;
492 }
493 }
f6a0ac9f 494 if (i == ARRAY_SIZE(coupling))
e0b7d23c
ML
495 ret = SR_ERR_ARG;
496 break;
f4816ac6 497 default:
bd6fbf62 498 ret = SR_ERR_NA;
29d957ce 499 break;
f4816ac6
ML
500 }
501
502 return ret;
503}
504
8f996b89
ML
505static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
506 const struct sr_probe_group *probe_group)
a1c743fc 507{
861c447b
BV
508 GVariant *tuple, *rational[2];
509 GVariantBuilder gvb;
510 unsigned int i;
a7be14ad 511 struct dev_context *devc;
a1c743fc 512
8f996b89
ML
513 (void)probe_group;
514
a1c743fc 515 switch (key) {
ca55277c
ML
516 case SR_CONF_SCAN_OPTIONS:
517 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
518 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
519 break;
9a6517d1 520 case SR_CONF_DEVICE_OPTIONS:
f6a0ac9f
BV
521 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
522 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
9a6517d1 523 break;
2a7b113d 524 case SR_CONF_COUPLING:
169dbe85
UH
525 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
526 break;
e4f2b2ad 527 case SR_CONF_VDIV:
861c447b
BV
528 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
529 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
530 rational[0] = g_variant_new_uint64(vdivs[i][0]);
531 rational[1] = g_variant_new_uint64(vdivs[i][1]);
532 tuple = g_variant_new_tuple(rational, 2);
533 g_variant_builder_add_value(&gvb, tuple);
534 }
535 *data = g_variant_builder_end(&gvb);
e4f2b2ad 536 break;
41f5bd09 537 case SR_CONF_TIMEBASE:
861c447b
BV
538 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
539 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
540 rational[0] = g_variant_new_uint64(timebases[i][0]);
541 rational[1] = g_variant_new_uint64(timebases[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);
41f5bd09 546 break;
328bafab 547 case SR_CONF_TRIGGER_SOURCE:
a7be14ad
BV
548 if (!sdi || !sdi->priv)
549 /* Can't know this until we have the exact model. */
550 return SR_ERR_ARG;
551 devc = sdi->priv;
f6a0ac9f 552 *data = g_variant_new_strv(trigger_sources,
6bb192bc 553 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 554 break;
a1c743fc 555 default:
bd6fbf62 556 return SR_ERR_NA;
a1c743fc
BV
557 }
558
559 return SR_OK;
560}
561
254dd102 562static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 563{
9bd4c956 564 struct sr_serial_dev_inst *serial;
29d957ce 565 struct dev_context *devc;
254dd102
BV
566 struct sr_probe *probe;
567 GSList *l;
254dd102 568 char cmd[256];
29d957ce 569
e73ffd42
BV
570 if (sdi->status != SR_ST_ACTIVE)
571 return SR_ERR_DEV_CLOSED;
e0b7d23c 572
9bd4c956 573 serial = sdi->conn;
29d957ce
UH
574 devc = sdi->priv;
575
254dd102
BV
576 for (l = sdi->probes; l; l = l->next) {
577 probe = l->data;
6bb192bc
ML
578 sr_dbg("handling probe %s", probe->name);
579 if (probe->type == SR_PROBE_ANALOG) {
580 if (probe->enabled)
581 devc->enabled_analog_probes = g_slist_append(
582 devc->enabled_analog_probes, probe);
583 if (probe->enabled != devc->analog_channels[probe->index]) {
584 /* Enabled channel is currently disabled, or vice versa. */
585 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
586 probe->enabled ? "ON" : "OFF");
9bd4c956 587 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
588 return SR_ERR;
589 }
590 } else if (probe->type == SR_PROBE_LOGIC) {
591 if (probe->enabled)
592 devc->enabled_digital_probes = g_slist_append(
593 devc->enabled_digital_probes, probe);
594 if (probe->enabled != devc->digital_channels[probe->index]) {
595 /* Enabled channel is currently disabled, or vice versa. */
596 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
597 probe->enabled ? "ON" : "OFF");
9bd4c956 598 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
599 return SR_ERR;
600 }
254dd102
BV
601 }
602 }
6bb192bc 603 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 604 return SR_ERR;
e0b7d23c 605
9bd4c956 606 sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
e0b7d23c
ML
607
608 /* Send header packet to the session bus. */
29a27196 609 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 610
254dd102 611 /* Fetch the first frame. */
6bb192bc
ML
612 if (devc->enabled_analog_probes) {
613 devc->channel_frame = devc->enabled_analog_probes->data;
9bd4c956 614 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
6bb192bc
ML
615 devc->channel_frame->index + 1) != SR_OK)
616 return SR_ERR;
617 } else {
618 devc->channel_frame = devc->enabled_digital_probes->data;
9bd4c956 619 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
6bb192bc
ML
620 return SR_ERR;
621 }
f4816ac6 622
ee7e9bee
ML
623 devc->num_frame_bytes = 0;
624
f4816ac6
ML
625 return SR_OK;
626}
627
254dd102 628static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 629{
29d957ce 630 struct dev_context *devc;
cc9fd2d2 631 struct sr_serial_dev_inst *serial;
29d957ce 632
f4816ac6
ML
633 (void)cb_data;
634
29d957ce
UH
635 devc = sdi->priv;
636
f4816ac6
ML
637 if (sdi->status != SR_ST_ACTIVE) {
638 sr_err("Device inactive, can't stop acquisition.");
639 return SR_ERR;
640 }
641
6bb192bc
ML
642 g_slist_free(devc->enabled_analog_probes);
643 g_slist_free(devc->enabled_digital_probes);
644 devc->enabled_analog_probes = NULL;
645 devc->enabled_digital_probes = NULL;
cc9fd2d2
BV
646 serial = sdi->conn;
647 sr_source_remove(serial->fd);
f4816ac6
ML
648
649 return SR_OK;
650}
651
652SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
653 .name = "rigol-ds1xx2",
654 .longname = "Rigol DS1xx2",
655 .api_version = 1,
6078d2c9
UH
656 .init = init,
657 .cleanup = cleanup,
658 .scan = scan,
659 .dev_list = dev_list,
3b412e3a 660 .dev_clear = dev_clear,
d62d7ad1 661 .config_get = config_get,
035a1078 662 .config_set = config_set,
a1c743fc 663 .config_list = config_list,
6078d2c9
UH
664 .dev_open = dev_open,
665 .dev_close = dev_close,
254dd102
BV
666 .dev_acquisition_start = dev_acquisition_start,
667 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
668 .priv = NULL,
669};