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