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