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