]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
rigol-ds: Add support for DS2xx2 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]))) {
314 devc->vdivs = &timebases[i];
315 devc->num_vdivs = NUM_VDIV - (&timebases[i] - &timebases[0]);
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;
bafd4890 587 struct dev_context *devc = sdi->priv;
8f996b89 588
e43fdd8d 589 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
590 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
591 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
592 return SR_OK;
593 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
594 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
595 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
596 return SR_OK;
597 }
598
599 /* Every other option requires a valid device instance. */
600 if (!sdi || !(devc = sdi->priv))
601 return SR_ERR_ARG;
602
be60a9e4
BV
603 /* If a probe group is specified, it must be a valid one. */
604 if (probe_group) {
605 if (probe_group != &devc->analog_groups[0]
606 && probe_group != &devc->analog_groups[1]) {
607 sr_err("Invalid probe group specified.");
608 return SR_ERR;
609 }
610 }
611
e43fdd8d 612 switch (key) {
ca55277c 613 break;
9a6517d1 614 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
615 if (!probe_group) {
616 sr_err("No probe group specified.");
617 return SR_ERR_PROBE_GROUP;
618 }
e43fdd8d 619 if (probe_group == &devc->digital_group) {
f48e0249
ML
620 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
621 NULL, 0, sizeof(int32_t));
622 return SR_OK;
623 } else {
624 for (i = 0; i < 2; i++) {
625 if (probe_group == &devc->analog_groups[i]) {
626 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
627 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
628 return SR_OK;
629 }
630 }
631 return SR_ERR_NA;
632 }
5f77dffc 633 break;
2a7b113d 634 case SR_CONF_COUPLING:
be60a9e4
BV
635 if (!probe_group) {
636 sr_err("No probe group specified.");
637 return SR_ERR_PROBE_GROUP;
f48e0249 638 }
58f43369
BV
639 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
640 break;
e4f2b2ad 641 case SR_CONF_VDIV:
be60a9e4
BV
642 if (!probe_group) {
643 sr_err("No probe group specified.");
644 return SR_ERR_PROBE_GROUP;
861c447b 645 }
58f43369 646 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
647 for (i = 0; i < devc->num_vdivs; i++) {
648 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
649 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
650 tuple = g_variant_new_tuple(rational, 2);
651 g_variant_builder_add_value(&gvb, tuple);
652 }
653 *data = g_variant_builder_end(&gvb);
654 break;
41f5bd09 655 case SR_CONF_TIMEBASE:
861c447b 656 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
657 for (i = 0; i < devc->num_timebases; i++) {
658 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
659 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
660 tuple = g_variant_new_tuple(rational, 2);
661 g_variant_builder_add_value(&gvb, tuple);
662 }
663 *data = g_variant_builder_end(&gvb);
41f5bd09 664 break;
328bafab 665 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 666 *data = g_variant_new_strv(trigger_sources,
bafd4890 667 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 668 break;
a1c743fc 669 default:
bd6fbf62 670 return SR_ERR_NA;
a1c743fc
BV
671 }
672
673 return SR_OK;
674}
675
254dd102 676static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 677{
9bd4c956 678 struct sr_serial_dev_inst *serial;
29d957ce 679 struct dev_context *devc;
254dd102
BV
680 struct sr_probe *probe;
681 GSList *l;
254dd102 682 char cmd[256];
29d957ce 683
e73ffd42
BV
684 if (sdi->status != SR_ST_ACTIVE)
685 return SR_ERR_DEV_CLOSED;
e0b7d23c 686
9bd4c956 687 serial = sdi->conn;
29d957ce
UH
688 devc = sdi->priv;
689
254dd102
BV
690 for (l = sdi->probes; l; l = l->next) {
691 probe = l->data;
6bb192bc
ML
692 sr_dbg("handling probe %s", probe->name);
693 if (probe->type == SR_PROBE_ANALOG) {
694 if (probe->enabled)
695 devc->enabled_analog_probes = g_slist_append(
696 devc->enabled_analog_probes, probe);
697 if (probe->enabled != devc->analog_channels[probe->index]) {
698 /* Enabled channel is currently disabled, or vice versa. */
699 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
700 probe->enabled ? "ON" : "OFF");
3086efdd 701 if (rigol_ds_send(sdi, cmd) != SR_OK)
6bb192bc
ML
702 return SR_ERR;
703 }
704 } else if (probe->type == SR_PROBE_LOGIC) {
705 if (probe->enabled)
706 devc->enabled_digital_probes = g_slist_append(
707 devc->enabled_digital_probes, probe);
708 if (probe->enabled != devc->digital_channels[probe->index]) {
709 /* Enabled channel is currently disabled, or vice versa. */
710 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
711 probe->enabled ? "ON" : "OFF");
3086efdd 712 if (rigol_ds_send(sdi, cmd) != SR_OK)
6bb192bc
ML
713 return SR_ERR;
714 }
254dd102
BV
715 }
716 }
6bb192bc 717 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 718 return SR_ERR;
e0b7d23c 719
3086efdd 720 sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
721
722 /* Send header packet to the session bus. */
29a27196 723 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 724
bafd4890
ML
725 if (devc->model->series == 1) {
726 /* Fetch the first frame. */
727 if (devc->enabled_analog_probes) {
728 devc->channel_frame = devc->enabled_analog_probes->data;
729 if (rigol_ds_send(sdi, ":WAV:DATA? CHAN%d",
730 devc->channel_frame->index + 1) != SR_OK)
731 return SR_ERR;
732 } else {
733 devc->channel_frame = devc->enabled_digital_probes->data;
734 if (rigol_ds_send(sdi, ":WAV:DATA? DIG") != SR_OK)
735 return SR_ERR;
736 }
737
738 devc->num_frame_bytes = 0;
6bb192bc 739 } else {
bafd4890
ML
740 if (devc->enabled_analog_probes) {
741 /* Assume there already was a trigger event - don't wait */
742 if (rigol_ds2xx2_acquisition_start(sdi, FALSE) != SR_OK)
743 return SR_ERR;
744 }
6bb192bc 745 }
f4816ac6
ML
746
747 return SR_OK;
748}
749
254dd102 750static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 751{
29d957ce 752 struct dev_context *devc;
cc9fd2d2 753 struct sr_serial_dev_inst *serial;
29d957ce 754
f4816ac6
ML
755 (void)cb_data;
756
29d957ce
UH
757 devc = sdi->priv;
758
f4816ac6
ML
759 if (sdi->status != SR_ST_ACTIVE) {
760 sr_err("Device inactive, can't stop acquisition.");
761 return SR_ERR;
762 }
763
6bb192bc
ML
764 g_slist_free(devc->enabled_analog_probes);
765 g_slist_free(devc->enabled_digital_probes);
766 devc->enabled_analog_probes = NULL;
767 devc->enabled_digital_probes = NULL;
cc9fd2d2
BV
768 serial = sdi->conn;
769 sr_source_remove(serial->fd);
f4816ac6
ML
770
771 return SR_OK;
772}
773
3086efdd
ML
774SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
775 .name = "rigol-ds",
776 .longname = "Rigol DS",
f4816ac6 777 .api_version = 1,
6078d2c9
UH
778 .init = init,
779 .cleanup = cleanup,
780 .scan = scan,
781 .dev_list = dev_list,
3b412e3a 782 .dev_clear = dev_clear,
d62d7ad1 783 .config_get = config_get,
035a1078 784 .config_set = config_set,
a1c743fc 785 .config_list = config_list,
6078d2c9
UH
786 .dev_open = dev_open,
787 .dev_close = dev_close,
254dd102
BV
788 .dev_acquisition_start = dev_acquisition_start,
789 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
790 .priv = NULL,
791};