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