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