]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
Rename rigol-ds1xx2 driver to rigol-ds.
[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>
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
3086efdd
ML
145SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
146static struct sr_dev_driver *di = &rigol_ds_driver_info;
f4816ac6 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);
3086efdd 175 if (rigol_ds_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
3086efdd 361 if (rigol_ds_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
be60a9e4
BV
396 /* If a probe group is specified, it must be a valid one. */
397 if (probe_group) {
398 if (probe_group != &devc->analog_groups[0]
399 && probe_group != &devc->analog_groups[1]) {
400 sr_err("Invalid probe group specified.");
401 return SR_ERR;
402 }
403 }
404
d62d7ad1
BV
405 switch (id) {
406 case SR_CONF_NUM_TIMEBASE:
407 *data = g_variant_new_int32(NUM_TIMEBASE);
408 break;
409 case SR_CONF_NUM_VDIV:
be60a9e4
BV
410 if (!probe_group) {
411 sr_err("No probe group specified.");
412 return SR_ERR_PROBE_GROUP;
413 }
f48e0249 414 for (i = 0; i < 2; i++) {
e43fdd8d 415 if (probe_group == &devc->analog_groups[i]) {
f48e0249
ML
416 *data = g_variant_new_int32(NUM_VDIV);
417 return SR_OK;
418 }
419 }
420 return SR_ERR_NA;
d62d7ad1 421 default:
bd6fbf62 422 return SR_ERR_NA;
d62d7ad1
BV
423 }
424
425 return SR_OK;
426}
427
8f996b89
ML
428static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
429 const struct sr_probe_group *probe_group)
f4816ac6 430{
29d957ce 431 struct dev_context *devc;
f6a0ac9f 432 uint64_t tmp_u64, p, q;
254dd102 433 double t_dbl;
f48e0249 434 unsigned int i, j;
254dd102
BV
435 int ret;
436 const char *tmp_str;
f4816ac6 437
e43fdd8d
BV
438 if (!(devc = sdi->priv))
439 return SR_ERR_ARG;
29d957ce 440
e73ffd42
BV
441 if (sdi->status != SR_ST_ACTIVE)
442 return SR_ERR_DEV_CLOSED;
f4816ac6 443
be60a9e4
BV
444 /* If a probe group is specified, it must be a valid one. */
445 if (probe_group) {
446 if (probe_group != &devc->analog_groups[0]
447 && probe_group != &devc->analog_groups[1]) {
448 sr_err("Invalid probe group specified.");
449 return SR_ERR;
450 }
451 }
452
f4816ac6 453 ret = SR_OK;
035a1078 454 switch (id) {
1953564a 455 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 456 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 457 break;
1953564a 458 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 459 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
460 if (tmp_u64 != 0 && tmp_u64 != 1)
461 return SR_ERR;
462 g_free(devc->trigger_slope);
463 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
464 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 465 break;
1953564a 466 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
467 t_dbl = g_variant_get_double(data);
468 if (t_dbl < 0.0 || t_dbl > 1.0)
469 return SR_ERR;
470 devc->horiz_triggerpos = t_dbl;
471 /* We have the trigger offset as a percentage of the frame, but
472 * need to express this in seconds. */
473 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
474 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
e0b7d23c 475 break;
1953564a 476 case SR_CONF_TIMEBASE:
f6a0ac9f 477 g_variant_get(data, "(tt)", &p, &q);
f6a0ac9f
BV
478 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
479 if (timebases[i][0] == p && timebases[i][1] == q) {
254dd102
BV
480 devc->timebase = (float)p / q;
481 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
f6a0ac9f
BV
482 break;
483 }
484 }
254dd102
BV
485 if (i == ARRAY_SIZE(timebases))
486 ret = SR_ERR_ARG;
e0b7d23c 487 break;
1953564a 488 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 489 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
490 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
491 if (!strcmp(trigger_sources[i], tmp_str)) {
492 g_free(devc->trigger_source);
493 devc->trigger_source = g_strdup(trigger_sources[i]);
494 if (!strcmp(devc->trigger_source, "AC Line"))
495 tmp_str = "ACL";
496 else if (!strcmp(devc->trigger_source, "CH1"))
497 tmp_str = "CHAN1";
498 else if (!strcmp(devc->trigger_source, "CH2"))
499 tmp_str = "CHAN2";
500 else
501 tmp_str = (char *)devc->trigger_source;
502 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
503 break;
504 }
4e108ace 505 }
254dd102
BV
506 if (i == ARRAY_SIZE(trigger_sources))
507 ret = SR_ERR_ARG;
e0b7d23c 508 break;
1953564a 509 case SR_CONF_VDIV:
be60a9e4
BV
510 if (!probe_group) {
511 sr_err("No probe group specified.");
512 return SR_ERR_PROBE_GROUP;
513 }
f6a0ac9f 514 g_variant_get(data, "(tt)", &p, &q);
f48e0249 515 for (i = 0; i < 2; i++) {
78bcc55a
BV
516 if (probe_group == &devc->analog_groups[i]) {
517 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
518 if (vdivs[j][0] != p || vdivs[j][1] != q)
519 continue;
520 devc->vdiv[i] = (float)p / q;
521 return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
522 devc->vdiv[i]);
523 }
524 return SR_ERR_ARG;
525 }
e0b7d23c 526 }
f48e0249 527 return SR_ERR_NA;
1953564a 528 case SR_CONF_COUPLING:
78bcc55a
BV
529 if (!probe_group) {
530 sr_err("No probe group specified.");
531 return SR_ERR_PROBE_GROUP;
532 }
f6a0ac9f 533 tmp_str = g_variant_get_string(data, NULL);
f48e0249 534 for (i = 0; i < 2; i++) {
78bcc55a
BV
535 if (probe_group == &devc->analog_groups[i]) {
536 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
537 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
538 g_free(devc->coupling[i]);
539 devc->coupling[i] = g_strdup(coupling[j]);
540 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
541 devc->coupling[i]);
542 }
543 }
544 return SR_ERR_ARG;
e0b7d23c
ML
545 }
546 }
f48e0249 547 return SR_ERR_NA;
f4816ac6 548 default:
bd6fbf62 549 ret = SR_ERR_NA;
29d957ce 550 break;
f4816ac6
ML
551 }
552
553 return ret;
554}
555
8f996b89
ML
556static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
557 const struct sr_probe_group *probe_group)
a1c743fc 558{
861c447b
BV
559 GVariant *tuple, *rational[2];
560 GVariantBuilder gvb;
561 unsigned int i;
e43fdd8d 562 struct dev_context *devc;
8f996b89 563
e43fdd8d 564 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
565 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
566 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
567 return SR_OK;
568 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
569 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
570 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
571 return SR_OK;
572 }
573
574 /* Every other option requires a valid device instance. */
575 if (!sdi || !(devc = sdi->priv))
576 return SR_ERR_ARG;
577
be60a9e4
BV
578 /* If a probe group is specified, it must be a valid one. */
579 if (probe_group) {
580 if (probe_group != &devc->analog_groups[0]
581 && probe_group != &devc->analog_groups[1]) {
582 sr_err("Invalid probe group specified.");
583 return SR_ERR;
584 }
585 }
586
e43fdd8d 587 switch (key) {
ca55277c 588 break;
9a6517d1 589 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
590 if (!probe_group) {
591 sr_err("No probe group specified.");
592 return SR_ERR_PROBE_GROUP;
593 }
e43fdd8d 594 if (probe_group == &devc->digital_group) {
f48e0249
ML
595 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
596 NULL, 0, sizeof(int32_t));
597 return SR_OK;
598 } else {
599 for (i = 0; i < 2; i++) {
600 if (probe_group == &devc->analog_groups[i]) {
601 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
602 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
603 return SR_OK;
604 }
605 }
606 return SR_ERR_NA;
607 }
5f77dffc 608 break;
2a7b113d 609 case SR_CONF_COUPLING:
be60a9e4
BV
610 if (!probe_group) {
611 sr_err("No probe group specified.");
612 return SR_ERR_PROBE_GROUP;
f48e0249 613 }
58f43369
BV
614 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
615 break;
e4f2b2ad 616 case SR_CONF_VDIV:
be60a9e4
BV
617 if (!probe_group) {
618 sr_err("No probe group specified.");
619 return SR_ERR_PROBE_GROUP;
861c447b 620 }
58f43369
BV
621 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
622 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
623 rational[0] = g_variant_new_uint64(vdivs[i][0]);
624 rational[1] = g_variant_new_uint64(vdivs[i][1]);
625 tuple = g_variant_new_tuple(rational, 2);
626 g_variant_builder_add_value(&gvb, tuple);
627 }
628 *data = g_variant_builder_end(&gvb);
629 break;
41f5bd09 630 case SR_CONF_TIMEBASE:
861c447b
BV
631 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
632 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
633 rational[0] = g_variant_new_uint64(timebases[i][0]);
634 rational[1] = g_variant_new_uint64(timebases[i][1]);
635 tuple = g_variant_new_tuple(rational, 2);
636 g_variant_builder_add_value(&gvb, tuple);
637 }
638 *data = g_variant_builder_end(&gvb);
41f5bd09 639 break;
328bafab 640 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 641 *data = g_variant_new_strv(trigger_sources,
6bb192bc 642 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 643 break;
a1c743fc 644 default:
bd6fbf62 645 return SR_ERR_NA;
a1c743fc
BV
646 }
647
648 return SR_OK;
649}
650
254dd102 651static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 652{
9bd4c956 653 struct sr_serial_dev_inst *serial;
29d957ce 654 struct dev_context *devc;
254dd102
BV
655 struct sr_probe *probe;
656 GSList *l;
254dd102 657 char cmd[256];
29d957ce 658
e73ffd42
BV
659 if (sdi->status != SR_ST_ACTIVE)
660 return SR_ERR_DEV_CLOSED;
e0b7d23c 661
9bd4c956 662 serial = sdi->conn;
29d957ce
UH
663 devc = sdi->priv;
664
254dd102
BV
665 for (l = sdi->probes; l; l = l->next) {
666 probe = l->data;
6bb192bc
ML
667 sr_dbg("handling probe %s", probe->name);
668 if (probe->type == SR_PROBE_ANALOG) {
669 if (probe->enabled)
670 devc->enabled_analog_probes = g_slist_append(
671 devc->enabled_analog_probes, probe);
672 if (probe->enabled != devc->analog_channels[probe->index]) {
673 /* Enabled channel is currently disabled, or vice versa. */
674 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
675 probe->enabled ? "ON" : "OFF");
3086efdd 676 if (rigol_ds_send(sdi, cmd) != SR_OK)
6bb192bc
ML
677 return SR_ERR;
678 }
679 } else if (probe->type == SR_PROBE_LOGIC) {
680 if (probe->enabled)
681 devc->enabled_digital_probes = g_slist_append(
682 devc->enabled_digital_probes, probe);
683 if (probe->enabled != devc->digital_channels[probe->index]) {
684 /* Enabled channel is currently disabled, or vice versa. */
685 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
686 probe->enabled ? "ON" : "OFF");
3086efdd 687 if (rigol_ds_send(sdi, cmd) != SR_OK)
6bb192bc
ML
688 return SR_ERR;
689 }
254dd102
BV
690 }
691 }
6bb192bc 692 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 693 return SR_ERR;
e0b7d23c 694
3086efdd 695 sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
696
697 /* Send header packet to the session bus. */
29a27196 698 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 699
254dd102 700 /* Fetch the first frame. */
6bb192bc
ML
701 if (devc->enabled_analog_probes) {
702 devc->channel_frame = devc->enabled_analog_probes->data;
3086efdd 703 if (rigol_ds_send(sdi, ":WAV:DATA? CHAN%d",
6bb192bc
ML
704 devc->channel_frame->index + 1) != SR_OK)
705 return SR_ERR;
706 } else {
707 devc->channel_frame = devc->enabled_digital_probes->data;
3086efdd 708 if (rigol_ds_send(sdi, ":WAV:DATA? DIG") != SR_OK)
6bb192bc
ML
709 return SR_ERR;
710 }
f4816ac6 711
ee7e9bee
ML
712 devc->num_frame_bytes = 0;
713
f4816ac6
ML
714 return SR_OK;
715}
716
254dd102 717static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 718{
29d957ce 719 struct dev_context *devc;
cc9fd2d2 720 struct sr_serial_dev_inst *serial;
29d957ce 721
f4816ac6
ML
722 (void)cb_data;
723
29d957ce
UH
724 devc = sdi->priv;
725
f4816ac6
ML
726 if (sdi->status != SR_ST_ACTIVE) {
727 sr_err("Device inactive, can't stop acquisition.");
728 return SR_ERR;
729 }
730
6bb192bc
ML
731 g_slist_free(devc->enabled_analog_probes);
732 g_slist_free(devc->enabled_digital_probes);
733 devc->enabled_analog_probes = NULL;
734 devc->enabled_digital_probes = NULL;
cc9fd2d2
BV
735 serial = sdi->conn;
736 sr_source_remove(serial->fd);
f4816ac6
ML
737
738 return SR_OK;
739}
740
3086efdd
ML
741SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
742 .name = "rigol-ds",
743 .longname = "Rigol DS",
f4816ac6 744 .api_version = 1,
6078d2c9
UH
745 .init = init,
746 .cleanup = cleanup,
747 .scan = scan,
748 .dev_list = dev_list,
3b412e3a 749 .dev_clear = dev_clear,
d62d7ad1 750 .config_get = config_get,
035a1078 751 .config_set = config_set,
a1c743fc 752 .config_list = config_list,
6078d2c9
UH
753 .dev_open = dev_open,
754 .dev_close = dev_close,
254dd102
BV
755 .dev_acquisition_start = dev_acquisition_start,
756 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
757 .priv = NULL,
758};