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