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