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