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