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