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