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