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