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