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