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