]> sigrok.org Git - libsigrok.git/blame - src/hardware/rigol-ds/api.c
rigol-ds: Fix broken channel group check in config_list().
[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,
178};
10afee13 179
569d4dbd
ML
180/* short name, full name */
181static const struct rigol_ds_vendor supported_vendors[] = {
182 [RIGOL] = {"Rigol", "Rigol Technologies"},
14e1aa6d 183 [AGILENT] = {"Agilent", "Agilent Technologies"},
569d4dbd
ML
184};
185
186#define VENDOR(x) &supported_vendors[x]
187/* vendor, series, protocol, max timebase, min vdiv, number of horizontal divs,
188 * live waveform samples, memory buffer samples */
189static const struct rigol_ds_series supported_series[] = {
190 [VS5000] = {VENDOR(RIGOL), "VS5000", PROTOCOL_V1, FORMAT_RAW,
191 {50, 1}, {2, 1000}, 14, 2048, 0},
192 [DS1000] = {VENDOR(RIGOL), "DS1000", PROTOCOL_V2, FORMAT_IEEE488_2,
193 {50, 1}, {2, 1000}, 12, 600, 1048576},
194 [DS2000] = {VENDOR(RIGOL), "DS2000", PROTOCOL_V3, FORMAT_IEEE488_2,
96cb7faa 195 {500, 1}, {500, 1000000}, 14, 1400, 14000},
569d4dbd
ML
196 [DS2000A] = {VENDOR(RIGOL), "DS2000A", PROTOCOL_V3, FORMAT_IEEE488_2,
197 {1000, 1}, {500, 1000000}, 14, 1400, 14000},
198 [DSO1000] = {VENDOR(AGILENT), "DSO1000", PROTOCOL_V3, FORMAT_IEEE488_2,
199 {50, 1}, {2, 1000}, 12, 600, 20480},
200};
10afee13 201
569d4dbd
ML
202#define SERIES(x) &supported_series[x]
203/* series, model, min timebase, analog channels, digital */
bafd4890 204static const struct rigol_ds_model supported_models[] = {
569d4dbd
ML
205 {SERIES(VS5000), "VS5022", {20, 1000000000}, 2, false},
206 {SERIES(VS5000), "VS5042", {10, 1000000000}, 2, false},
207 {SERIES(VS5000), "VS5062", {5, 1000000000}, 2, false},
208 {SERIES(VS5000), "VS5102", {2, 1000000000}, 2, false},
209 {SERIES(VS5000), "VS5202", {2, 1000000000}, 2, false},
210 {SERIES(VS5000), "VS5022D", {20, 1000000000}, 2, true},
211 {SERIES(VS5000), "VS5042D", {10, 1000000000}, 2, true},
212 {SERIES(VS5000), "VS5062D", {5, 1000000000}, 2, true},
213 {SERIES(VS5000), "VS5102D", {2, 1000000000}, 2, true},
214 {SERIES(VS5000), "VS5202D", {2, 1000000000}, 2, true},
215 {SERIES(DS1000), "DS1052E", {5, 1000000000}, 2, false},
216 {SERIES(DS1000), "DS1102E", {2, 1000000000}, 2, false},
217 {SERIES(DS1000), "DS1152E", {2, 1000000000}, 2, false},
218 {SERIES(DS1000), "DS1052D", {5, 1000000000}, 2, true},
219 {SERIES(DS1000), "DS1102D", {2, 1000000000}, 2, true},
220 {SERIES(DS1000), "DS1152D", {2, 1000000000}, 2, true},
221 {SERIES(DS2000), "DS2072", {5, 1000000000}, 2, false},
222 {SERIES(DS2000), "DS2102", {5, 1000000000}, 2, false},
223 {SERIES(DS2000), "DS2202", {2, 1000000000}, 2, false},
224 {SERIES(DS2000), "DS2302", {1, 1000000000}, 2, false},
225 {SERIES(DS2000A), "DS2072A", {5, 1000000000}, 2, false},
226 {SERIES(DS2000A), "DS2102A", {5, 1000000000}, 2, false},
227 {SERIES(DS2000A), "DS2202A", {2, 1000000000}, 2, false},
228 {SERIES(DS2000A), "DS2302A", {1, 1000000000}, 2, false},
229 {SERIES(DSO1000), "DSO1002A", {5, 1000000000}, 2, false},
230 {SERIES(DSO1000), "DSO1004A", {5, 1000000000}, 4, false},
231 {SERIES(DSO1000), "DSO1012A", {2, 1000000000}, 2, false},
232 {SERIES(DSO1000), "DSO1014A", {2, 1000000000}, 4, false},
233 {SERIES(DSO1000), "DSO1022A", {2, 1000000000}, 2, false},
234 {SERIES(DSO1000), "DSO1024A", {2, 1000000000}, 4, false},
512bb890
BV
235};
236
3086efdd
ML
237SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
238static struct sr_dev_driver *di = &rigol_ds_driver_info;
f4816ac6 239
fa85f376 240static void clear_helper(void *priv)
f4816ac6 241{
f4816ac6 242 struct dev_context *devc;
effb9dd1 243 unsigned int i;
f4816ac6 244
ba358ffd 245 devc = priv;
babab622
ML
246 g_free(devc->data);
247 g_free(devc->buffer);
effb9dd1
AJ
248 for (i = 0; i < ARRAY_SIZE(devc->coupling); i++)
249 g_free(devc->coupling[i]);
fa85f376
UH
250 g_free(devc->trigger_source);
251 g_free(devc->trigger_slope);
562b7ae5 252 g_free(devc->analog_groups);
562b7ae5 253 g_free(devc);
fa85f376 254}
f4816ac6 255
3b412e3a 256static int dev_clear(void)
fa85f376
UH
257{
258 return std_dev_clear(di, clear_helper);
f4816ac6
ML
259}
260
6078d2c9 261static int init(struct sr_context *sr_ctx)
f4816ac6 262{
f6beaac5 263 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
264}
265
9d3ae01b 266static struct sr_dev_inst *probe_device(struct sr_scpi_dev_inst *scpi)
f4816ac6 267{
cc9fd2d2
BV
268 struct dev_context *devc;
269 struct sr_dev_inst *sdi;
ae1bc1cc 270 struct sr_scpi_hw_info *hw_info;
ba7dd8bb 271 struct sr_channel *ch;
8dd0b290 272 long n[3];
f6a0ac9f 273 unsigned int i;
bafd4890 274 const struct rigol_ds_model *model = NULL;
569d4dbd 275 gchar *channel_name, **version;
fb6e5ba8 276
ae1bc1cc 277 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
05238d28
ML
278 sr_info("Couldn't get IDN response, retrying.");
279 sr_scpi_close(scpi);
280 sr_scpi_open(scpi);
281 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
282 sr_info("Couldn't get IDN response.");
283 return NULL;
284 }
ca55277c 285 }
e0b7d23c 286
ca55277c 287 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
569d4dbd
ML
288 if (!strcasecmp(hw_info->manufacturer,
289 supported_models[i].series->vendor->full_name) &&
10afee13 290 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 291 model = &supported_models[i];
ca55277c 292 break;
fb6e5ba8 293 }
ca55277c 294 }
fb6e5ba8 295
0af636be 296 if (!model) {
ae1bc1cc 297 sr_scpi_hw_info_free(hw_info);
9d3ae01b 298 return NULL;
ca55277c 299 }
fb6e5ba8 300
aac29cc1 301 sdi = g_malloc0(sizeof(struct sr_dev_inst));
0af636be
UH
302 sdi->status = SR_ST_ACTIVE;
303 sdi->vendor = g_strdup(model->series->vendor->name);
304 sdi->model = g_strdup(model->name);
305 sdi->version = g_strdup(hw_info->firmware_version);
ae1bc1cc 306 sdi->conn = scpi;
cc9fd2d2 307 sdi->driver = di;
ae1bc1cc 308 sdi->inst_type = SR_INST_SCPI;
b3fccc85 309 sdi->serial_num = g_strdup(hw_info->serial_number);
f57d8ffe 310 devc = g_malloc0(sizeof(struct dev_context));
cc9fd2d2 311 devc->limit_frames = 0;
bafd4890 312 devc->model = model;
569d4dbd 313 devc->format = model->series->format;
8dd0b290 314
569d4dbd
ML
315 /* DS1000 models with firmware before 0.2.4 used the old data format. */
316 if (model->series == SERIES(DS1000)) {
8dd0b290
BV
317 version = g_strsplit(hw_info->firmware_version, ".", 0);
318 do {
319 if (!version[0] || !version[1] || !version[2])
320 break;
321 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
322 break;
323 for (i = 0; i < 3; i++) {
324 if (sr_atol(version[i], &n[i]) != SR_OK)
325 break;
326 }
327 if (i != 3)
328 break;
329 if (n[0] != 0 || n[1] > 2)
330 break;
331 if (n[1] == 2 && n[2] > 3)
332 break;
569d4dbd
ML
333 sr_dbg("Found DS1000 firmware < 0.2.4, using raw data format.");
334 devc->format = FORMAT_RAW;
8dd0b290
BV
335 } while(0);
336 g_strfreev(version);
337 }
338
339 sr_scpi_hw_info_free(hw_info);
512bb890 340
562b7ae5
SA
341 devc->analog_groups = g_malloc0(sizeof(struct sr_channel_group*) *
342 model->analog_channels);
343
821fbcad
ML
344 for (i = 0; i < model->analog_channels; i++) {
345 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
9d3ae01b 346 return NULL;
5e23fcab 347 ch = sr_channel_new(sdi, i, SR_CHANNEL_ANALOG, TRUE, channel_name);
562b7ae5
SA
348
349 devc->analog_groups[i] = g_malloc0(sizeof(struct sr_channel_group));
350
351 devc->analog_groups[i]->name = channel_name;
352 devc->analog_groups[i]->channels = g_slist_append(NULL, ch);
660e398f 353 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 354 devc->analog_groups[i]);
ca55277c 355 }
512bb890 356
bafd4890 357 if (devc->model->has_digital) {
16aca766 358 devc->digital_group = g_malloc0(sizeof(struct sr_channel_group));
562b7ae5 359
effb9dd1 360 for (i = 0; i < ARRAY_SIZE(devc->digital_channels); i++) {
ca55277c 361 if (!(channel_name = g_strdup_printf("D%d", i)))
9d3ae01b 362 return NULL;
5e23fcab 363 ch = sr_channel_new(sdi, i, SR_CHANNEL_LOGIC, TRUE, channel_name);
ca55277c 364 g_free(channel_name);
562b7ae5
SA
365 devc->digital_group->channels = g_slist_append(
366 devc->digital_group->channels, ch);
512bb890 367 }
562b7ae5 368 devc->digital_group->name = g_strdup("LA");
660e398f 369 sdi->channel_groups = g_slist_append(sdi->channel_groups,
562b7ae5 370 devc->digital_group);
ca55277c 371 }
bafd4890
ML
372
373 for (i = 0; i < NUM_TIMEBASE; i++) {
374 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
375 devc->timebases = &timebases[i];
569d4dbd 376 if (!memcmp(&devc->model->series->max_timebase, &timebases[i], sizeof(uint64_t[2])))
bafd4890
ML
377 devc->num_timebases = &timebases[i] - devc->timebases + 1;
378 }
379
0709197d 380 for (i = 0; i < NUM_VDIV; i++)
81b85663 381 if (!memcmp(&devc->model->series->min_vdiv, &vdivs[i], sizeof(uint64_t[2]))) {
6ff1394e 382 devc->vdivs = &vdivs[i];
81b85663
AJ
383 devc->num_vdivs = NUM_VDIV - i;
384 }
bafd4890 385
babab622 386 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
9d3ae01b 387 return NULL;
babab622 388 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
9d3ae01b 389 return NULL;
babab622
ML
390
391 devc->data_source = DATA_SOURCE_LIVE;
392
cc9fd2d2
BV
393 sdi->priv = devc;
394
9d3ae01b 395 return sdi;
ca55277c 396}
512bb890 397
6078d2c9 398static GSList *scan(GSList *options)
ca55277c 399{
9d3ae01b 400 return sr_scpi_scan(di->priv, options, probe_device);
f4816ac6
ML
401}
402
6078d2c9 403static GSList *dev_list(void)
f4816ac6 404{
0e94d524 405 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
406}
407
6078d2c9 408static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 409{
e1b5b7e7 410 int ret;
ae1bc1cc 411 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 412
e1b5b7e7
UH
413 if ((ret = sr_scpi_open(scpi)) < 0) {
414 sr_err("Failed to open SCPI device: %s.", sr_strerror(ret));
e0b7d23c 415 return SR_ERR;
e1b5b7e7 416 }
e0b7d23c 417
e1b5b7e7
UH
418 if ((ret = rigol_ds_get_dev_cfg(sdi)) < 0) {
419 sr_err("Failed to get device config: %s.", sr_strerror(ret));
254dd102 420 return SR_ERR;
e1b5b7e7 421 }
f4816ac6 422
46a743c1 423 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 424
f4816ac6
ML
425 return SR_OK;
426}
427
6078d2c9 428static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 429{
ae1bc1cc 430 struct sr_scpi_dev_inst *scpi;
22c19688 431 struct dev_context *devc;
ae1bc1cc 432
83dbd9f0
AJ
433 if (sdi->status != SR_ST_ACTIVE)
434 return SR_ERR_DEV_CLOSED;
464d4936 435
ae1bc1cc 436 scpi = sdi->conn;
22c19688
ML
437 devc = sdi->priv;
438
6e94eb41 439 if (devc->model->series->protocol == PROTOCOL_V2)
38354d9d 440 rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 441
ae1bc1cc
ML
442 if (scpi) {
443 if (sr_scpi_close(scpi) < 0)
444 return SR_ERR;
cc9fd2d2
BV
445 sdi->status = SR_ST_INACTIVE;
446 }
f4816ac6
ML
447
448 return SR_OK;
449}
450
6078d2c9 451static int cleanup(void)
f4816ac6 452{
3b412e3a 453 return dev_clear();
f4816ac6
ML
454}
455
5415e602
ML
456static int analog_frame_size(const struct sr_dev_inst *sdi)
457{
458 struct dev_context *devc = sdi->priv;
ba7dd8bb
UH
459 struct sr_channel *ch;
460 int analog_channels = 0;
5415e602
ML
461 GSList *l;
462
ba7dd8bb
UH
463 for (l = sdi->channels; l; l = l->next) {
464 ch = l->data;
3f239f08 465 if (ch->type == SR_CHANNEL_ANALOG && ch->enabled)
ba7dd8bb 466 analog_channels++;
569d4dbd
ML
467 }
468
ba7dd8bb 469 if (analog_channels == 0)
824eb2ac
ML
470 return 0;
471
569d4dbd
ML
472 switch (devc->data_source) {
473 case DATA_SOURCE_LIVE:
474 return devc->model->series->live_samples;
475 case DATA_SOURCE_MEMORY:
ba7dd8bb 476 return devc->model->series->buffer_samples / analog_channels;
470140fc 477 default:
569d4dbd 478 return 0;
5415e602
ML
479 }
480}
481
d22250a9
ML
482static int digital_frame_size(const struct sr_dev_inst *sdi)
483{
484 struct dev_context *devc = sdi->priv;
485
569d4dbd
ML
486 switch (devc->data_source) {
487 case DATA_SOURCE_LIVE:
488 return devc->model->series->live_samples * 2;
489 case DATA_SOURCE_MEMORY:
490 return devc->model->series->buffer_samples * 2;
d22250a9
ML
491 default:
492 return 0;
493 }
494}
495
584560f1 496static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 497 const struct sr_channel_group *cg)
d62d7ad1 498{
e43fdd8d 499 struct dev_context *devc;
ba7dd8bb 500 struct sr_channel *ch;
2b0e4a46 501 const char *tmp_str;
c2b394d5 502 uint64_t samplerate;
2b0e4a46 503 int analog_channel = -1;
c33ff377 504 float smallest_diff = INFINITY;
2b0e4a46
AJ
505 int idx = -1;
506 unsigned i;
d62d7ad1 507
e43fdd8d
BV
508 if (!sdi || !(devc = sdi->priv))
509 return SR_ERR_ARG;
510
660e398f 511 /* If a channel group is specified, it must be a valid one. */
53b4680f 512 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
660e398f 513 sr_err("Invalid channel group specified.");
969edf63 514 return SR_ERR;
be60a9e4
BV
515 }
516
53b4680f 517 if (cg) {
ba7dd8bb
UH
518 ch = g_slist_nth_data(cg->channels, 0);
519 if (!ch)
2b0e4a46 520 return SR_ERR;
3f239f08 521 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb 522 if (ch->name[2] < '1' || ch->name[2] > '4')
2b0e4a46 523 return SR_ERR;
ba7dd8bb 524 analog_channel = ch->name[2] - '1';
2b0e4a46
AJ
525 }
526 }
527
584560f1 528 switch (key) {
bf622e6d 529 case SR_CONF_NUM_HDIV:
569d4dbd 530 *data = g_variant_new_int32(devc->model->series->num_horizontal_divs);
d62d7ad1
BV
531 break;
532 case SR_CONF_NUM_VDIV:
81b85663 533 *data = g_variant_new_int32(devc->num_vdivs);
f44f7e61 534 break;
babab622
ML
535 case SR_CONF_DATA_SOURCE:
536 if (devc->data_source == DATA_SOURCE_LIVE)
537 *data = g_variant_new_string("Live");
538 else if (devc->data_source == DATA_SOURCE_MEMORY)
539 *data = g_variant_new_string("Memory");
540 else
541 *data = g_variant_new_string("Segmented");
542 break;
4914dd4b
ML
543 case SR_CONF_SAMPLERATE:
544 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 545 samplerate = analog_frame_size(sdi) /
569d4dbd 546 (devc->timebase * devc->model->series->num_horizontal_divs);
4914dd4b 547 *data = g_variant_new_uint64(samplerate);
c2b394d5 548 } else {
e1b5b7e7 549 sr_dbg("Unknown data source: %d.", devc->data_source);
4914dd4b 550 return SR_ERR_NA;
c2b394d5 551 }
4914dd4b 552 break;
2b0e4a46
AJ
553 case SR_CONF_TRIGGER_SOURCE:
554 if (!strcmp(devc->trigger_source, "ACL"))
555 tmp_str = "AC Line";
556 else if (!strcmp(devc->trigger_source, "CHAN1"))
557 tmp_str = "CH1";
558 else if (!strcmp(devc->trigger_source, "CHAN2"))
559 tmp_str = "CH2";
560 else if (!strcmp(devc->trigger_source, "CHAN3"))
561 tmp_str = "CH3";
562 else if (!strcmp(devc->trigger_source, "CHAN4"))
563 tmp_str = "CH4";
564 else
565 tmp_str = devc->trigger_source;
566 *data = g_variant_new_string(tmp_str);
567 break;
5d336f11 568 case SR_CONF_TRIGGER_SLOPE:
e1b5b7e7 569 if (!strncmp(devc->trigger_slope, "POS", 3)) {
5d336f11 570 tmp_str = "r";
e1b5b7e7 571 } else if (!strncmp(devc->trigger_slope, "NEG", 3)) {
5d336f11 572 tmp_str = "f";
e1b5b7e7
UH
573 } else {
574 sr_dbg("Unknown trigger slope: '%s'.", devc->trigger_slope);
5d336f11 575 return SR_ERR_NA;
e1b5b7e7 576 }
5d336f11
AJ
577 *data = g_variant_new_string(tmp_str);
578 break;
2b0e4a46
AJ
579 case SR_CONF_TIMEBASE:
580 for (i = 0; i < devc->num_timebases; i++) {
581 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
582 float diff = fabs(devc->timebase - tb);
583 if (diff < smallest_diff) {
584 smallest_diff = diff;
585 idx = i;
586 }
587 }
e1b5b7e7
UH
588 if (idx < 0) {
589 sr_dbg("Negative timebase index: %d.", idx);
2b0e4a46 590 return SR_ERR_NA;
e1b5b7e7 591 }
2b0e4a46
AJ
592 *data = g_variant_new("(tt)", devc->timebases[idx][0],
593 devc->timebases[idx][1]);
594 break;
595 case SR_CONF_VDIV:
e1b5b7e7
UH
596 if (analog_channel < 0) {
597 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 598 return SR_ERR_NA;
e1b5b7e7 599 }
2b0e4a46
AJ
600 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
601 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
602 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
603 if (diff < smallest_diff) {
604 smallest_diff = diff;
605 idx = i;
606 }
607 }
e1b5b7e7
UH
608 if (idx < 0) {
609 sr_dbg("Negative vdiv index: %d.", idx);
2b0e4a46 610 return SR_ERR_NA;
e1b5b7e7 611 }
2b0e4a46
AJ
612 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
613 break;
614 case SR_CONF_COUPLING:
e1b5b7e7
UH
615 if (analog_channel < 0) {
616 sr_dbg("Negative analog channel: %d.", analog_channel);
2b0e4a46 617 return SR_ERR_NA;
e1b5b7e7 618 }
2b0e4a46
AJ
619 *data = g_variant_new_string(devc->coupling[analog_channel]);
620 break;
d62d7ad1 621 default:
e1b5b7e7 622 sr_dbg("Tried to get unknown config key: %d.", key);
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:
e1b5b7e7 787 sr_dbg("Tried to set unknown config key: %d.", key);
bd6fbf62 788 ret = SR_ERR_NA;
29d957ce 789 break;
f4816ac6
ML
790 }
791
792 return ret;
793}
794
584560f1 795static int config_list(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
53b4680f 796 const struct sr_channel_group *cg)
a1c743fc 797{
861c447b
BV
798 GVariant *tuple, *rational[2];
799 GVariantBuilder gvb;
800 unsigned int i;
7cc1a550
ML
801 struct dev_context *devc = NULL;
802
803 if (sdi)
804 devc = sdi->priv;
8f996b89 805
e43fdd8d 806 if (key == SR_CONF_SCAN_OPTIONS) {
584560f1 807 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
a0e0bb41 808 scanopts, ARRAY_SIZE(scanopts), sizeof(uint32_t));
e43fdd8d 809 return SR_OK;
53b4680f 810 } else if (key == SR_CONF_DEVICE_OPTIONS && cg == NULL) {
584560f1 811 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 812 devopts, ARRAY_SIZE(devopts), sizeof(uint32_t));
e43fdd8d
BV
813 return SR_OK;
814 }
815
816 /* Every other option requires a valid device instance. */
817 if (!sdi || !(devc = sdi->priv))
818 return SR_ERR_ARG;
819
660e398f 820 /* If a channel group is specified, it must be a valid one. */
40c2c915
ML
821 if (cg && !g_slist_find(sdi->channel_groups, cg)) {
822 sr_err("Invalid channel group specified.");
823 return SR_ERR;
be60a9e4
BV
824 }
825
e43fdd8d 826 switch (key) {
9a6517d1 827 case SR_CONF_DEVICE_OPTIONS:
53b4680f 828 if (!cg) {
660e398f
UH
829 sr_err("No channel group specified.");
830 return SR_ERR_CHANNEL_GROUP;
be60a9e4 831 }
562b7ae5 832 if (cg == devc->digital_group) {
584560f1
BV
833 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
834 NULL, 0, sizeof(uint32_t));
f48e0249
ML
835 return SR_OK;
836 } else {
effb9dd1 837 for (i = 0; i < devc->model->analog_channels; i++) {
562b7ae5 838 if (cg == devc->analog_groups[i]) {
584560f1 839 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_UINT32,
f254bc4b 840 analog_devopts, ARRAY_SIZE(analog_devopts), sizeof(uint32_t));
f48e0249
ML
841 return SR_OK;
842 }
843 }
844 return SR_ERR_NA;
845 }
5f77dffc 846 break;
2a7b113d 847 case SR_CONF_COUPLING:
53b4680f 848 if (!cg) {
660e398f
UH
849 sr_err("No channel group specified.");
850 return SR_ERR_CHANNEL_GROUP;
f48e0249 851 }
58f43369
BV
852 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
853 break;
e4f2b2ad 854 case SR_CONF_VDIV:
7cc1a550
ML
855 if (!devc)
856 /* Can't know this until we have the exact model. */
857 return SR_ERR_ARG;
53b4680f 858 if (!cg) {
660e398f
UH
859 sr_err("No channel group specified.");
860 return SR_ERR_CHANNEL_GROUP;
861c447b 861 }
58f43369 862 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
81b85663 863 for (i = 0; i < devc->num_vdivs; i++) {
bafd4890
ML
864 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
865 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
866 tuple = g_variant_new_tuple(rational, 2);
867 g_variant_builder_add_value(&gvb, tuple);
868 }
869 *data = g_variant_builder_end(&gvb);
870 break;
41f5bd09 871 case SR_CONF_TIMEBASE:
7cc1a550
ML
872 if (!devc)
873 /* Can't know this until we have the exact model. */
874 return SR_ERR_ARG;
a31b2ccb
AJ
875 if (devc->num_timebases <= 0)
876 return SR_ERR_NA;
861c447b 877 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
878 for (i = 0; i < devc->num_timebases; i++) {
879 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
880 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
881 tuple = g_variant_new_tuple(rational, 2);
882 g_variant_builder_add_value(&gvb, tuple);
883 }
884 *data = g_variant_builder_end(&gvb);
41f5bd09 885 break;
328bafab 886 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
887 if (!devc)
888 /* Can't know this until we have the exact model. */
889 return SR_ERR_ARG;
f6a0ac9f 890 *data = g_variant_new_strv(trigger_sources,
bafd4890 891 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 892 break;
5d336f11
AJ
893 case SR_CONF_TRIGGER_SLOPE:
894 *data = g_variant_new_strv(trigger_slopes, ARRAY_SIZE(trigger_slopes));
895 break;
babab622
ML
896 case SR_CONF_DATA_SOURCE:
897 if (!devc)
898 /* Can't know this until we have the exact model. */
899 return SR_ERR_ARG;
569d4dbd
ML
900 switch (devc->model->series->protocol) {
901 case PROTOCOL_V1:
902 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 2);
903 break;
904 case PROTOCOL_V2:
babab622 905 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
569d4dbd
ML
906 break;
907 default:
908 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
909 break;
910 }
babab622 911 break;
a1c743fc 912 default:
e1b5b7e7 913 sr_dbg("Tried to list unknown config key: %d.", key);
bd6fbf62 914 return SR_ERR_NA;
a1c743fc
BV
915 }
916
917 return SR_OK;
918}
919
254dd102 920static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 921{
ae1bc1cc 922 struct sr_scpi_dev_inst *scpi;
29d957ce 923 struct dev_context *devc;
ba7dd8bb 924 struct sr_channel *ch;
f76c24f6 925 struct sr_datafeed_packet packet;
254dd102 926 GSList *l;
29d957ce 927
e73ffd42
BV
928 if (sdi->status != SR_ST_ACTIVE)
929 return SR_ERR_DEV_CLOSED;
e0b7d23c 930
ae1bc1cc 931 scpi = sdi->conn;
29d957ce
UH
932 devc = sdi->priv;
933
51b294cd
ML
934 devc->num_frames = 0;
935
ba7dd8bb
UH
936 for (l = sdi->channels; l; l = l->next) {
937 ch = l->data;
938 sr_dbg("handling channel %s", ch->name);
3f239f08 939 if (ch->type == SR_CHANNEL_ANALOG) {
ba7dd8bb
UH
940 if (ch->enabled)
941 devc->enabled_analog_channels = g_slist_append(
942 devc->enabled_analog_channels, ch);
943 if (ch->enabled != devc->analog_channels[ch->index]) {
6bb192bc 944 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
945 if (rigol_ds_config_set(sdi, ":CHAN%d:DISP %s", ch->index + 1,
946 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 947 return SR_ERR;
ba7dd8bb 948 devc->analog_channels[ch->index] = ch->enabled;
6bb192bc 949 }
3f239f08 950 } else if (ch->type == SR_CHANNEL_LOGIC) {
ba7dd8bb
UH
951 if (ch->enabled) {
952 devc->enabled_digital_channels = g_slist_append(
953 devc->enabled_digital_channels, ch);
04e8e01e
ML
954 /* Turn on LA module if currently off. */
955 if (!devc->la_enabled) {
38354d9d 956 if (rigol_ds_config_set(sdi, ":LA:DISP ON") != SR_OK)
04e8e01e
ML
957 return SR_ERR;
958 devc->la_enabled = TRUE;
959 }
960 }
ba7dd8bb 961 if (ch->enabled != devc->digital_channels[ch->index]) {
6bb192bc 962 /* Enabled channel is currently disabled, or vice versa. */
ba7dd8bb
UH
963 if (rigol_ds_config_set(sdi, ":DIG%d:TURN %s", ch->index,
964 ch->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 965 return SR_ERR;
ba7dd8bb 966 devc->digital_channels[ch->index] = ch->enabled;
6bb192bc 967 }
254dd102
BV
968 }
969 }
1fed20cb 970
ba7dd8bb 971 if (!devc->enabled_analog_channels && !devc->enabled_digital_channels)
254dd102 972 return SR_ERR;
e0b7d23c 973
ba7dd8bb
UH
974 /* Turn off LA module if on and no digital channels selected. */
975 if (devc->la_enabled && !devc->enabled_digital_channels)
38354d9d 976 if (rigol_ds_config_set(sdi, ":LA:DISP OFF") != SR_OK)
04e8e01e
ML
977 return SR_ERR;
978
e086b750
ML
979 /* Set memory mode. */
980 if (devc->data_source == DATA_SOURCE_SEGMENTED) {
981 sr_err("Data source 'Segmented' not yet supported");
982 return SR_ERR;
983 }
984
985 devc->analog_frame_size = analog_frame_size(sdi);
986 devc->digital_frame_size = digital_frame_size(sdi);
987
569d4dbd
ML
988 switch (devc->model->series->protocol) {
989 case PROTOCOL_V2:
99af83b7 990 if (rigol_ds_config_set(sdi, ":ACQ:MEMD LONG") != SR_OK)
e086b750 991 return SR_ERR;
569d4dbd
ML
992 break;
993 case PROTOCOL_V3:
e086b750
ML
994 /* Apparently for the DS2000 the memory
995 * depth can only be set in Running state -
996 * this matches the behaviour of the UI. */
38354d9d 997 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1fed20cb 998 return SR_ERR;
e086b750
ML
999 if (rigol_ds_config_set(sdi, ":ACQ:MDEP %d",
1000 devc->analog_frame_size) != SR_OK)
1001 return SR_ERR;
1002 if (rigol_ds_config_set(sdi, ":STOP") != SR_OK)
1fed20cb 1003 return SR_ERR;
569d4dbd
ML
1004 break;
1005 default:
1006 break;
1fed20cb
ML
1007 }
1008
e086b750
ML
1009 if (devc->data_source == DATA_SOURCE_LIVE)
1010 if (rigol_ds_config_set(sdi, ":RUN") != SR_OK)
1011 return SR_ERR;
1012
102f1239
BV
1013 sr_scpi_source_add(sdi->session, scpi, G_IO_IN, 50,
1014 rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
1015
1016 /* Send header packet to the session bus. */
29a27196 1017 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 1018
ba7dd8bb
UH
1019 if (devc->enabled_analog_channels)
1020 devc->channel_entry = devc->enabled_analog_channels;
821fbcad 1021 else
ba7dd8bb 1022 devc->channel_entry = devc->enabled_digital_channels;
821fbcad 1023
e086b750
ML
1024 if (rigol_ds_capture_start(sdi) != SR_OK)
1025 return SR_ERR;
f4816ac6 1026
f76c24f6
ML
1027 /* Start of first frame. */
1028 packet.type = SR_DF_FRAME_BEGIN;
1029 sr_session_send(cb_data, &packet);
1030
f4816ac6
ML
1031 return SR_OK;
1032}
1033
254dd102 1034static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 1035{
29d957ce 1036 struct dev_context *devc;
ae1bc1cc 1037 struct sr_scpi_dev_inst *scpi;
b751cf7a 1038 struct sr_datafeed_packet packet;
29d957ce 1039
f4816ac6
ML
1040 (void)cb_data;
1041
29d957ce
UH
1042 devc = sdi->priv;
1043
f4816ac6
ML
1044 if (sdi->status != SR_ST_ACTIVE) {
1045 sr_err("Device inactive, can't stop acquisition.");
1046 return SR_ERR;
1047 }
1048
b751cf7a
ML
1049 /* End of last frame. */
1050 packet.type = SR_DF_END;
1051 sr_session_send(sdi, &packet);
1052
ba7dd8bb
UH
1053 g_slist_free(devc->enabled_analog_channels);
1054 g_slist_free(devc->enabled_digital_channels);
1055 devc->enabled_analog_channels = NULL;
1056 devc->enabled_digital_channels = NULL;
ae1bc1cc 1057 scpi = sdi->conn;
102f1239 1058 sr_scpi_source_remove(sdi->session, scpi);
f4816ac6
ML
1059
1060 return SR_OK;
1061}
1062
3086efdd
ML
1063SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1064 .name = "rigol-ds",
1065 .longname = "Rigol DS",
f4816ac6 1066 .api_version = 1,
6078d2c9
UH
1067 .init = init,
1068 .cleanup = cleanup,
1069 .scan = scan,
1070 .dev_list = dev_list,
3b412e3a 1071 .dev_clear = dev_clear,
d62d7ad1 1072 .config_get = config_get,
035a1078 1073 .config_set = config_set,
a1c743fc 1074 .config_list = config_list,
6078d2c9
UH
1075 .dev_open = dev_open,
1076 .dev_close = dev_close,
254dd102
BV
1077 .dev_acquisition_start = dev_acquisition_start,
1078 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1079 .priv = NULL,
1080};