]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
rigol-ds: Stop capture cleanly on read errors.
[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>
2b0e4a46 26#include <math.h>
f4816ac6
ML
27#include <glib.h>
28#include "libsigrok.h"
29#include "libsigrok-internal.h"
30#include "protocol.h"
31
ca55277c
ML
32static const int32_t hwopts[] = {
33 SR_CONF_CONN,
0dc7b43e 34 SR_CONF_SERIALCOMM
ca55277c
ML
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,
c1bcb8cc 44 SR_CONF_LIMIT_FRAMES,
4914dd4b 45 SR_CONF_SAMPLERATE,
f48e0249
ML
46};
47
48static const int32_t analog_hwcaps[] = {
d62d7ad1 49 SR_CONF_NUM_VDIV,
f48e0249 50 SR_CONF_VDIV,
78bcc55a 51 SR_CONF_COUPLING,
babab622 52 SR_CONF_DATA_SOURCE,
e0b7d23c
ML
53};
54
f6a0ac9f 55static const uint64_t timebases[][2] = {
e0b7d23c 56 /* nanoseconds */
8e06edf5 57 { 1, 1000000000 },
e0b7d23c
ML
58 { 2, 1000000000 },
59 { 5, 1000000000 },
60 { 10, 1000000000 },
61 { 20, 1000000000 },
62 { 50, 1000000000 },
63 { 100, 1000000000 },
64 { 500, 1000000000 },
65 /* microseconds */
66 { 1, 1000000 },
67 { 2, 1000000 },
68 { 5, 1000000 },
69 { 10, 1000000 },
70 { 20, 1000000 },
71 { 50, 1000000 },
72 { 100, 1000000 },
73 { 200, 1000000 },
74 { 500, 1000000 },
75 /* milliseconds */
76 { 1, 1000 },
77 { 2, 1000 },
78 { 5, 1000 },
79 { 10, 1000 },
80 { 20, 1000 },
81 { 50, 1000 },
82 { 100, 1000 },
83 { 200, 1000 },
84 { 500, 1000 },
85 /* seconds */
86 { 1, 1 },
87 { 2, 1 },
88 { 5, 1 },
89 { 10, 1 },
90 { 20, 1 },
91 { 50, 1 },
bafd4890
ML
92 { 100, 1 },
93 { 200, 1 },
94 { 500, 1 },
8e06edf5 95 { 1000, 1 },
e0b7d23c
ML
96};
97
f6a0ac9f 98static const uint64_t vdivs[][2] = {
bafd4890
ML
99 /* microvolts */
100 { 500, 1000000 },
e0b7d23c 101 /* millivolts */
bafd4890 102 { 1, 1000 },
e0b7d23c
ML
103 { 2, 1000 },
104 { 5, 1000 },
105 { 10, 1000 },
106 { 20, 1000 },
107 { 50, 1000 },
108 { 100, 1000 },
109 { 200, 1000 },
110 { 500, 1000 },
111 /* volts */
112 { 1, 1 },
113 { 2, 1 },
114 { 5, 1 },
115 { 10, 1 },
e0b7d23c
ML
116};
117
bafd4890
ML
118#define NUM_TIMEBASE ARRAY_SIZE(timebases)
119#define NUM_VDIV ARRAY_SIZE(vdivs)
120
e0b7d23c
ML
121static const char *trigger_sources[] = {
122 "CH1",
123 "CH2",
821fbcad
ML
124 "CH3",
125 "CH4",
e0b7d23c
ML
126 "EXT",
127 "AC Line",
6bb192bc
ML
128 "D0",
129 "D1",
130 "D2",
131 "D3",
132 "D4",
133 "D5",
134 "D6",
135 "D7",
136 "D8",
137 "D9",
138 "D10",
139 "D11",
140 "D12",
141 "D13",
142 "D14",
143 "D15",
e0b7d23c
ML
144};
145
146static const char *coupling[] = {
147 "AC",
148 "DC",
149 "GND",
e0b7d23c
ML
150};
151
babab622
ML
152/* Do not change the order of entries */
153static const char *data_sources[] = {
154 "Live",
155 "Memory",
156 "Segmented",
157};
158
569d4dbd
ML
159enum vendor {
160 RIGOL,
161 AGILENT,
162};
163
164enum series {
165 VS5000,
166 DS1000,
167 DS2000,
168 DS2000A,
169 DSO1000,
170};
10afee13 171
569d4dbd
ML
172/* short name, full name */
173static const struct rigol_ds_vendor supported_vendors[] = {
174 [RIGOL] = {"Rigol", "Rigol Technologies"},
175 [AGILENT] = {"Agilent", "Rigol Technologies"},
176};
177
178#define VENDOR(x) &supported_vendors[x]
179/* vendor, series, protocol, max timebase, min vdiv, number of horizontal divs,
180 * live waveform samples, memory buffer samples */
181static const struct rigol_ds_series supported_series[] = {
182 [VS5000] = {VENDOR(RIGOL), "VS5000", PROTOCOL_V1, FORMAT_RAW,
183 {50, 1}, {2, 1000}, 14, 2048, 0},
184 [DS1000] = {VENDOR(RIGOL), "DS1000", PROTOCOL_V2, FORMAT_IEEE488_2,
185 {50, 1}, {2, 1000}, 12, 600, 1048576},
186 [DS2000] = {VENDOR(RIGOL), "DS2000", PROTOCOL_V3, FORMAT_IEEE488_2,
187 {500, 1}, {2, 1000}, 14, 1400, 14000},
188 [DS2000A] = {VENDOR(RIGOL), "DS2000A", PROTOCOL_V3, FORMAT_IEEE488_2,
189 {1000, 1}, {500, 1000000}, 14, 1400, 14000},
190 [DSO1000] = {VENDOR(AGILENT), "DSO1000", PROTOCOL_V3, FORMAT_IEEE488_2,
191 {50, 1}, {2, 1000}, 12, 600, 20480},
192};
10afee13 193
569d4dbd
ML
194#define SERIES(x) &supported_series[x]
195/* series, model, min timebase, analog channels, digital */
bafd4890 196static const struct rigol_ds_model supported_models[] = {
569d4dbd
ML
197 {SERIES(VS5000), "VS5022", {20, 1000000000}, 2, false},
198 {SERIES(VS5000), "VS5042", {10, 1000000000}, 2, false},
199 {SERIES(VS5000), "VS5062", {5, 1000000000}, 2, false},
200 {SERIES(VS5000), "VS5102", {2, 1000000000}, 2, false},
201 {SERIES(VS5000), "VS5202", {2, 1000000000}, 2, false},
202 {SERIES(VS5000), "VS5022D", {20, 1000000000}, 2, true},
203 {SERIES(VS5000), "VS5042D", {10, 1000000000}, 2, true},
204 {SERIES(VS5000), "VS5062D", {5, 1000000000}, 2, true},
205 {SERIES(VS5000), "VS5102D", {2, 1000000000}, 2, true},
206 {SERIES(VS5000), "VS5202D", {2, 1000000000}, 2, true},
207 {SERIES(DS1000), "DS1052E", {5, 1000000000}, 2, false},
208 {SERIES(DS1000), "DS1102E", {2, 1000000000}, 2, false},
209 {SERIES(DS1000), "DS1152E", {2, 1000000000}, 2, false},
210 {SERIES(DS1000), "DS1052D", {5, 1000000000}, 2, true},
211 {SERIES(DS1000), "DS1102D", {2, 1000000000}, 2, true},
212 {SERIES(DS1000), "DS1152D", {2, 1000000000}, 2, true},
213 {SERIES(DS2000), "DS2072", {5, 1000000000}, 2, false},
214 {SERIES(DS2000), "DS2102", {5, 1000000000}, 2, false},
215 {SERIES(DS2000), "DS2202", {2, 1000000000}, 2, false},
216 {SERIES(DS2000), "DS2302", {1, 1000000000}, 2, false},
217 {SERIES(DS2000A), "DS2072A", {5, 1000000000}, 2, false},
218 {SERIES(DS2000A), "DS2102A", {5, 1000000000}, 2, false},
219 {SERIES(DS2000A), "DS2202A", {2, 1000000000}, 2, false},
220 {SERIES(DS2000A), "DS2302A", {1, 1000000000}, 2, false},
221 {SERIES(DSO1000), "DSO1002A", {5, 1000000000}, 2, false},
222 {SERIES(DSO1000), "DSO1004A", {5, 1000000000}, 4, false},
223 {SERIES(DSO1000), "DSO1012A", {2, 1000000000}, 2, false},
224 {SERIES(DSO1000), "DSO1014A", {2, 1000000000}, 4, false},
225 {SERIES(DSO1000), "DSO1022A", {2, 1000000000}, 2, false},
226 {SERIES(DSO1000), "DSO1024A", {2, 1000000000}, 4, false},
512bb890
BV
227};
228
3086efdd
ML
229SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
230static struct sr_dev_driver *di = &rigol_ds_driver_info;
f4816ac6 231
fa85f376 232static void clear_helper(void *priv)
f4816ac6 233{
f4816ac6 234 struct dev_context *devc;
f4816ac6 235
ba358ffd 236 devc = priv;
babab622
ML
237 g_free(devc->data);
238 g_free(devc->buffer);
fa85f376
UH
239 g_free(devc->coupling[0]);
240 g_free(devc->coupling[1]);
241 g_free(devc->trigger_source);
242 g_free(devc->trigger_slope);
ba358ffd
BV
243 g_slist_free(devc->analog_groups[0].probes);
244 g_slist_free(devc->analog_groups[1].probes);
245 g_slist_free(devc->digital_group.probes);
fa85f376 246}
f4816ac6 247
3b412e3a 248static int dev_clear(void)
fa85f376
UH
249{
250 return std_dev_clear(di, clear_helper);
f4816ac6
ML
251}
252
6078d2c9 253static int init(struct sr_context *sr_ctx)
f4816ac6 254{
f6beaac5 255 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
256}
257
3520422f 258static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
f4816ac6 259{
cc9fd2d2
BV
260 struct dev_context *devc;
261 struct sr_dev_inst *sdi;
ae1bc1cc
ML
262 struct sr_scpi_dev_inst *scpi;
263 struct sr_scpi_hw_info *hw_info;
cc9fd2d2 264 struct sr_probe *probe;
8dd0b290 265 long n[3];
f6a0ac9f 266 unsigned int i;
bafd4890 267 const struct rigol_ds_model *model = NULL;
569d4dbd 268 gchar *channel_name, **version;
fb6e5ba8 269
46a743c1 270 *devices = NULL;
0dc7b43e 271
c3515cea
AJ
272 if (!(scpi = scpi_dev_inst_new(resource, serialcomm)))
273 return SR_ERR;
9bd4c956 274
ae1bc1cc 275 if (sr_scpi_open(scpi) != SR_OK) {
10afee13 276 sr_info("Couldn't open SCPI device.");
ae1bc1cc 277 sr_scpi_free(scpi);
9bd4c956 278 return SR_ERR;
ae1bc1cc 279 };
9bd4c956 280
ae1bc1cc
ML
281 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
282 sr_info("Couldn't get IDN response.");
283 sr_scpi_close(scpi);
284 sr_scpi_free(scpi);
285 return SR_ERR;
ca55277c 286 }
e0b7d23c 287
ca55277c 288 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
569d4dbd
ML
289 if (!strcasecmp(hw_info->manufacturer,
290 supported_models[i].series->vendor->full_name) &&
10afee13 291 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 292 model = &supported_models[i];
ca55277c 293 break;
fb6e5ba8 294 }
ca55277c 295 }
fb6e5ba8 296
bafd4890 297 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
569d4dbd
ML
298 model->series->vendor->name,
299 model->name,
ae1bc1cc
ML
300 hw_info->firmware_version))) {
301 sr_scpi_hw_info_free(hw_info);
b4936bae 302 sr_scpi_close(scpi);
ae1bc1cc 303 sr_scpi_free(scpi);
ca55277c
ML
304 return SR_ERR_NA;
305 }
fb6e5ba8 306
b4936bae 307 sr_scpi_close(scpi);
ae1bc1cc
ML
308
309 sdi->conn = scpi;
fb6e5ba8 310
cc9fd2d2 311 sdi->driver = di;
ae1bc1cc 312 sdi->inst_type = SR_INST_SCPI;
512bb890 313
cc9fd2d2 314 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
ca55277c 315 return SR_ERR_MALLOC;
ae1bc1cc 316
cc9fd2d2 317 devc->limit_frames = 0;
bafd4890 318 devc->model = model;
569d4dbd 319 devc->format = model->series->format;
8dd0b290 320
569d4dbd
ML
321 /* DS1000 models with firmware before 0.2.4 used the old data format. */
322 if (model->series == SERIES(DS1000)) {
8dd0b290
BV
323 version = g_strsplit(hw_info->firmware_version, ".", 0);
324 do {
325 if (!version[0] || !version[1] || !version[2])
326 break;
327 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
328 break;
329 for (i = 0; i < 3; i++) {
330 if (sr_atol(version[i], &n[i]) != SR_OK)
331 break;
332 }
333 if (i != 3)
334 break;
335 if (n[0] != 0 || n[1] > 2)
336 break;
337 if (n[1] == 2 && n[2] > 3)
338 break;
569d4dbd
ML
339 sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format.");
340 devc->format = FORMAT_RAW;
8dd0b290
BV
341 } while(0);
342 g_strfreev(version);
343 }
344
345 sr_scpi_hw_info_free(hw_info);
512bb890 346
821fbcad
ML
347 for (i = 0; i < model->analog_channels; i++) {
348 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
ca55277c 349 return SR_ERR_MALLOC;
821fbcad 350 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
ca55277c 351 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
352 devc->analog_groups[i].name = channel_name;
353 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
354 sdi->probe_groups = g_slist_append(sdi->probe_groups,
355 &devc->analog_groups[i]);
ca55277c 356 }
512bb890 357
bafd4890 358 if (devc->model->has_digital) {
ca55277c
ML
359 for (i = 0; i < 16; i++) {
360 if (!(channel_name = g_strdup_printf("D%d", i)))
361 return SR_ERR_MALLOC;
362 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
363 g_free(channel_name);
364 if (!probe)
365 return SR_ERR_MALLOC;
366 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
367 devc->digital_group.probes = g_slist_append(
368 devc->digital_group.probes, probe);
512bb890 369 }
b3916147
ML
370 devc->digital_group.name = "LA";
371 sdi->probe_groups = g_slist_append(sdi->probe_groups,
372 &devc->digital_group);
ca55277c 373 }
bafd4890
ML
374
375 for (i = 0; i < NUM_TIMEBASE; i++) {
376 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
377 devc->timebases = &timebases[i];
569d4dbd 378 if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
bafd4890
ML
379 devc->num_timebases = &timebases[i] - devc->timebases + 1;
380 }
381
0709197d 382 for (i = 0; i < NUM_VDIV; i++)
569d4dbd 383 if (!memcmp(&devc->model->series->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
6ff1394e 384 devc->vdivs = &vdivs[i];
bafd4890 385
babab622
ML
386 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
387 return SR_ERR_MALLOC;
388 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
389 return SR_ERR_MALLOC;
390
391 devc->data_source = DATA_SOURCE_LIVE;
392
cc9fd2d2
BV
393 sdi->priv = devc;
394
395 *devices = g_slist_append(NULL, sdi);
512bb890 396
ca55277c
ML
397 return SR_OK;
398}
512bb890 399
6078d2c9 400static GSList *scan(GSList *options)
ca55277c
ML
401{
402 struct drv_context *drvc;
ca55277c 403 struct sr_config *src;
cc9fd2d2 404 GSList *l, *devices;
ca55277c 405 GDir *dir;
ca55277c 406 int ret;
cc9fd2d2
BV
407 const gchar *dev_name;
408 gchar *port = NULL;
0dc7b43e 409 gchar *serialcomm = NULL;
fb6e5ba8 410
ca55277c 411 drvc = di->priv;
d2e0b1fa 412
ca55277c
ML
413 for (l = options; l; l = l->next) {
414 src = l->data;
0dc7b43e
ML
415 switch (src->key) {
416 case SR_CONF_CONN:
cc9fd2d2 417 port = (char *)g_variant_get_string(src->data, NULL);
ca55277c 418 break;
0dc7b43e
ML
419 case SR_CONF_SERIALCOMM:
420 serialcomm = (char *)g_variant_get_string(src->data, NULL);
421 break;
fb6e5ba8 422 }
ca55277c 423 }
fb6e5ba8 424
46a743c1 425 devices = NULL;
cc9fd2d2 426 if (port) {
0dc7b43e
ML
427 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
428 g_free(port);
429 if (serialcomm)
430 g_free(serialcomm);
ca55277c 431 return NULL;
0dc7b43e 432 }
ca55277c 433 } else {
da970d24
BV
434 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
435 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
436 return NULL;
ca55277c 437 while ((dev_name = g_dir_read_name(dir))) {
cc9fd2d2 438 if (strncmp(dev_name, "usbtmc", 6))
ca55277c 439 continue;
cc9fd2d2 440 port = g_strconcat("/dev/", dev_name, NULL);
0dc7b43e 441 ret = probe_port(port, serialcomm, &devices);
cc9fd2d2 442 g_free(port);
0dc7b43e
ML
443 if (serialcomm)
444 g_free(serialcomm);
ca55277c
ML
445 if (ret == SR_ERR_MALLOC) {
446 g_dir_close(dir);
ca55277c 447 return NULL;
6bb192bc
ML
448 }
449 }
ca55277c
ML
450 g_dir_close(dir);
451 }
f4816ac6 452
46a743c1
BV
453 /* Tack a copy of the newly found devices onto the driver list. */
454 l = g_slist_copy(devices);
455 drvc->instances = g_slist_concat(drvc->instances, l);
cc9fd2d2 456
f4816ac6
ML
457 return devices;
458}
459
6078d2c9 460static GSList *dev_list(void)
f4816ac6 461{
0e94d524 462 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
463}
464
6078d2c9 465static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 466{
ae1bc1cc 467 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 468
ae1bc1cc 469 if (sr_scpi_open(scpi) < 0)
e0b7d23c 470 return SR_ERR;
e0b7d23c 471
3086efdd 472 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
254dd102 473 return SR_ERR;
f4816ac6 474
46a743c1 475 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 476
f4816ac6
ML
477 return SR_OK;
478}
479
6078d2c9 480static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 481{
ae1bc1cc 482 struct sr_scpi_dev_inst *scpi;
22c19688 483 struct dev_context *devc;
ae1bc1cc
ML
484
485 scpi = sdi->conn;
22c19688
ML
486 devc = sdi->priv;
487
569d4dbd 488 if (devc->model->series->protocol >= PROTOCOL_V2)
38354d9d 489 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 490
ae1bc1cc
ML
491 if (scpi) {
492 if (sr_scpi_close(scpi) < 0)
493 return SR_ERR;
cc9fd2d2
BV
494 sdi->status = SR_ST_INACTIVE;
495 }
f4816ac6
ML
496
497 return SR_OK;
498}
499
6078d2c9 500static int cleanup(void)
f4816ac6 501{
3b412e3a 502 return dev_clear();
f4816ac6
ML
503}
504
5415e602
ML
505static int analog_frame_size(const struct sr_dev_inst *sdi)
506{
507 struct dev_context *devc = sdi->priv;
508 struct sr_probe *probe;
509 int analog_probes = 0;
510 GSList *l;
511
569d4dbd
ML
512 for (l = sdi->probes; l; l = l->next) {
513 probe = l->data;
514 if (probe->type == SR_PROBE_ANALOG && probe->enabled)
515 analog_probes++;
516 }
517
518 switch (devc->data_source) {
519 case DATA_SOURCE_LIVE:
520 return devc->model->series->live_samples;
521 case DATA_SOURCE_MEMORY:
522 return devc->model->series->buffer_samples / analog_probes;
470140fc 523 default:
569d4dbd 524 return 0;
5415e602
ML
525 }
526}
527
d22250a9
ML
528static int digital_frame_size(const struct sr_dev_inst *sdi)
529{
530 struct dev_context *devc = sdi->priv;
531
569d4dbd
ML
532 switch (devc->data_source) {
533 case DATA_SOURCE_LIVE:
534 return devc->model->series->live_samples * 2;
535 case DATA_SOURCE_MEMORY:
536 return devc->model->series->buffer_samples * 2;
d22250a9
ML
537 default:
538 return 0;
539 }
540}
541
8f996b89
ML
542static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
543 const struct sr_probe_group *probe_group)
d62d7ad1 544{
e43fdd8d 545 struct dev_context *devc;
2b0e4a46
AJ
546 struct sr_probe *probe;
547 const char *tmp_str;
c2b394d5 548 uint64_t samplerate;
2b0e4a46
AJ
549 int analog_channel = -1;
550 float smallest_diff = 0.0000000001;
551 int idx = -1;
552 unsigned i;
d62d7ad1 553
e43fdd8d
BV
554 if (!sdi || !(devc = sdi->priv))
555 return SR_ERR_ARG;
556
be60a9e4 557 /* If a probe group is specified, it must be a valid one. */
c2b394d5 558 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
559 sr_err("Invalid probe group specified.");
560 return SR_ERR;
be60a9e4
BV
561 }
562
2b0e4a46
AJ
563 if (probe_group) {
564 probe = g_slist_nth_data(probe_group->probes, 0);
565 if (!probe)
566 return SR_ERR;
567 if (probe->type == SR_PROBE_ANALOG) {
568 if (probe->name[2] < '1' || probe->name[2] > '4')
569 return SR_ERR;
570 analog_channel = probe->name[2] - '1';
571 }
572 }
573
d62d7ad1
BV
574 switch (id) {
575 case SR_CONF_NUM_TIMEBASE:
569d4dbd 576 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
577 break;
578 case SR_CONF_NUM_VDIV:
72ecba02 579 *data = g_variant_new_int32(NUM_VDIV);
babab622
ML
580 case SR_CONF_DATA_SOURCE:
581 if (devc->data_source == DATA_SOURCE_LIVE)
582 *data = g_variant_new_string("Live");
583 else if (devc->data_source == DATA_SOURCE_MEMORY)
584 *data = g_variant_new_string("Memory");
585 else
586 *data = g_variant_new_string("Segmented");
587 break;
4914dd4b
ML
588 case SR_CONF_SAMPLERATE:
589 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 590 samplerate = analog_frame_size(sdi) /
569d4dbd 591 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 592 *data = g_variant_new_uint64(samplerate);
c2b394d5 593 } else {
4914dd4b 594 return SR_ERR_NA;
c2b394d5 595 }
4914dd4b 596 break;
2b0e4a46
AJ
597 case SR_CONF_TRIGGER_SOURCE:
598 if (!strcmp(devc->trigger_source, "ACL"))
599 tmp_str = "AC Line";
600 else if (!strcmp(devc->trigger_source, "CHAN1"))
601 tmp_str = "CH1";
602 else if (!strcmp(devc->trigger_source, "CHAN2"))
603 tmp_str = "CH2";
604 else if (!strcmp(devc->trigger_source, "CHAN3"))
605 tmp_str = "CH3";
606 else if (!strcmp(devc->trigger_source, "CHAN4"))
607 tmp_str = "CH4";
608 else
609 tmp_str = devc->trigger_source;
610 *data = g_variant_new_string(tmp_str);
611 break;
612 case SR_CONF_TIMEBASE:
613 for (i = 0; i < devc->num_timebases; i++) {
614 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
615 float diff = fabs(devc->timebase - tb);
616 if (diff < smallest_diff) {
617 smallest_diff = diff;
618 idx = i;
619 }
620 }
621 if (idx < 0)
622 return SR_ERR_NA;
623 *data = g_variant_new("(tt)", devc->timebases[idx][0],
624 devc->timebases[idx][1]);
625 break;
626 case SR_CONF_VDIV:
627 if (analog_channel < 0)
628 return SR_ERR_NA;
629 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
630 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
631 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
632 if (diff < smallest_diff) {
633 smallest_diff = diff;
634 idx = i;
635 }
636 }
637 if (idx < 0)
638 return SR_ERR_NA;
639 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
640 break;
641 case SR_CONF_COUPLING:
642 if (analog_channel < 0)
643 return SR_ERR_NA;
644 *data = g_variant_new_string(devc->coupling[analog_channel]);
645 break;
d62d7ad1 646 default:
bd6fbf62 647 return SR_ERR_NA;
d62d7ad1
BV
648 }
649
650 return SR_OK;
651}
652
8f996b89
ML
653static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
654 const struct sr_probe_group *probe_group)
f4816ac6 655{
29d957ce 656 struct dev_context *devc;
f6a0ac9f 657 uint64_t tmp_u64, p, q;
254dd102 658 double t_dbl;
f48e0249 659 unsigned int i, j;
254dd102
BV
660 int ret;
661 const char *tmp_str;
889ef4a0 662 char buffer[16];
f4816ac6 663
e43fdd8d
BV
664 if (!(devc = sdi->priv))
665 return SR_ERR_ARG;
29d957ce 666
e73ffd42
BV
667 if (sdi->status != SR_ST_ACTIVE)
668 return SR_ERR_DEV_CLOSED;
f4816ac6 669
be60a9e4 670 /* If a probe group is specified, it must be a valid one. */
c2b394d5 671 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
672 sr_err("Invalid probe group specified.");
673 return SR_ERR;
be60a9e4
BV
674 }
675
f4816ac6 676 ret = SR_OK;
035a1078 677 switch (id) {
1953564a 678 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 679 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 680 break;
1953564a 681 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 682 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
683 if (tmp_u64 != 0 && tmp_u64 != 1)
684 return SR_ERR;
685 g_free(devc->trigger_slope);
686 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
38354d9d 687 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 688 break;
1953564a 689 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
690 t_dbl = g_variant_get_double(data);
691 if (t_dbl < 0.0 || t_dbl > 1.0)
692 return SR_ERR;
693 devc->horiz_triggerpos = t_dbl;
694 /* We have the trigger offset as a percentage of the frame, but
695 * need to express this in seconds. */
bafd4890 696 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 697 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 698 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 699 break;
1953564a 700 case SR_CONF_TIMEBASE:
f6a0ac9f 701 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
702 for (i = 0; i < devc->num_timebases; i++) {
703 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 704 devc->timebase = (float)p / q;
889ef4a0
AJ
705 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
706 devc->timebase);
38354d9d 707 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
708 break;
709 }
710 }
bafd4890 711 if (i == devc->num_timebases)
254dd102 712 ret = SR_ERR_ARG;
e0b7d23c 713 break;
1953564a 714 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 715 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
716 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
717 if (!strcmp(trigger_sources[i], tmp_str)) {
718 g_free(devc->trigger_source);
719 devc->trigger_source = g_strdup(trigger_sources[i]);
720 if (!strcmp(devc->trigger_source, "AC Line"))
721 tmp_str = "ACL";
722 else if (!strcmp(devc->trigger_source, "CH1"))
723 tmp_str = "CHAN1";
724 else if (!strcmp(devc->trigger_source, "CH2"))
725 tmp_str = "CHAN2";
821fbcad
ML
726 else if (!strcmp(devc->trigger_source, "CH3"))
727 tmp_str = "CHAN3";
728 else if (!strcmp(devc->trigger_source, "CH4"))
729 tmp_str = "CHAN4";
254dd102
BV
730 else
731 tmp_str = (char *)devc->trigger_source;
38354d9d 732 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
733 break;
734 }
4e108ace 735 }
254dd102
BV
736 if (i == ARRAY_SIZE(trigger_sources))
737 ret = SR_ERR_ARG;
e0b7d23c 738 break;
1953564a 739 case SR_CONF_VDIV:
be60a9e4
BV
740 if (!probe_group) {
741 sr_err("No probe group specified.");
742 return SR_ERR_PROBE_GROUP;
743 }
f6a0ac9f 744 g_variant_get(data, "(tt)", &p, &q);
f48e0249 745 for (i = 0; i < 2; i++) {
78bcc55a
BV
746 if (probe_group == &devc->analog_groups[i]) {
747 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
748 if (vdivs[j][0] != p || vdivs[j][1] != q)
749 continue;
750 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
751 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
752 devc->vdiv[i]);
38354d9d 753 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 754 buffer);
f48e0249
ML
755 }
756 return SR_ERR_ARG;
757 }
e0b7d23c 758 }
f48e0249 759 return SR_ERR_NA;
1953564a 760 case SR_CONF_COUPLING:
78bcc55a
BV
761 if (!probe_group) {
762 sr_err("No probe group specified.");
763 return SR_ERR_PROBE_GROUP;
764 }
f6a0ac9f 765 tmp_str = g_variant_get_string(data, NULL);
f48e0249 766 for (i = 0; i < 2; i++) {
78bcc55a
BV
767 if (probe_group == &devc->analog_groups[i]) {
768 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
769 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
770 g_free(devc->coupling[i]);
771 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 772 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
773 devc->coupling[i]);
774 }
775 }
776 return SR_ERR_ARG;
e0b7d23c
ML
777 }
778 }
f48e0249 779 return SR_ERR_NA;
babab622
ML
780 case SR_CONF_DATA_SOURCE:
781 tmp_str = g_variant_get_string(data, NULL);
782 if (!strcmp(tmp_str, "Live"))
783 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
784 else if (devc->model->series->protocol >= PROTOCOL_V2
785 && !strcmp(tmp_str, "Memory"))
babab622 786 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 787 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
788 && !strcmp(tmp_str, "Segmented"))
789 devc->data_source = DATA_SOURCE_SEGMENTED;
790 else
791 return SR_ERR;
792 break;
f4816ac6 793 default:
bd6fbf62 794 ret = SR_ERR_NA;
29d957ce 795 break;
f4816ac6
ML
796 }
797
798 return ret;
799}
800
8f996b89
ML
801static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
802 const struct sr_probe_group *probe_group)
a1c743fc 803{
861c447b
BV
804 GVariant *tuple, *rational[2];
805 GVariantBuilder gvb;
806 unsigned int i;
7cc1a550
ML
807 struct dev_context *devc = NULL;
808
809 if (sdi)
810 devc = sdi->priv;
8f996b89 811
e43fdd8d 812 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
813 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
814 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
815 return SR_OK;
816 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
817 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
818 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
819 return SR_OK;
820 }
821
822 /* Every other option requires a valid device instance. */
823 if (!sdi || !(devc = sdi->priv))
824 return SR_ERR_ARG;
825
be60a9e4
BV
826 /* If a probe group is specified, it must be a valid one. */
827 if (probe_group) {
828 if (probe_group != &devc->analog_groups[0]
829 && probe_group != &devc->analog_groups[1]) {
830 sr_err("Invalid probe group specified.");
831 return SR_ERR;
832 }
833 }
834
e43fdd8d 835 switch (key) {
9a6517d1 836 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
837 if (!probe_group) {
838 sr_err("No probe group specified.");
839 return SR_ERR_PROBE_GROUP;
840 }
e43fdd8d 841 if (probe_group == &devc->digital_group) {
f48e0249
ML
842 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
843 NULL, 0, sizeof(int32_t));
844 return SR_OK;
845 } else {
846 for (i = 0; i < 2; i++) {
847 if (probe_group == &devc->analog_groups[i]) {
848 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
849 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
850 return SR_OK;
851 }
852 }
853 return SR_ERR_NA;
854 }
5f77dffc 855 break;
2a7b113d 856 case SR_CONF_COUPLING:
be60a9e4
BV
857 if (!probe_group) {
858 sr_err("No probe group specified.");
859 return SR_ERR_PROBE_GROUP;
f48e0249 860 }
58f43369
BV
861 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
862 break;
e4f2b2ad 863 case SR_CONF_VDIV:
7cc1a550
ML
864 if (!devc)
865 /* Can't know this until we have the exact model. */
866 return SR_ERR_ARG;
be60a9e4
BV
867 if (!probe_group) {
868 sr_err("No probe group specified.");
869 return SR_ERR_PROBE_GROUP;
861c447b 870 }
58f43369 871 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 872 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
873 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
874 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
875 tuple = g_variant_new_tuple(rational, 2);
876 g_variant_builder_add_value(&gvb, tuple);
877 }
878 *data = g_variant_builder_end(&gvb);
879 break;
41f5bd09 880 case SR_CONF_TIMEBASE:
7cc1a550
ML
881 if (!devc)
882 /* Can't know this until we have the exact model. */
883 return SR_ERR_ARG;
a31b2ccb
AJ
884 if (devc->num_timebases <= 0)
885 return SR_ERR_NA;
861c447b 886 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
887 for (i = 0; i < devc->num_timebases; i++) {
888 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
889 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
890 tuple = g_variant_new_tuple(rational, 2);
891 g_variant_builder_add_value(&gvb, tuple);
892 }
893 *data = g_variant_builder_end(&gvb);
41f5bd09 894 break;
328bafab 895 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
896 if (!devc)
897 /* Can't know this until we have the exact model. */
898 return SR_ERR_ARG;
f6a0ac9f 899 *data = g_variant_new_strv(trigger_sources,
bafd4890 900 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 901 break;
babab622
ML
902 case SR_CONF_DATA_SOURCE:
903 if (!devc)
904 /* Can't know this until we have the exact model. */
905 return SR_ERR_ARG;
569d4dbd
ML
906 switch (devc->model->series->protocol) {
907 case PROTOCOL_V1:
908 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
909 break;
910 case PROTOCOL_V2:
babab622 911 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
912 break;
913 default:
914 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
915 break;
916 }
babab622 917 break;
a1c743fc 918 default:
bd6fbf62 919 return SR_ERR_NA;
a1c743fc
BV
920 }
921
922 return SR_OK;
923}
924
254dd102 925static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 926{
ae1bc1cc 927 struct sr_scpi_dev_inst *scpi;
29d957ce 928 struct dev_context *devc;
254dd102 929 struct sr_probe *probe;
f76c24f6 930 struct sr_datafeed_packet packet;
254dd102 931 GSList *l;
29d957ce 932
e73ffd42
BV
933 if (sdi->status != SR_ST_ACTIVE)
934 return SR_ERR_DEV_CLOSED;
e0b7d23c 935
ae1bc1cc 936 scpi = sdi->conn;
29d957ce
UH
937 devc = sdi->priv;
938
51b294cd
ML
939 devc->num_frames = 0;
940
254dd102
BV
941 for (l = sdi->probes; l; l = l->next) {
942 probe = l->data;
6bb192bc
ML
943 sr_dbg("handling probe %s", probe->name);
944 if (probe->type == SR_PROBE_ANALOG) {
945 if (probe->enabled)
946 devc->enabled_analog_probes = g_slist_append(
947 devc->enabled_analog_probes, probe);
948 if (probe->enabled != devc->analog_channels[probe->index]) {
949 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 950 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", probe->index + 1,
6396b0a7 951 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 952 return SR_ERR;
904fd29b 953 devc->analog_channels[probe->index] = probe->enabled;
6bb192bc
ML
954 }
955 } else if (probe->type == SR_PROBE_LOGIC) {
04e8e01e 956 if (probe->enabled) {
6bb192bc
ML
957 devc->enabled_digital_probes = g_slist_append(
958 devc->enabled_digital_probes, probe);
04e8e01e
ML
959 /* Turn on LA module if currently off. */
960 if (!devc->la_enabled) {
38354d9d 961 if (rigol_ds_config_set(sdi, ":LA:DISP ON") != SR_OK)
04e8e01e
ML
962 return SR_ERR;
963 devc->la_enabled = TRUE;
964 }
965 }
6bb192bc
ML
966 if (probe->enabled != devc->digital_channels[probe->index]) {
967 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 968 if (rigol_ds_config_set(sdi, ":DIG%d:TURN %s", probe->index,
6396b0a7 969 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 970 return SR_ERR;
904fd29b 971 devc->digital_channels[probe->index] = probe->enabled;
6bb192bc 972 }
254dd102
BV
973 }
974 }
1fed20cb 975
6bb192bc 976 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 977 return SR_ERR;
e0b7d23c 978
04e8e01e
ML
979 /* Turn off LA module if on and no digital probes selected. */
980 if (devc->la_enabled && !devc->enabled_digital_probes)
38354d9d 981 if (rigol_ds_config_set(sdi, ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
982 return SR_ERR;
983
e086b750
ML
984 /* Set memory mode. */
985 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
986 sr_err("Data source 'Segmented' not yet supported");
987 return SR_ERR;
988 }
989
990 devc->analog_frame_size = analog_frame_size(sdi);
991 devc->digital_frame_size = digital_frame_size(sdi);
992
569d4dbd
ML
993 switch (devc->model->series->protocol) {
994 case PROTOCOL_V2:
e086b750
ML
995 if (rigol_ds_config_set(sdi, ":ACQ:MDEP LONG") != SR_OK)
996 return SR_ERR;
569d4dbd
ML
997 break;
998 case PROTOCOL_V3:
e086b750
ML
999 /* Apparently for the DS2000 the memory
1000 * depth can only be set in Running state -
1001 * this matches the behaviour of the UI. */
38354d9d 1002 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 1003 return SR_ERR;
e086b750
ML
1004 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1005 devc->analog_frame_size) != SR_OK)
1006 return SR_ERR;
1007 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1008 return SR_ERR;
569d4dbd
ML
1009 break;
1010 default:
1011 break;
1fed20cb
ML
1012 }
1013
e086b750
ML
1014 if (devc->data_source == DATA_SOURCE_LIVE)
1015 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1016 return SR_ERR;
1017
ae1bc1cc 1018 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
1019
1020 /* Send header packet to the session bus. */
29a27196 1021 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 1022
821fbcad
ML
1023 if (devc->enabled_analog_probes)
1024 devc->channel_entry = devc->enabled_analog_probes;
1025 else
1026 devc->channel_entry = devc->enabled_digital_probes;
1027
e086b750
ML
1028 if (rigol_ds_capture_start(sdi) != SR_OK)
1029 return SR_ERR;
f4816ac6 1030
f76c24f6
ML
1031 /* Start of first frame. */
1032 packet.type = SR_DF_FRAME_BEGIN;
1033 sr_session_send(cb_data, &packet);
1034
f4816ac6
ML
1035 return SR_OK;
1036}
1037
254dd102 1038static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 1039{
29d957ce 1040 struct dev_context *devc;
ae1bc1cc 1041 struct sr_scpi_dev_inst *scpi;
b751cf7a 1042 struct sr_datafeed_packet packet;
29d957ce 1043
f4816ac6
ML
1044 (void)cb_data;
1045
29d957ce
UH
1046 devc = sdi->priv;
1047
f4816ac6
ML
1048 if (sdi->status != SR_ST_ACTIVE) {
1049 sr_err("Device inactive, can't stop acquisition.");
1050 return SR_ERR;
1051 }
1052
b751cf7a
ML
1053 /* End of last frame. */
1054 packet.type = SR_DF_END;
1055 sr_session_send(sdi, &packet);
1056
6bb192bc
ML
1057 g_slist_free(devc->enabled_analog_probes);
1058 g_slist_free(devc->enabled_digital_probes);
1059 devc->enabled_analog_probes = NULL;
1060 devc->enabled_digital_probes = NULL;
ae1bc1cc
ML
1061 scpi = sdi->conn;
1062 sr_scpi_source_remove(scpi);
f4816ac6
ML
1063
1064 return SR_OK;
1065}
1066
3086efdd
ML
1067SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1068 .name = "rigol-ds",
1069 .longname = "Rigol DS",
f4816ac6 1070 .api_version = 1,
6078d2c9
UH
1071 .init = init,
1072 .cleanup = cleanup,
1073 .scan = scan,
1074 .dev_list = dev_list,
3b412e3a 1075 .dev_clear = dev_clear,
d62d7ad1 1076 .config_get = config_get,
035a1078 1077 .config_set = config_set,
a1c743fc 1078 .config_list = config_list,
6078d2c9
UH
1079 .dev_open = dev_open,
1080 .dev_close = dev_close,
254dd102
BV
1081 .dev_acquisition_start = dev_acquisition_start,
1082 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1083 .priv = NULL,
1084};