]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds1xx2/api.c
rigol-ds1xx2: Minor coding style fixes
[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 48 SR_CONF_VDIV,
78bcc55a 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 489 for (i = 0; i < 2; i++) {
78bcc55a
BV
490 if (probe_group == &devc->analog_groups[i]) {
491 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
492 if (vdivs[j][0] != p || vdivs[j][1] != q)
493 continue;
494 devc->vdiv[i] = (float)p / q;
495 return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
496 devc->vdiv[i]);
497 }
498 return SR_ERR_ARG;
499 }
e0b7d23c 500 }
f48e0249 501 return SR_ERR_NA;
1953564a 502 case SR_CONF_COUPLING:
78bcc55a
BV
503 if (!probe_group) {
504 sr_err("No probe group specified.");
505 return SR_ERR_PROBE_GROUP;
506 }
f6a0ac9f 507 tmp_str = g_variant_get_string(data, NULL);
f48e0249 508 for (i = 0; i < 2; i++) {
78bcc55a
BV
509 if (probe_group == &devc->analog_groups[i]) {
510 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
511 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
512 g_free(devc->coupling[i]);
513 devc->coupling[i] = g_strdup(coupling[j]);
514 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
515 devc->coupling[i]);
516 }
517 }
518 return SR_ERR_ARG;
e0b7d23c
ML
519 }
520 }
f48e0249 521 return SR_ERR_NA;
f4816ac6 522 default:
bd6fbf62 523 ret = SR_ERR_NA;
29d957ce 524 break;
f4816ac6
ML
525 }
526
527 return ret;
528}
529
8f996b89
ML
530static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
531 const struct sr_probe_group *probe_group)
a1c743fc 532{
861c447b
BV
533 GVariant *tuple, *rational[2];
534 GVariantBuilder gvb;
535 unsigned int i;
e43fdd8d 536 struct dev_context *devc;
8f996b89 537
e43fdd8d 538 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
539 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
540 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
541 return SR_OK;
542 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
543 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
544 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
545 return SR_OK;
546 }
547
548 /* Every other option requires a valid device instance. */
549 if (!sdi || !(devc = sdi->priv))
550 return SR_ERR_ARG;
551
552 switch (key) {
ca55277c 553 break;
9a6517d1 554 case SR_CONF_DEVICE_OPTIONS:
e43fdd8d 555 if (probe_group == &devc->digital_group) {
f48e0249
ML
556 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
557 NULL, 0, sizeof(int32_t));
558 return SR_OK;
559 } else {
560 for (i = 0; i < 2; i++) {
561 if (probe_group == &devc->analog_groups[i]) {
562 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
563 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
564 return SR_OK;
565 }
566 }
567 return SR_ERR_NA;
568 }
2a7b113d 569 case SR_CONF_COUPLING:
f48e0249
ML
570 for (i = 0; i < 2; i++) {
571 if (probe_group == &devc->analog_groups[i]) {
572 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
573 return SR_OK;
574 }
575 }
576 return SR_ERR_NA;
e4f2b2ad 577 case SR_CONF_VDIV:
f48e0249
ML
578 for (i = 0; i < 2; i++) {
579 if (probe_group == &devc->analog_groups[i]) {
580 rational[0] = g_variant_new_uint64(vdivs[i][0]);
581 rational[1] = g_variant_new_uint64(vdivs[i][1]);
582 *data = g_variant_new_tuple(rational, 2);
583 return SR_OK;
584 }
861c447b 585 }
f48e0249 586 return SR_ERR_NA;
41f5bd09 587 case SR_CONF_TIMEBASE:
861c447b
BV
588 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
589 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
590 rational[0] = g_variant_new_uint64(timebases[i][0]);
591 rational[1] = g_variant_new_uint64(timebases[i][1]);
592 tuple = g_variant_new_tuple(rational, 2);
593 g_variant_builder_add_value(&gvb, tuple);
594 }
595 *data = g_variant_builder_end(&gvb);
41f5bd09 596 break;
328bafab 597 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 598 *data = g_variant_new_strv(trigger_sources,
6bb192bc 599 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 600 break;
a1c743fc 601 default:
bd6fbf62 602 return SR_ERR_NA;
a1c743fc
BV
603 }
604
605 return SR_OK;
606}
607
254dd102 608static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 609{
9bd4c956 610 struct sr_serial_dev_inst *serial;
29d957ce 611 struct dev_context *devc;
254dd102
BV
612 struct sr_probe *probe;
613 GSList *l;
254dd102 614 char cmd[256];
29d957ce 615
e73ffd42
BV
616 if (sdi->status != SR_ST_ACTIVE)
617 return SR_ERR_DEV_CLOSED;
e0b7d23c 618
9bd4c956 619 serial = sdi->conn;
29d957ce
UH
620 devc = sdi->priv;
621
254dd102
BV
622 for (l = sdi->probes; l; l = l->next) {
623 probe = l->data;
6bb192bc
ML
624 sr_dbg("handling probe %s", probe->name);
625 if (probe->type == SR_PROBE_ANALOG) {
626 if (probe->enabled)
627 devc->enabled_analog_probes = g_slist_append(
628 devc->enabled_analog_probes, probe);
629 if (probe->enabled != devc->analog_channels[probe->index]) {
630 /* Enabled channel is currently disabled, or vice versa. */
631 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
632 probe->enabled ? "ON" : "OFF");
9bd4c956 633 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
634 return SR_ERR;
635 }
636 } else if (probe->type == SR_PROBE_LOGIC) {
637 if (probe->enabled)
638 devc->enabled_digital_probes = g_slist_append(
639 devc->enabled_digital_probes, probe);
640 if (probe->enabled != devc->digital_channels[probe->index]) {
641 /* Enabled channel is currently disabled, or vice versa. */
642 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
643 probe->enabled ? "ON" : "OFF");
9bd4c956 644 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
6bb192bc
ML
645 return SR_ERR;
646 }
254dd102
BV
647 }
648 }
6bb192bc 649 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 650 return SR_ERR;
e0b7d23c 651
9bd4c956 652 sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
e0b7d23c
ML
653
654 /* Send header packet to the session bus. */
29a27196 655 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 656
254dd102 657 /* Fetch the first frame. */
6bb192bc
ML
658 if (devc->enabled_analog_probes) {
659 devc->channel_frame = devc->enabled_analog_probes->data;
9bd4c956 660 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
6bb192bc
ML
661 devc->channel_frame->index + 1) != SR_OK)
662 return SR_ERR;
663 } else {
664 devc->channel_frame = devc->enabled_digital_probes->data;
9bd4c956 665 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
6bb192bc
ML
666 return SR_ERR;
667 }
f4816ac6 668
ee7e9bee
ML
669 devc->num_frame_bytes = 0;
670
f4816ac6
ML
671 return SR_OK;
672}
673
254dd102 674static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 675{
29d957ce 676 struct dev_context *devc;
cc9fd2d2 677 struct sr_serial_dev_inst *serial;
29d957ce 678
f4816ac6
ML
679 (void)cb_data;
680
29d957ce
UH
681 devc = sdi->priv;
682
f4816ac6
ML
683 if (sdi->status != SR_ST_ACTIVE) {
684 sr_err("Device inactive, can't stop acquisition.");
685 return SR_ERR;
686 }
687
6bb192bc
ML
688 g_slist_free(devc->enabled_analog_probes);
689 g_slist_free(devc->enabled_digital_probes);
690 devc->enabled_analog_probes = NULL;
691 devc->enabled_digital_probes = NULL;
cc9fd2d2
BV
692 serial = sdi->conn;
693 sr_source_remove(serial->fd);
f4816ac6
ML
694
695 return SR_OK;
696}
697
698SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
699 .name = "rigol-ds1xx2",
700 .longname = "Rigol DS1xx2",
701 .api_version = 1,
6078d2c9
UH
702 .init = init,
703 .cleanup = cleanup,
704 .scan = scan,
705 .dev_list = dev_list,
3b412e3a 706 .dev_clear = dev_clear,
d62d7ad1 707 .config_get = config_get,
035a1078 708 .config_set = config_set,
a1c743fc 709 .config_list = config_list,
6078d2c9
UH
710 .dev_open = dev_open,
711 .dev_close = dev_close,
254dd102
BV
712 .dev_acquisition_start = dev_acquisition_start,
713 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
714 .priv = NULL,
715};