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