]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
scpi: add a generic scan API and implement it in usbtmc and serial transport
[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
17bdda58 272 if (!(scpi = scpi_dev_inst_new(di->priv, resource, serialcomm)))
c3515cea 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 484
83dbd9f0
AJ
485 if (sdi->status != SR_ST_ACTIVE)
486 return SR_ERR_DEV_CLOSED;
464d4936 487
ae1bc1cc 488 scpi = sdi->conn;
22c19688
ML
489 devc = sdi->priv;
490
6e94eb41 491 if (devc->model->series->protocol == PROTOCOL_V2)
38354d9d 492 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 493
ae1bc1cc
ML
494 if (scpi) {
495 if (sr_scpi_close(scpi) < 0)
496 return SR_ERR;
cc9fd2d2
BV
497 sdi->status = SR_ST_INACTIVE;
498 }
f4816ac6
ML
499
500 return SR_OK;
501}
502
6078d2c9 503static int cleanup(void)
f4816ac6 504{
3b412e3a 505 return dev_clear();
f4816ac6
ML
506}
507
5415e602
ML
508static int analog_frame_size(const struct sr_dev_inst *sdi)
509{
510 struct dev_context *devc = sdi->priv;
511 struct sr_probe *probe;
512 int analog_probes = 0;
513 GSList *l;
514
569d4dbd
ML
515 for (l = sdi->probes; l; l = l->next) {
516 probe = l->data;
517 if (probe->type == SR_PROBE_ANALOG && probe->enabled)
518 analog_probes++;
519 }
520
824eb2ac
ML
521 if (analog_probes == 0)
522 return 0;
523
569d4dbd
ML
524 switch (devc->data_source) {
525 case DATA_SOURCE_LIVE:
526 return devc->model->series->live_samples;
527 case DATA_SOURCE_MEMORY:
528 return devc->model->series->buffer_samples / analog_probes;
470140fc 529 default:
569d4dbd 530 return 0;
5415e602
ML
531 }
532}
533
d22250a9
ML
534static int digital_frame_size(const struct sr_dev_inst *sdi)
535{
536 struct dev_context *devc = sdi->priv;
537
569d4dbd
ML
538 switch (devc->data_source) {
539 case DATA_SOURCE_LIVE:
540 return devc->model->series->live_samples * 2;
541 case DATA_SOURCE_MEMORY:
542 return devc->model->series->buffer_samples * 2;
d22250a9
ML
543 default:
544 return 0;
545 }
546}
547
8f996b89
ML
548static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
549 const struct sr_probe_group *probe_group)
d62d7ad1 550{
e43fdd8d 551 struct dev_context *devc;
2b0e4a46
AJ
552 struct sr_probe *probe;
553 const char *tmp_str;
c2b394d5 554 uint64_t samplerate;
2b0e4a46
AJ
555 int analog_channel = -1;
556 float smallest_diff = 0.0000000001;
557 int idx = -1;
558 unsigned i;
d62d7ad1 559
e43fdd8d
BV
560 if (!sdi || !(devc = sdi->priv))
561 return SR_ERR_ARG;
562
be60a9e4 563 /* If a probe group is specified, it must be a valid one. */
c2b394d5 564 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
565 sr_err("Invalid probe group specified.");
566 return SR_ERR;
be60a9e4
BV
567 }
568
2b0e4a46
AJ
569 if (probe_group) {
570 probe = g_slist_nth_data(probe_group->probes, 0);
571 if (!probe)
572 return SR_ERR;
573 if (probe->type == SR_PROBE_ANALOG) {
574 if (probe->name[2] < '1' || probe->name[2] > '4')
575 return SR_ERR;
576 analog_channel = probe->name[2] - '1';
577 }
578 }
579
d62d7ad1
BV
580 switch (id) {
581 case SR_CONF_NUM_TIMEBASE:
569d4dbd 582 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
583 break;
584 case SR_CONF_NUM_VDIV:
72ecba02 585 *data = g_variant_new_int32(NUM_VDIV);
babab622
ML
586 case SR_CONF_DATA_SOURCE:
587 if (devc->data_source == DATA_SOURCE_LIVE)
588 *data = g_variant_new_string("Live");
589 else if (devc->data_source == DATA_SOURCE_MEMORY)
590 *data = g_variant_new_string("Memory");
591 else
592 *data = g_variant_new_string("Segmented");
593 break;
4914dd4b
ML
594 case SR_CONF_SAMPLERATE:
595 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 596 samplerate = analog_frame_size(sdi) /
569d4dbd 597 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 598 *data = g_variant_new_uint64(samplerate);
c2b394d5 599 } else {
4914dd4b 600 return SR_ERR_NA;
c2b394d5 601 }
4914dd4b 602 break;
2b0e4a46
AJ
603 case SR_CONF_TRIGGER_SOURCE:
604 if (!strcmp(devc->trigger_source, "ACL"))
605 tmp_str = "AC Line";
606 else if (!strcmp(devc->trigger_source, "CHAN1"))
607 tmp_str = "CH1";
608 else if (!strcmp(devc->trigger_source, "CHAN2"))
609 tmp_str = "CH2";
610 else if (!strcmp(devc->trigger_source, "CHAN3"))
611 tmp_str = "CH3";
612 else if (!strcmp(devc->trigger_source, "CHAN4"))
613 tmp_str = "CH4";
614 else
615 tmp_str = devc->trigger_source;
616 *data = g_variant_new_string(tmp_str);
617 break;
618 case SR_CONF_TIMEBASE:
619 for (i = 0; i < devc->num_timebases; i++) {
620 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
621 float diff = fabs(devc->timebase - tb);
622 if (diff < smallest_diff) {
623 smallest_diff = diff;
624 idx = i;
625 }
626 }
627 if (idx < 0)
628 return SR_ERR_NA;
629 *data = g_variant_new("(tt)", devc->timebases[idx][0],
630 devc->timebases[idx][1]);
631 break;
632 case SR_CONF_VDIV:
633 if (analog_channel < 0)
634 return SR_ERR_NA;
635 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
636 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
637 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
638 if (diff < smallest_diff) {
639 smallest_diff = diff;
640 idx = i;
641 }
642 }
643 if (idx < 0)
644 return SR_ERR_NA;
645 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
646 break;
647 case SR_CONF_COUPLING:
648 if (analog_channel < 0)
649 return SR_ERR_NA;
650 *data = g_variant_new_string(devc->coupling[analog_channel]);
651 break;
d62d7ad1 652 default:
bd6fbf62 653 return SR_ERR_NA;
d62d7ad1
BV
654 }
655
656 return SR_OK;
657}
658
8f996b89
ML
659static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
660 const struct sr_probe_group *probe_group)
f4816ac6 661{
29d957ce 662 struct dev_context *devc;
ca9b9f48 663 uint64_t p, q;
254dd102 664 double t_dbl;
f48e0249 665 unsigned int i, j;
254dd102
BV
666 int ret;
667 const char *tmp_str;
889ef4a0 668 char buffer[16];
f4816ac6 669
e43fdd8d
BV
670 if (!(devc = sdi->priv))
671 return SR_ERR_ARG;
29d957ce 672
e73ffd42
BV
673 if (sdi->status != SR_ST_ACTIVE)
674 return SR_ERR_DEV_CLOSED;
f4816ac6 675
be60a9e4 676 /* If a probe group is specified, it must be a valid one. */
c2b394d5 677 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
678 sr_err("Invalid probe group specified.");
679 return SR_ERR;
be60a9e4
BV
680 }
681
f4816ac6 682 ret = SR_OK;
035a1078 683 switch (id) {
1953564a 684 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 685 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 686 break;
1953564a 687 case SR_CONF_TRIGGER_SLOPE:
ca9b9f48
DE
688 tmp_str = g_variant_get_string(data, NULL);
689
690 if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r'))
691 return SR_ERR_ARG;
692
254dd102 693 g_free(devc->trigger_slope);
ca9b9f48 694 devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
38354d9d 695 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 696 break;
1953564a 697 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
698 t_dbl = g_variant_get_double(data);
699 if (t_dbl < 0.0 || t_dbl > 1.0)
700 return SR_ERR;
701 devc->horiz_triggerpos = t_dbl;
702 /* We have the trigger offset as a percentage of the frame, but
703 * need to express this in seconds. */
bafd4890 704 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 705 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 706 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 707 break;
1953564a 708 case SR_CONF_TIMEBASE:
f6a0ac9f 709 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
710 for (i = 0; i < devc->num_timebases; i++) {
711 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 712 devc->timebase = (float)p / q;
889ef4a0
AJ
713 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
714 devc->timebase);
38354d9d 715 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
716 break;
717 }
718 }
bafd4890 719 if (i == devc->num_timebases)
254dd102 720 ret = SR_ERR_ARG;
e0b7d23c 721 break;
1953564a 722 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 723 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
724 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
725 if (!strcmp(trigger_sources[i], tmp_str)) {
726 g_free(devc->trigger_source);
727 devc->trigger_source = g_strdup(trigger_sources[i]);
728 if (!strcmp(devc->trigger_source, "AC Line"))
729 tmp_str = "ACL";
730 else if (!strcmp(devc->trigger_source, "CH1"))
731 tmp_str = "CHAN1";
732 else if (!strcmp(devc->trigger_source, "CH2"))
733 tmp_str = "CHAN2";
821fbcad
ML
734 else if (!strcmp(devc->trigger_source, "CH3"))
735 tmp_str = "CHAN3";
736 else if (!strcmp(devc->trigger_source, "CH4"))
737 tmp_str = "CHAN4";
254dd102
BV
738 else
739 tmp_str = (char *)devc->trigger_source;
38354d9d 740 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
741 break;
742 }
4e108ace 743 }
254dd102
BV
744 if (i == ARRAY_SIZE(trigger_sources))
745 ret = SR_ERR_ARG;
e0b7d23c 746 break;
1953564a 747 case SR_CONF_VDIV:
be60a9e4
BV
748 if (!probe_group) {
749 sr_err("No probe group specified.");
750 return SR_ERR_PROBE_GROUP;
751 }
f6a0ac9f 752 g_variant_get(data, "(tt)", &p, &q);
f48e0249 753 for (i = 0; i < 2; i++) {
78bcc55a
BV
754 if (probe_group == &devc->analog_groups[i]) {
755 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
756 if (vdivs[j][0] != p || vdivs[j][1] != q)
757 continue;
758 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
759 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
760 devc->vdiv[i]);
38354d9d 761 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 762 buffer);
f48e0249
ML
763 }
764 return SR_ERR_ARG;
765 }
e0b7d23c 766 }
f48e0249 767 return SR_ERR_NA;
1953564a 768 case SR_CONF_COUPLING:
78bcc55a
BV
769 if (!probe_group) {
770 sr_err("No probe group specified.");
771 return SR_ERR_PROBE_GROUP;
772 }
f6a0ac9f 773 tmp_str = g_variant_get_string(data, NULL);
f48e0249 774 for (i = 0; i < 2; i++) {
78bcc55a
BV
775 if (probe_group == &devc->analog_groups[i]) {
776 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
777 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
778 g_free(devc->coupling[i]);
779 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 780 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
781 devc->coupling[i]);
782 }
783 }
784 return SR_ERR_ARG;
e0b7d23c
ML
785 }
786 }
f48e0249 787 return SR_ERR_NA;
babab622
ML
788 case SR_CONF_DATA_SOURCE:
789 tmp_str = g_variant_get_string(data, NULL);
790 if (!strcmp(tmp_str, "Live"))
791 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
792 else if (devc->model->series->protocol >= PROTOCOL_V2
793 && !strcmp(tmp_str, "Memory"))
babab622 794 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 795 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
796 && !strcmp(tmp_str, "Segmented"))
797 devc->data_source = DATA_SOURCE_SEGMENTED;
798 else
799 return SR_ERR;
800 break;
f4816ac6 801 default:
bd6fbf62 802 ret = SR_ERR_NA;
29d957ce 803 break;
f4816ac6
ML
804 }
805
806 return ret;
807}
808
8f996b89
ML
809static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
810 const struct sr_probe_group *probe_group)
a1c743fc 811{
861c447b
BV
812 GVariant *tuple, *rational[2];
813 GVariantBuilder gvb;
814 unsigned int i;
7cc1a550
ML
815 struct dev_context *devc = NULL;
816
817 if (sdi)
818 devc = sdi->priv;
8f996b89 819
e43fdd8d 820 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
821 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
822 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
823 return SR_OK;
824 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
825 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
826 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
827 return SR_OK;
828 }
829
830 /* Every other option requires a valid device instance. */
831 if (!sdi || !(devc = sdi->priv))
832 return SR_ERR_ARG;
833
be60a9e4
BV
834 /* If a probe group is specified, it must be a valid one. */
835 if (probe_group) {
836 if (probe_group != &devc->analog_groups[0]
837 && probe_group != &devc->analog_groups[1]) {
838 sr_err("Invalid probe group specified.");
839 return SR_ERR;
840 }
841 }
842
e43fdd8d 843 switch (key) {
9a6517d1 844 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
845 if (!probe_group) {
846 sr_err("No probe group specified.");
847 return SR_ERR_PROBE_GROUP;
848 }
e43fdd8d 849 if (probe_group == &devc->digital_group) {
f48e0249
ML
850 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
851 NULL, 0, sizeof(int32_t));
852 return SR_OK;
853 } else {
854 for (i = 0; i < 2; i++) {
855 if (probe_group == &devc->analog_groups[i]) {
856 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
857 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
858 return SR_OK;
859 }
860 }
861 return SR_ERR_NA;
862 }
5f77dffc 863 break;
2a7b113d 864 case SR_CONF_COUPLING:
be60a9e4
BV
865 if (!probe_group) {
866 sr_err("No probe group specified.");
867 return SR_ERR_PROBE_GROUP;
f48e0249 868 }
58f43369
BV
869 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
870 break;
e4f2b2ad 871 case SR_CONF_VDIV:
7cc1a550
ML
872 if (!devc)
873 /* Can't know this until we have the exact model. */
874 return SR_ERR_ARG;
be60a9e4
BV
875 if (!probe_group) {
876 sr_err("No probe group specified.");
877 return SR_ERR_PROBE_GROUP;
861c447b 878 }
58f43369 879 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 880 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
881 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
882 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
883 tuple = g_variant_new_tuple(rational, 2);
884 g_variant_builder_add_value(&gvb, tuple);
885 }
886 *data = g_variant_builder_end(&gvb);
887 break;
41f5bd09 888 case SR_CONF_TIMEBASE:
7cc1a550
ML
889 if (!devc)
890 /* Can't know this until we have the exact model. */
891 return SR_ERR_ARG;
a31b2ccb
AJ
892 if (devc->num_timebases <= 0)
893 return SR_ERR_NA;
861c447b 894 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
895 for (i = 0; i < devc->num_timebases; i++) {
896 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
897 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
898 tuple = g_variant_new_tuple(rational, 2);
899 g_variant_builder_add_value(&gvb, tuple);
900 }
901 *data = g_variant_builder_end(&gvb);
41f5bd09 902 break;
328bafab 903 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
904 if (!devc)
905 /* Can't know this until we have the exact model. */
906 return SR_ERR_ARG;
f6a0ac9f 907 *data = g_variant_new_strv(trigger_sources,
bafd4890 908 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 909 break;
babab622
ML
910 case SR_CONF_DATA_SOURCE:
911 if (!devc)
912 /* Can't know this until we have the exact model. */
913 return SR_ERR_ARG;
569d4dbd
ML
914 switch (devc->model->series->protocol) {
915 case PROTOCOL_V1:
916 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
917 break;
918 case PROTOCOL_V2:
babab622 919 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
920 break;
921 default:
922 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
923 break;
924 }
babab622 925 break;
a1c743fc 926 default:
bd6fbf62 927 return SR_ERR_NA;
a1c743fc
BV
928 }
929
930 return SR_OK;
931}
932
254dd102 933static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 934{
ae1bc1cc 935 struct sr_scpi_dev_inst *scpi;
29d957ce 936 struct dev_context *devc;
254dd102 937 struct sr_probe *probe;
f76c24f6 938 struct sr_datafeed_packet packet;
254dd102 939 GSList *l;
29d957ce 940
e73ffd42
BV
941 if (sdi->status != SR_ST_ACTIVE)
942 return SR_ERR_DEV_CLOSED;
e0b7d23c 943
ae1bc1cc 944 scpi = sdi->conn;
29d957ce
UH
945 devc = sdi->priv;
946
51b294cd
ML
947 devc->num_frames = 0;
948
254dd102
BV
949 for (l = sdi->probes; l; l = l->next) {
950 probe = l->data;
6bb192bc
ML
951 sr_dbg("handling probe %s", probe->name);
952 if (probe->type == SR_PROBE_ANALOG) {
953 if (probe->enabled)
954 devc->enabled_analog_probes = g_slist_append(
955 devc->enabled_analog_probes, probe);
956 if (probe->enabled != devc->analog_channels[probe->index]) {
957 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 958 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", probe->index + 1,
6396b0a7 959 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 960 return SR_ERR;
904fd29b 961 devc->analog_channels[probe->index] = probe->enabled;
6bb192bc
ML
962 }
963 } else if (probe->type == SR_PROBE_LOGIC) {
04e8e01e 964 if (probe->enabled) {
6bb192bc
ML
965 devc->enabled_digital_probes = g_slist_append(
966 devc->enabled_digital_probes, probe);
04e8e01e
ML
967 /* Turn on LA module if currently off. */
968 if (!devc->la_enabled) {
38354d9d 969 if (rigol_ds_config_set(sdi, ":LA:DISP ON") != SR_OK)
04e8e01e
ML
970 return SR_ERR;
971 devc->la_enabled = TRUE;
972 }
973 }
6bb192bc
ML
974 if (probe->enabled != devc->digital_channels[probe->index]) {
975 /* Enabled channel is currently disabled, or vice versa. */
38354d9d 976 if (rigol_ds_config_set(sdi, ":DIG%d:TURN %s", probe->index,
6396b0a7 977 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 978 return SR_ERR;
904fd29b 979 devc->digital_channels[probe->index] = probe->enabled;
6bb192bc 980 }
254dd102
BV
981 }
982 }
1fed20cb 983
6bb192bc 984 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 985 return SR_ERR;
e0b7d23c 986
04e8e01e
ML
987 /* Turn off LA module if on and no digital probes selected. */
988 if (devc->la_enabled && !devc->enabled_digital_probes)
38354d9d 989 if (rigol_ds_config_set(sdi, ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
990 return SR_ERR;
991
e086b750
ML
992 /* Set memory mode. */
993 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
994 sr_err("Data source 'Segmented' not yet supported");
995 return SR_ERR;
996 }
997
998 devc->analog_frame_size = analog_frame_size(sdi);
999 devc->digital_frame_size = digital_frame_size(sdi);
1000
569d4dbd
ML
1001 switch (devc->model->series->protocol) {
1002 case PROTOCOL_V2:
e086b750
ML
1003 if (rigol_ds_config_set(sdi, ":ACQ:MDEP LONG") != SR_OK)
1004 return SR_ERR;
569d4dbd
ML
1005 break;
1006 case PROTOCOL_V3:
e086b750
ML
1007 /* Apparently for the DS2000 the memory
1008 * depth can only be set in Running state -
1009 * this matches the behaviour of the UI. */
38354d9d 1010 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 1011 return SR_ERR;
e086b750
ML
1012 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1013 devc->analog_frame_size) != SR_OK)
1014 return SR_ERR;
1015 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1016 return SR_ERR;
569d4dbd
ML
1017 break;
1018 default:
1019 break;
1fed20cb
ML
1020 }
1021
e086b750
ML
1022 if (devc->data_source == DATA_SOURCE_LIVE)
1023 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1024 return SR_ERR;
1025
ae1bc1cc 1026 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
1027
1028 /* Send header packet to the session bus. */
29a27196 1029 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 1030
821fbcad
ML
1031 if (devc->enabled_analog_probes)
1032 devc->channel_entry = devc->enabled_analog_probes;
1033 else
1034 devc->channel_entry = devc->enabled_digital_probes;
1035
e086b750
ML
1036 if (rigol_ds_capture_start(sdi) != SR_OK)
1037 return SR_ERR;
f4816ac6 1038
f76c24f6
ML
1039 /* Start of first frame. */
1040 packet.type = SR_DF_FRAME_BEGIN;
1041 sr_session_send(cb_data, &packet);
1042
f4816ac6
ML
1043 return SR_OK;
1044}
1045
254dd102 1046static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 1047{
29d957ce 1048 struct dev_context *devc;
ae1bc1cc 1049 struct sr_scpi_dev_inst *scpi;
b751cf7a 1050 struct sr_datafeed_packet packet;
29d957ce 1051
f4816ac6
ML
1052 (void)cb_data;
1053
29d957ce
UH
1054 devc = sdi->priv;
1055
f4816ac6
ML
1056 if (sdi->status != SR_ST_ACTIVE) {
1057 sr_err("Device inactive, can't stop acquisition.");
1058 return SR_ERR;
1059 }
1060
b751cf7a
ML
1061 /* End of last frame. */
1062 packet.type = SR_DF_END;
1063 sr_session_send(sdi, &packet);
1064
6bb192bc
ML
1065 g_slist_free(devc->enabled_analog_probes);
1066 g_slist_free(devc->enabled_digital_probes);
1067 devc->enabled_analog_probes = NULL;
1068 devc->enabled_digital_probes = NULL;
ae1bc1cc
ML
1069 scpi = sdi->conn;
1070 sr_scpi_source_remove(scpi);
f4816ac6
ML
1071
1072 return SR_OK;
1073}
1074
3086efdd
ML
1075SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1076 .name = "rigol-ds",
1077 .longname = "Rigol DS",
f4816ac6 1078 .api_version = 1,
6078d2c9
UH
1079 .init = init,
1080 .cleanup = cleanup,
1081 .scan = scan,
1082 .dev_list = dev_list,
3b412e3a 1083 .dev_clear = dev_clear,
d62d7ad1 1084 .config_get = config_get,
035a1078 1085 .config_set = config_set,
a1c743fc 1086 .config_list = config_list,
6078d2c9
UH
1087 .dev_open = dev_open,
1088 .dev_close = dev_close,
254dd102
BV
1089 .dev_acquisition_start = dev_acquisition_start,
1090 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1091 .priv = NULL,
1092};