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