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