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