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