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