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