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