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