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