]> sigrok.org Git - libsigrok.git/blame - src/hardware/rigol-ds/api.c
config_list: Don't check for sdi->priv != NULL.
[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
9d3ae01b 275static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
f4816ac6 276{
cc9fd2d2
BV
277 struct dev_context *devc;
278 struct sr_dev_inst *sdi;
ae1bc1cc 279 struct sr_scpi_hw_info *hw_info;
ba7dd8bb 280 struct sr_channel *ch;
8dd0b290 281 long n[3];
f6a0ac9f 282 unsigned int i;
bafd4890 283 const struct rigol_ds_model *model = NULL;
569d4dbd 284 gchar *channel_name, **version;
fb6e5ba8 285
ae1bc1cc 286 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
05238d28
ML
287 sr_info("Couldn't get IDN response, retrying.");
288 sr_scpi_close(scpi);
289 sr_scpi_open(scpi);
290 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
291 sr_info("Couldn't get IDN response.");
292 return NULL;
293 }
ca55277c 294 }
e0b7d23c 295
ca55277c 296 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
34577da6 297 if (!g_ascii_strcasecmp(hw_info->manufacturer,
569d4dbd 298 supported_models[i].series->vendor->full_name) &&
10afee13 299 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 300 model = &supported_models[i];
ca55277c 301 break;
fb6e5ba8 302 }
ca55277c 303 }
fb6e5ba8 304
0af636be 305 if (!model) {
ae1bc1cc 306 sr_scpi_hw_info_free(hw_info);
9d3ae01b 307 return NULL;
ca55277c 308 }
fb6e5ba8 309
aac29cc1 310 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be
UH
311 sdi->vendor = g_strdup(model->series->vendor->name);
312 sdi->model = g_strdup(model->name);
313 sdi->version = g_strdup(hw_info->firmware_version);
ae1bc1cc 314 sdi->conn = scpi;
4f840ce9 315 sdi->driver = &rigol_ds_driver_info;
ae1bc1cc 316 sdi->inst_type = SR_INST_SCPI;
b3fccc85 317 sdi->serial_num = g_strdup(hw_info->serial_number);
f57d8ffe 318 devc = g_malloc0(sizeof(struct dev_context));
cc9fd2d2 319 devc->limit_frames = 0;
bafd4890 320 devc->model = model;
569d4dbd 321 devc->format = model->series->format;
8dd0b290 322
569d4dbd
ML
323 /* DS1000 models with firmware before 0.2.4 used the old data format. */
324 if (model->series == SERIES(DS1000)) {
8dd0b290
BV
325 version = g_strsplit(hw_info->firmware_version, ".", 0);
326 do {
327 if (!version[0] || !version[1] || !version[2])
328 break;
329 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
330 break;
331 for (i = 0; i < 3; i++) {
332 if (sr_atol(version[i], &n[i]) != SR_OK)
333 break;
334 }
335 if (i != 3)
336 break;
de285cce
BV
337 scpi->firmware_version = n[0] * 100 + n[1] * 10 + n[2];
338 if (scpi->firmware_version < 24) {
339 sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format.");
340 devc->format = FORMAT_RAW;
341 }
342 break;
0c5f2abc 343 } while (0);
8dd0b290
BV
344 g_strfreev(version);
345 }
346
347 sr_scpi_hw_info_free(hw_info);
512bb890 348
562b7ae5
SA
349 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
350 model->analog_channels);
351
821fbcad 352 for (i = 0; i < model->analog_channels; i++) {
eac0c613 353 channel_name = g_strdup_printf("CH%d", i + 1);
5e23fcab 354 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_name);
562b7ae5
SA
355
356 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
357
358 devc->analog_groups[i]->name = channel_name;
359 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
660e398f 360 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 361 devc->analog_groups[i]);
ca55277c 362 }
512bb890 363
bafd4890 364 if (devc->model->has_digital) {
16aca766 365 devc->digital_group = g_malloc0(sizeof(struct sr_channel_group));
562b7ae5 366
effb9dd1 367 for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
eac0c613 368 channel_name = g_strdup_printf("D%d", i);
5e23fcab 369 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ca55277c 370 g_free(channel_name);
562b7ae5
SA
371 devc->digital_group->channels = g_slist_append(
372 devc->digital_group->channels, ch);
512bb890 373 }
562b7ae5 374 devc->digital_group->name = g_strdup("LA");
660e398f 375 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 376 devc->digital_group);
ca55277c 377 }
bafd4890
ML
378
379 for (i = 0; i < NUM_TIMEBASE; i++) {
380 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
381 devc->timebases = &timebases[i];
569d4dbd 382 if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
bafd4890
ML
383 devc->num_timebases = &timebases[i] - devc->timebases + 1;
384 }
385
a95f142e
UH
386 for (i = 0; i < NUM_VDIV; i++) {
387 if (!memcmp(&devc->model->series->min_vdiv,
388 &vdivs[i], sizeof(uint64_t[2]))) {
6ff1394e 389 devc->vdivs = &vdivs[i];
81b85663
AJ
390 devc->num_vdivs = NUM_VDIV - i;
391 }
a95f142e 392 }
bafd4890 393
a95f142e
UH
394 devc->buffer = g_malloc(ACQ_BUFFER_SIZE);
395 devc->data = g_malloc(ACQ_BUFFER_SIZE * sizeof(float));
babab622
ML
396
397 devc->data_source = DATA_SOURCE_LIVE;
398
cc9fd2d2
BV
399 sdi->priv = devc;
400
9d3ae01b 401 return sdi;
ca55277c 402}
512bb890 403
4f840ce9 404static GSList *scan(struct sr_dev_driver *di, GSList *options)
ca55277c 405{
41812aca 406 return sr_scpi_scan(di->context, options, probe_device);
f4816ac6
ML
407}
408
6078d2c9 409static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 410{
e1b5b7e7 411 int ret;
ae1bc1cc 412 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 413
e1b5b7e7
UH
414 if ((ret = sr_scpi_open(scpi)) < 0) {
415 sr_err("Failed to open SCPI device: %s.", sr_strerror(ret));
e0b7d23c 416 return SR_ERR;
e1b5b7e7 417 }
e0b7d23c 418
e1b5b7e7
UH
419 if ((ret = rigol_ds_get_dev_cfg(sdi)) < 0) {
420 sr_err("Failed to get device config: %s.", sr_strerror(ret));
254dd102 421 return SR_ERR;
e1b5b7e7 422 }
f4816ac6 423
46a743c1 424 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 425
f4816ac6
ML
426 return SR_OK;
427}
428
6078d2c9 429static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 430{
ae1bc1cc 431 struct sr_scpi_dev_inst *scpi;
22c19688 432 struct dev_context *devc;
ae1bc1cc 433
83dbd9f0
AJ
434 if (sdi->status != SR_ST_ACTIVE)
435 return SR_ERR_DEV_CLOSED;
464d4936 436
ae1bc1cc 437 scpi = sdi->conn;
22c19688
ML
438 devc = sdi->priv;
439
6e94eb41 440 if (devc->model->series->protocol == PROTOCOL_V2)
38354d9d 441 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
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
5415e602
ML
452static int analog_frame_size(const struct sr_dev_inst *sdi)
453{
454 struct dev_context *devc = sdi->priv;
ba7dd8bb
UH
455 struct sr_channel *ch;
456 int analog_channels = 0;
5415e602
ML
457 GSList *l;
458
ba7dd8bb
UH
459 for (l = sdi->channels; l; l = l->next) {
460 ch = l->data;
3f239f08 461 if (ch->type == SR_CHANNEL_ANALOG && ch->enabled)
ba7dd8bb 462 analog_channels++;
569d4dbd
ML
463 }
464
ba7dd8bb 465 if (analog_channels == 0)
824eb2ac
ML
466 return 0;
467
569d4dbd
ML
468 switch (devc->data_source) {
469 case DATA_SOURCE_LIVE:
470 return devc->model->series->live_samples;
471 case DATA_SOURCE_MEMORY:
ba7dd8bb 472 return devc->model->series->buffer_samples / analog_channels;
470140fc 473 default:
569d4dbd 474 return 0;
5415e602
ML
475 }
476}
477
d22250a9
ML
478static int digital_frame_size(const struct sr_dev_inst *sdi)
479{
480 struct dev_context *devc = sdi->priv;
481
569d4dbd
ML
482 switch (devc->data_source) {
483 case DATA_SOURCE_LIVE:
484 return devc->model->series->live_samples * 2;
485 case DATA_SOURCE_MEMORY:
486 return devc->model->series->buffer_samples * 2;
d22250a9
ML
487 default:
488 return 0;
489 }
490}
491
584560f1 492static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 493 const struct sr_channel_group *cg)
d62d7ad1 494{
e43fdd8d 495 struct dev_context *devc;
ba7dd8bb 496 struct sr_channel *ch;
2b0e4a46 497 const char *tmp_str;
c2b394d5 498 uint64_t samplerate;
2b0e4a46 499 int analog_channel = -1;
c33ff377 500 float smallest_diff = INFINITY;
2b0e4a46
AJ
501 int idx = -1;
502 unsigned i;
d62d7ad1 503
709468ba 504 if (!sdi)
e43fdd8d
BV
505 return SR_ERR_ARG;
506
709468ba
UH
507 devc = sdi->priv;
508
660e398f 509 /* If a channel group is specified, it must be a valid one. */
53b4680f 510 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 511 sr_err("Invalid channel group specified.");
969edf63 512 return SR_ERR;
be60a9e4
BV
513 }
514
53b4680f 515 if (cg) {
ba7dd8bb
UH
516 ch = g_slist_nth_data(cg->channels, 0);
517 if (!ch)
2b0e4a46 518 return SR_ERR;
3f239f08 519 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 520 if (ch->name[2] < '1' || ch->name[2] > '4')
2b0e4a46 521 return SR_ERR;
ba7dd8bb 522 analog_channel = ch->name[2] - '1';
2b0e4a46
AJ
523 }
524 }
525
584560f1 526 switch (key) {
bf622e6d 527 case SR_CONF_NUM_HDIV:
569d4dbd 528 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
529 break;
530 case SR_CONF_NUM_VDIV:
81b85663 531 *data = g_variant_new_int32(devc->num_vdivs);
f44f7e61 532 break;
babab622
ML
533 case SR_CONF_DATA_SOURCE:
534 if (devc->data_source == DATA_SOURCE_LIVE)
535 *data = g_variant_new_string("Live");
536 else if (devc->data_source == DATA_SOURCE_MEMORY)
537 *data = g_variant_new_string("Memory");
538 else
539 *data = g_variant_new_string("Segmented");
540 break;
4914dd4b
ML
541 case SR_CONF_SAMPLERATE:
542 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 543 samplerate = analog_frame_size(sdi) /
569d4dbd 544 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 545 *data = g_variant_new_uint64(samplerate);
c2b394d5 546 } else {
e1b5b7e7 547 sr_dbg("Unknown data source: %d.", devc->data_source);
4914dd4b 548 return SR_ERR_NA;
c2b394d5 549 }
4914dd4b 550 break;
2b0e4a46
AJ
551 case SR_CONF_TRIGGER_SOURCE:
552 if (!strcmp(devc->trigger_source, "ACL"))
553 tmp_str = "AC Line";
554 else if (!strcmp(devc->trigger_source, "CHAN1"))
555 tmp_str = "CH1";
556 else if (!strcmp(devc->trigger_source, "CHAN2"))
557 tmp_str = "CH2";
558 else if (!strcmp(devc->trigger_source, "CHAN3"))
559 tmp_str = "CH3";
560 else if (!strcmp(devc->trigger_source, "CHAN4"))
561 tmp_str = "CH4";
562 else
563 tmp_str = devc->trigger_source;
564 *data = g_variant_new_string(tmp_str);
565 break;
5d336f11 566 case SR_CONF_TRIGGER_SLOPE:
e1b5b7e7 567 if (!strncmp(devc->trigger_slope, "POS", 3)) {
5d336f11 568 tmp_str = "r";
e1b5b7e7 569 } else if (!strncmp(devc->trigger_slope, "NEG", 3)) {
5d336f11 570 tmp_str = "f";
e1b5b7e7
UH
571 } else {
572 sr_dbg("Unknown trigger slope: '%s'.", devc->trigger_slope);
5d336f11 573 return SR_ERR_NA;
e1b5b7e7 574 }
5d336f11
AJ
575 *data = g_variant_new_string(tmp_str);
576 break;
2b0e4a46
AJ
577 case SR_CONF_TIMEBASE:
578 for (i = 0; i < devc->num_timebases; i++) {
579 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
580 float diff = fabs(devc->timebase - tb);
581 if (diff < smallest_diff) {
582 smallest_diff = diff;
583 idx = i;
584 }
585 }
e1b5b7e7
UH
586 if (idx < 0) {
587 sr_dbg("Negative timebase index: %d.", idx);
2b0e4a46 588 return SR_ERR_NA;
e1b5b7e7 589 }
2b0e4a46
AJ
590 *data = g_variant_new("(tt)", devc->timebases[idx][0],
591 devc->timebases[idx][1]);
592 break;
593 case SR_CONF_VDIV:
e1b5b7e7
UH
594 if (analog_channel < 0) {
595 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 596 return SR_ERR_NA;
e1b5b7e7 597 }
2b0e4a46
AJ
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 }
e1b5b7e7
UH
606 if (idx < 0) {
607 sr_dbg("Negative vdiv index: %d.", idx);
2b0e4a46 608 return SR_ERR_NA;
e1b5b7e7 609 }
2b0e4a46
AJ
610 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
611 break;
612 case SR_CONF_COUPLING:
e1b5b7e7
UH
613 if (analog_channel < 0) {
614 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 615 return SR_ERR_NA;
e1b5b7e7 616 }
2b0e4a46
AJ
617 *data = g_variant_new_string(devc->coupling[analog_channel]);
618 break;
d62d7ad1 619 default:
bd6fbf62 620 return SR_ERR_NA;
d62d7ad1
BV
621 }
622
623 return SR_OK;
624}
625
584560f1 626static int config_set(uint32_t key, GVariant *data, const struct sr_dev_inst *sdi,
53b4680f 627 const struct sr_channel_group *cg)
f4816ac6 628{
29d957ce 629 struct dev_context *devc;
ca9b9f48 630 uint64_t p, q;
254dd102 631 double t_dbl;
f48e0249 632 unsigned int i, j;
254dd102
BV
633 int ret;
634 const char *tmp_str;
889ef4a0 635 char buffer[16];
f4816ac6 636
b0baddef 637 devc = sdi->priv;
29d957ce 638
e73ffd42
BV
639 if (sdi->status != SR_ST_ACTIVE)
640 return SR_ERR_DEV_CLOSED;
f4816ac6 641
660e398f 642 /* If a channel group is specified, it must be a valid one. */
53b4680f 643 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 644 sr_err("Invalid channel group specified.");
969edf63 645 return SR_ERR;
be60a9e4
BV
646 }
647
f4816ac6 648 ret = SR_OK;
584560f1 649 switch (key) {
1953564a 650 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 651 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 652 break;
1953564a 653 case SR_CONF_TRIGGER_SLOPE:
ca9b9f48
DE
654 tmp_str = g_variant_get_string(data, NULL);
655
e1b5b7e7
UH
656 if (!tmp_str || !(tmp_str[0] == 'f' || tmp_str[0] == 'r')) {
657 sr_err("Unknown trigger slope: '%s'.",
658 (tmp_str) ? tmp_str : "NULL");
ca9b9f48 659 return SR_ERR_ARG;
e1b5b7e7 660 }
ca9b9f48 661
254dd102 662 g_free(devc->trigger_slope);
ca9b9f48 663 devc->trigger_slope = g_strdup((tmp_str[0] == 'r') ? "POS" : "NEG");
38354d9d 664 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 665 break;
1953564a 666 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102 667 t_dbl = g_variant_get_double(data);
e1b5b7e7
UH
668 if (t_dbl < 0.0 || t_dbl > 1.0) {
669 sr_err("Invalid horiz. trigger position: %g.", t_dbl);
254dd102 670 return SR_ERR;
e1b5b7e7 671 }
254dd102
BV
672 devc->horiz_triggerpos = t_dbl;
673 /* We have the trigger offset as a percentage of the frame, but
674 * need to express this in seconds. */
bafd4890 675 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0 676 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
38354d9d 677 ret = rigol_ds_config_set(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 678 break;
1953564a 679 case SR_CONF_TIMEBASE:
f6a0ac9f 680 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
681 for (i = 0; i < devc->num_timebases; i++) {
682 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 683 devc->timebase = (float)p / q;
889ef4a0
AJ
684 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
685 devc->timebase);
38354d9d 686 ret = rigol_ds_config_set(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
687 break;
688 }
689 }
e1b5b7e7
UH
690 if (i == devc->num_timebases) {
691 sr_err("Invalid timebase index: %d.", i);
254dd102 692 ret = SR_ERR_ARG;
e1b5b7e7 693 }
e0b7d23c 694 break;
1953564a 695 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 696 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
697 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
698 if (!strcmp(trigger_sources[i], tmp_str)) {
699 g_free(devc->trigger_source);
700 devc->trigger_source = g_strdup(trigger_sources[i]);
701 if (!strcmp(devc->trigger_source, "AC Line"))
702 tmp_str = "ACL";
703 else if (!strcmp(devc->trigger_source, "CH1"))
704 tmp_str = "CHAN1";
705 else if (!strcmp(devc->trigger_source, "CH2"))
706 tmp_str = "CHAN2";
821fbcad
ML
707 else if (!strcmp(devc->trigger_source, "CH3"))
708 tmp_str = "CHAN3";
709 else if (!strcmp(devc->trigger_source, "CH4"))
710 tmp_str = "CHAN4";
254dd102
BV
711 else
712 tmp_str = (char *)devc->trigger_source;
38354d9d 713 ret = rigol_ds_config_set(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
254dd102
BV
714 break;
715 }
4e108ace 716 }
e1b5b7e7
UH
717 if (i == ARRAY_SIZE(trigger_sources)) {
718 sr_err("Invalid trigger source index: %d.", i);
254dd102 719 ret = SR_ERR_ARG;
e1b5b7e7 720 }
e0b7d23c 721 break;
1953564a 722 case SR_CONF_VDIV:
53b4680f 723 if (!cg) {
660e398f
UH
724 sr_err("No channel group specified.");
725 return SR_ERR_CHANNEL_GROUP;
be60a9e4 726 }
f6a0ac9f 727 g_variant_get(data, "(tt)", &p, &q);
effb9dd1 728 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 729 if (cg == devc->analog_groups[i]) {
78bcc55a 730 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
731 if (vdivs[j][0] != p || vdivs[j][1] != q)
732 continue;
733 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
734 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
735 devc->vdiv[i]);
38354d9d 736 return rigol_ds_config_set(sdi, ":CHAN%d:SCAL %s", i + 1,
889ef4a0 737 buffer);
f48e0249 738 }
e1b5b7e7 739 sr_err("Invalid vdiv index: %d.", j);
f48e0249
ML
740 return SR_ERR_ARG;
741 }
e0b7d23c 742 }
e1b5b7e7 743 sr_dbg("Didn't set vdiv, unknown channel(group).");
f48e0249 744 return SR_ERR_NA;
1953564a 745 case SR_CONF_COUPLING:
53b4680f 746 if (!cg) {
660e398f
UH
747 sr_err("No channel group specified.");
748 return SR_ERR_CHANNEL_GROUP;
78bcc55a 749 }
f6a0ac9f 750 tmp_str = g_variant_get_string(data, NULL);
effb9dd1 751 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 752 if (cg == devc->analog_groups[i]) {
78bcc55a
BV
753 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
754 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
755 g_free(devc->coupling[i]);
756 devc->coupling[i] = g_strdup(coupling[j]);
38354d9d 757 return rigol_ds_config_set(sdi, ":CHAN%d:COUP %s", i + 1,
f48e0249
ML
758 devc->coupling[i]);
759 }
760 }
e1b5b7e7 761 sr_err("Invalid coupling index: %d.", j);
f48e0249 762 return SR_ERR_ARG;
e0b7d23c
ML
763 }
764 }
e1b5b7e7 765 sr_dbg("Didn't set coupling, unknown channel(group).");
f48e0249 766 return SR_ERR_NA;
babab622
ML
767 case SR_CONF_DATA_SOURCE:
768 tmp_str = g_variant_get_string(data, NULL);
769 if (!strcmp(tmp_str, "Live"))
770 devc->data_source = DATA_SOURCE_LIVE;
569d4dbd
ML
771 else if (devc->model->series->protocol >= PROTOCOL_V2
772 && !strcmp(tmp_str, "Memory"))
babab622 773 devc->data_source = DATA_SOURCE_MEMORY;
569d4dbd 774 else if (devc->model->series->protocol >= PROTOCOL_V3
babab622
ML
775 && !strcmp(tmp_str, "Segmented"))
776 devc->data_source = DATA_SOURCE_SEGMENTED;
e1b5b7e7
UH
777 else {
778 sr_err("Unknown data source: '%s'.", tmp_str);
babab622 779 return SR_ERR;
e1b5b7e7 780 }
babab622 781 break;
f4816ac6 782 default:
dcd438ee 783 return SR_ERR_NA;
f4816ac6
ML
784 }
785
786 return ret;
787}
788
584560f1 789static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 790 const struct sr_channel_group *cg)
a1c743fc 791{
861c447b
BV
792 GVariant *tuple, *rational[2];
793 GVariantBuilder gvb;
794 unsigned int i;
7cc1a550
ML
795 struct dev_context *devc = NULL;
796
e43fdd8d 797 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1 798 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
a0e0bb41 799 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
e43fdd8d 800 return SR_OK;
0c5f2abc 801 } else if (key == SR_CONF_DEVICE_OPTIONS && !cg) {
584560f1 802 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 803 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
e43fdd8d
BV
804 return SR_OK;
805 }
806
807 /* Every other option requires a valid device instance. */
4d399734 808 if (!sdi)
e43fdd8d 809 return SR_ERR_ARG;
4d399734 810 devc = sdi->priv;
e43fdd8d 811
660e398f 812 /* If a channel group is specified, it must be a valid one. */
40c2c915
ML
813 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
814 sr_err("Invalid channel group specified.");
815 return SR_ERR;
be60a9e4
BV
816 }
817
e43fdd8d 818 switch (key) {
9a6517d1 819 case SR_CONF_DEVICE_OPTIONS:
53b4680f 820 if (!cg) {
660e398f
UH
821 sr_err("No channel group specified.");
822 return SR_ERR_CHANNEL_GROUP;
be60a9e4 823 }
562b7ae5 824 if (cg == devc->digital_group) {
584560f1
BV
825 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
826 NULL, 0, sizeof(uint32_t));
f48e0249
ML
827 return SR_OK;
828 } else {
effb9dd1 829 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 830 if (cg == devc->analog_groups[i]) {
584560f1 831 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 832 analog_devopts, ARRAY_SIZE(analog_devopts), sizeof(uint32_t));
f48e0249
ML
833 return SR_OK;
834 }
835 }
836 return SR_ERR_NA;
837 }
5f77dffc 838 break;
2a7b113d 839 case SR_CONF_COUPLING:
53b4680f 840 if (!cg) {
660e398f
UH
841 sr_err("No channel group specified.");
842 return SR_ERR_CHANNEL_GROUP;
f48e0249 843 }
58f43369
BV
844 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
845 break;
e4f2b2ad 846 case SR_CONF_VDIV:
7cc1a550
ML
847 if (!devc)
848 /* Can't know this until we have the exact model. */
849 return SR_ERR_ARG;
53b4680f 850 if (!cg) {
660e398f
UH
851 sr_err("No channel group specified.");
852 return SR_ERR_CHANNEL_GROUP;
861c447b 853 }
58f43369 854 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
81b85663 855 for (i = 0; i < devc->num_vdivs; i++) {
bafd4890
ML
856 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
857 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
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);
862 break;
41f5bd09 863 case SR_CONF_TIMEBASE:
7cc1a550
ML
864 if (!devc)
865 /* Can't know this until we have the exact model. */
866 return SR_ERR_ARG;
a31b2ccb
AJ
867 if (devc->num_timebases <= 0)
868 return SR_ERR_NA;
861c447b 869 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
870 for (i = 0; i < devc->num_timebases; i++) {
871 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
872 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
873 tuple = g_variant_new_tuple(rational, 2);
874 g_variant_builder_add_value(&gvb, tuple);
875 }
876 *data = g_variant_builder_end(&gvb);
41f5bd09 877 break;
328bafab 878 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
879 if (!devc)
880 /* Can't know this until we have the exact model. */
881 return SR_ERR_ARG;
f6a0ac9f 882 *data = g_variant_new_strv(trigger_sources,
bafd4890 883 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 884 break;
5d336f11
AJ
885 case SR_CONF_TRIGGER_SLOPE:
886 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
887 break;
babab622
ML
888 case SR_CONF_DATA_SOURCE:
889 if (!devc)
890 /* Can't know this until we have the exact model. */
891 return SR_ERR_ARG;
569d4dbd
ML
892 switch (devc->model->series->protocol) {
893 case PROTOCOL_V1:
894 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
895 break;
896 case PROTOCOL_V2:
babab622 897 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
898 break;
899 default:
900 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
901 break;
902 }
babab622 903 break;
a1c743fc 904 default:
bd6fbf62 905 return SR_ERR_NA;
a1c743fc
BV
906 }
907
908 return SR_OK;
909}
910
695dc859 911static int dev_acquisition_start(const struct sr_dev_inst *sdi)
f4816ac6 912{
ae1bc1cc 913 struct sr_scpi_dev_inst *scpi;
29d957ce 914 struct dev_context *devc;
ba7dd8bb 915 struct sr_channel *ch;
f76c24f6 916 struct sr_datafeed_packet packet;
702f42e8 917 gboolean some_digital;
254dd102 918 GSList *l;
29d957ce 919
e73ffd42
BV
920 if (sdi->status != SR_ST_ACTIVE)
921 return SR_ERR_DEV_CLOSED;
e0b7d23c 922
ae1bc1cc 923 scpi = sdi->conn;
29d957ce
UH
924 devc = sdi->priv;
925
51b294cd
ML
926 devc->num_frames = 0;
927
702f42e8 928 some_digital = FALSE;
ba7dd8bb
UH
929 for (l = sdi->channels; l; l = l->next) {
930 ch = l->data;
931 sr_dbg("handling channel %s", ch->name);
3f239f08 932 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 933 if (ch->enabled)
702f42e8
ML
934 devc->enabled_channels = g_slist_append(
935 devc->enabled_channels, ch);
ba7dd8bb 936 if (ch->enabled != devc->analog_channels[ch->index]) {
6bb192bc 937 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
938 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
939 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 940 return SR_ERR;
ba7dd8bb 941 devc->analog_channels[ch->index] = ch->enabled;
6bb192bc 942 }
3f239f08 943 } else if (ch->type == SR_CHANNEL_LOGIC) {
702f42e8
ML
944 /* Only one list entry for DS1000D series. All channels are retrieved
945 * together when this entry is processed. */
946 if (ch->enabled && (
947 devc->model->series->protocol > PROTOCOL_V2 ||
948 !some_digital))
949 devc->enabled_channels = g_slist_append(
950 devc->enabled_channels, ch);
ba7dd8bb 951 if (ch->enabled) {
702f42e8 952 some_digital = TRUE;
04e8e01e
ML
953 /* Turn on LA module if currently off. */
954 if (!devc->la_enabled) {
702f42e8
ML
955 if (rigol_ds_config_set(sdi,
956 devc->model->series->protocol >= PROTOCOL_V4 ?
957 ":LA:STAT ON" : ":LA:DISP ON") != SR_OK)
04e8e01e
ML
958 return SR_ERR;
959 devc->la_enabled = TRUE;
960 }
961 }
ba7dd8bb 962 if (ch->enabled != devc->digital_channels[ch->index]) {
6bb192bc 963 /* Enabled channel is currently disabled, or vice versa. */
702f42e8
ML
964 if (rigol_ds_config_set(sdi,
965 devc->model->series->protocol >= PROTOCOL_V4 ?
966 ":LA:DIG%d:DISP %s" : ":DIG%d:TURN %s", ch->index,
ba7dd8bb 967 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 968 return SR_ERR;
ba7dd8bb 969 devc->digital_channels[ch->index] = ch->enabled;
6bb192bc 970 }
254dd102
BV
971 }
972 }
1fed20cb 973
702f42e8 974 if (!devc->enabled_channels)
254dd102 975 return SR_ERR;
e0b7d23c 976
ba7dd8bb 977 /* Turn off LA module if on and no digital channels selected. */
702f42e8
ML
978 if (devc->la_enabled && !some_digital)
979 if (rigol_ds_config_set(sdi,
980 devc->model->series->protocol >= PROTOCOL_V4 ?
981 ":LA:STAT OFF" : ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
982 return SR_ERR;
983
e086b750
ML
984 /* Set memory mode. */
985 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
986 sr_err("Data source 'Segmented' not yet supported");
987 return SR_ERR;
988 }
989
990 devc->analog_frame_size = analog_frame_size(sdi);
991 devc->digital_frame_size = digital_frame_size(sdi);
992
569d4dbd
ML
993 switch (devc->model->series->protocol) {
994 case PROTOCOL_V2:
99af83b7 995 if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
e086b750 996 return SR_ERR;
569d4dbd
ML
997 break;
998 case PROTOCOL_V3:
e086b750
ML
999 /* Apparently for the DS2000 the memory
1000 * depth can only be set in Running state -
1001 * this matches the behaviour of the UI. */
38354d9d 1002 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 1003 return SR_ERR;
e086b750
ML
1004 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1005 devc->analog_frame_size) != SR_OK)
1006 return SR_ERR;
1007 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1008 return SR_ERR;
569d4dbd
ML
1009 break;
1010 default:
1011 break;
1fed20cb
ML
1012 }
1013
e086b750
ML
1014 if (devc->data_source == DATA_SOURCE_LIVE)
1015 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1016 return SR_ERR;
1017
102f1239
BV
1018 sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
1019 rigol_ds_receive, (void *)sdi);
e0b7d23c 1020
695dc859 1021 std_session_send_df_header(sdi, LOG_PREFIX);
e0b7d23c 1022
702f42e8 1023 devc->channel_entry = devc->enabled_channels;
821fbcad 1024
e086b750
ML
1025 if (rigol_ds_capture_start(sdi) != SR_OK)
1026 return SR_ERR;
f4816ac6 1027
f76c24f6
ML
1028 /* Start of first frame. */
1029 packet.type = SR_DF_FRAME_BEGIN;
695dc859 1030 sr_session_send(sdi, &packet);
f76c24f6 1031
f4816ac6
ML
1032 return SR_OK;
1033}
1034
695dc859 1035static int dev_acquisition_stop(struct sr_dev_inst *sdi)
f4816ac6 1036{
29d957ce 1037 struct dev_context *devc;
ae1bc1cc 1038 struct sr_scpi_dev_inst *scpi;
29d957ce 1039
29d957ce
UH
1040 devc = sdi->priv;
1041
f4816ac6
ML
1042 if (sdi->status != SR_ST_ACTIVE) {
1043 sr_err("Device inactive, can't stop acquisition.");
1044 return SR_ERR;
1045 }
1046
3be42bc2 1047 std_session_send_df_end(sdi, LOG_PREFIX);
b751cf7a 1048
702f42e8
ML
1049 g_slist_free(devc->enabled_channels);
1050 devc->enabled_channels = NULL;
ae1bc1cc 1051 scpi = sdi->conn;
102f1239 1052 sr_scpi_source_remove(sdi->session, scpi);
f4816ac6
ML
1053
1054 return SR_OK;
1055}
1056
3086efdd
ML
1057SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1058 .name = "rigol-ds",
1059 .longname = "Rigol DS",
f4816ac6 1060 .api_version = 1,
c2fdcc25 1061 .init = std_init,
700d6b64 1062 .cleanup = std_cleanup,
6078d2c9 1063 .scan = scan,
c01bf34c 1064 .dev_list = std_dev_list,
3b412e3a 1065 .dev_clear = dev_clear,
d62d7ad1 1066 .config_get = config_get,
035a1078 1067 .config_set = config_set,
a1c743fc 1068 .config_list = config_list,
6078d2c9
UH
1069 .dev_open = dev_open,
1070 .dev_close = dev_close,
254dd102
BV
1071 .dev_acquisition_start = dev_acquisition_start,
1072 .dev_acquisition_stop = dev_acquisition_stop,
41812aca 1073 .context = NULL,
f4816ac6 1074};