]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
scpi: Log responses received by sr_scpi_get_string().
[libsigrok.git] / 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
e0b7d23c
ML
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdlib.h>
25#include <string.h>
2b0e4a46 26#include <math.h>
f4816ac6
ML
27#include <glib.h>
28#include "libsigrok.h"
29#include "libsigrok-internal.h"
30#include "protocol.h"
31
ca55277c
ML
32static const int32_t hwopts[] = {
33 SR_CONF_CONN,
0dc7b43e 34 SR_CONF_SERIALCOMM
ca55277c
ML
35};
36
f6a0ac9f 37static const int32_t hwcaps[] = {
1953564a 38 SR_CONF_OSCILLOSCOPE,
1953564a
BV
39 SR_CONF_TIMEBASE,
40 SR_CONF_TRIGGER_SOURCE,
41 SR_CONF_TRIGGER_SLOPE,
42 SR_CONF_HORIZ_TRIGGERPOS,
d62d7ad1 43 SR_CONF_NUM_TIMEBASE,
c1bcb8cc 44 SR_CONF_LIMIT_FRAMES,
4914dd4b 45 SR_CONF_SAMPLERATE,
f48e0249
ML
46};
47
48static const int32_t analog_hwcaps[] = {
d62d7ad1 49 SR_CONF_NUM_VDIV,
f48e0249 50 SR_CONF_VDIV,
78bcc55a 51 SR_CONF_COUPLING,
babab622 52 SR_CONF_DATA_SOURCE,
e0b7d23c
ML
53};
54
f6a0ac9f 55static const uint64_t timebases[][2] = {
e0b7d23c 56 /* nanoseconds */
8e06edf5 57 { 1, 1000000000 },
e0b7d23c
ML
58 { 2, 1000000000 },
59 { 5, 1000000000 },
60 { 10, 1000000000 },
61 { 20, 1000000000 },
62 { 50, 1000000000 },
63 { 100, 1000000000 },
64 { 500, 1000000000 },
65 /* microseconds */
66 { 1, 1000000 },
67 { 2, 1000000 },
68 { 5, 1000000 },
69 { 10, 1000000 },
70 { 20, 1000000 },
71 { 50, 1000000 },
72 { 100, 1000000 },
73 { 200, 1000000 },
74 { 500, 1000000 },
75 /* milliseconds */
76 { 1, 1000 },
77 { 2, 1000 },
78 { 5, 1000 },
79 { 10, 1000 },
80 { 20, 1000 },
81 { 50, 1000 },
82 { 100, 1000 },
83 { 200, 1000 },
84 { 500, 1000 },
85 /* seconds */
86 { 1, 1 },
87 { 2, 1 },
88 { 5, 1 },
89 { 10, 1 },
90 { 20, 1 },
91 { 50, 1 },
bafd4890
ML
92 { 100, 1 },
93 { 200, 1 },
94 { 500, 1 },
8e06edf5 95 { 1000, 1 },
e0b7d23c
ML
96};
97
f6a0ac9f 98static const uint64_t vdivs[][2] = {
bafd4890
ML
99 /* microvolts */
100 { 500, 1000000 },
e0b7d23c 101 /* millivolts */
bafd4890 102 { 1, 1000 },
e0b7d23c
ML
103 { 2, 1000 },
104 { 5, 1000 },
105 { 10, 1000 },
106 { 20, 1000 },
107 { 50, 1000 },
108 { 100, 1000 },
109 { 200, 1000 },
110 { 500, 1000 },
111 /* volts */
112 { 1, 1 },
113 { 2, 1 },
114 { 5, 1 },
115 { 10, 1 },
e0b7d23c
ML
116};
117
bafd4890
ML
118#define NUM_TIMEBASE ARRAY_SIZE(timebases)
119#define NUM_VDIV ARRAY_SIZE(vdivs)
120
e0b7d23c
ML
121static const char *trigger_sources[] = {
122 "CH1",
123 "CH2",
821fbcad
ML
124 "CH3",
125 "CH4",
e0b7d23c
ML
126 "EXT",
127 "AC Line",
6bb192bc
ML
128 "D0",
129 "D1",
130 "D2",
131 "D3",
132 "D4",
133 "D5",
134 "D6",
135 "D7",
136 "D8",
137 "D9",
138 "D10",
139 "D11",
140 "D12",
141 "D13",
142 "D14",
143 "D15",
e0b7d23c
ML
144};
145
146static const char *coupling[] = {
147 "AC",
148 "DC",
149 "GND",
e0b7d23c
ML
150};
151
babab622
ML
152/* Do not change the order of entries */
153static const char *data_sources[] = {
154 "Live",
155 "Memory",
156 "Segmented",
157};
158
159/*
160 * name, series, protocol flavor, min timebase, max timebase, min vdiv,
161 * digital channels, number of horizontal divs
162 */
10afee13
ML
163
164#define RIGOL "Rigol Technologies"
165#define AGILENT "Agilent Technologies"
fcdebbe8
BV
166#define RIGOL_SHORT "Rigol"
167#define AGILENT_SHORT "Agilent"
10afee13 168
bafd4890 169static const struct rigol_ds_model supported_models[] = {
470140fc
ML
170 {RIGOL, "DS1052E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
171 {RIGOL, "DS1102E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
172 {RIGOL, "DS1152E", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
173 {RIGOL, "DS1052D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
174 {RIGOL, "DS1102D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
175 {RIGOL, "DS1152D", RIGOL_DS1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 12},
821fbcad
ML
176 {RIGOL, "DS2072", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
177 {RIGOL, "DS2102", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
178 {RIGOL, "DS2202", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {500, 1}, {500, 1000000}, 2, false, 14},
036d378a
AJ
179 {RIGOL, "DS2302", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
180 {RIGOL, "DS2072A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
181 {RIGOL, "DS2102A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {5, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
182 {RIGOL, "DS2202A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {2, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
183 {RIGOL, "DS2302A", RIGOL_DS2000, PROTOCOL_IEEE488_2, {1, 1000000000}, {1000, 1}, {500, 1000000}, 2, false, 14},
821fbcad
ML
184 {RIGOL, "VS5022", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
185 {RIGOL, "VS5022D", RIGOL_VS5000, PROTOCOL_LEGACY, {20, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
186 {RIGOL, "VS5042", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
187 {RIGOL, "VS5042D", RIGOL_VS5000, PROTOCOL_LEGACY, {10, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
188 {RIGOL, "VS5062", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
189 {RIGOL, "VS5062D", RIGOL_VS5000, PROTOCOL_LEGACY, {5, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
190 {RIGOL, "VS5102", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
191 {RIGOL, "VS5102D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
192 {RIGOL, "VS5202", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 14},
193 {RIGOL, "VS5202D", RIGOL_VS5000, PROTOCOL_LEGACY, {2, 1000000000}, {50, 1}, {2, 1000}, 2, true, 14},
227a0981
ML
194 {AGILENT, "DSO1002A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
195 {AGILENT, "DSO1004A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {5, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
196 {AGILENT, "DSO1012A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
821fbcad 197 {AGILENT, "DSO1014A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
227a0981
ML
198 {AGILENT, "DSO1022A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 2, false, 12},
199 {AGILENT, "DSO1024A", AGILENT_DSO1000, PROTOCOL_IEEE488_2, {2, 1000000000}, {50, 1}, {2, 1000}, 4, false, 12},
512bb890
BV
200};
201
3086efdd
ML
202SR_PRIV struct sr_dev_driver rigol_ds_driver_info;
203static struct sr_dev_driver *di = &rigol_ds_driver_info;
f4816ac6 204
fa85f376 205static void clear_helper(void *priv)
f4816ac6 206{
f4816ac6 207 struct dev_context *devc;
f4816ac6 208
ba358ffd 209 devc = priv;
babab622
ML
210 g_free(devc->data);
211 g_free(devc->buffer);
fa85f376
UH
212 g_free(devc->coupling[0]);
213 g_free(devc->coupling[1]);
214 g_free(devc->trigger_source);
215 g_free(devc->trigger_slope);
ba358ffd
BV
216 g_slist_free(devc->analog_groups[0].probes);
217 g_slist_free(devc->analog_groups[1].probes);
218 g_slist_free(devc->digital_group.probes);
fa85f376 219}
f4816ac6 220
3b412e3a 221static int dev_clear(void)
fa85f376
UH
222{
223 return std_dev_clear(di, clear_helper);
f4816ac6
ML
224}
225
254dd102
BV
226static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
227{
10d309c8 228 struct dev_context *devc = sdi->priv;
254dd102 229 va_list args;
4d7a9a14 230 int ret;
254dd102 231
254dd102 232 va_start(args, format);
4d7a9a14 233 ret = sr_scpi_send_variadic(sdi->conn, format, args);
254dd102 234 va_end(args);
4d7a9a14
ML
235
236 if (ret != SR_OK)
254dd102
BV
237 return SR_ERR;
238
10d309c8
ML
239 if (devc->model->series == RIGOL_DS1000) {
240 /* The DS1000 series needs this stupid delay, *OPC? doesn't work. */
241 sr_spew("delay %dms", 100);
242 g_usleep(100000);
243 return SR_OK;
244 } else {
245 return sr_scpi_get_opc(sdi->conn);
246 }
254dd102
BV
247}
248
6078d2c9 249static int init(struct sr_context *sr_ctx)
f4816ac6 250{
f6beaac5 251 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
252}
253
3520422f 254static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
f4816ac6 255{
cc9fd2d2
BV
256 struct dev_context *devc;
257 struct sr_dev_inst *sdi;
ae1bc1cc
ML
258 struct sr_scpi_dev_inst *scpi;
259 struct sr_scpi_hw_info *hw_info;
cc9fd2d2 260 struct sr_probe *probe;
8dd0b290 261 long n[3];
f6a0ac9f 262 unsigned int i;
bafd4890 263 const struct rigol_ds_model *model = NULL;
8dd0b290 264 gchar *channel_name, *vendor, **version;
fb6e5ba8 265
46a743c1 266 *devices = NULL;
0dc7b43e 267
c3515cea
AJ
268 if (!(scpi = scpi_dev_inst_new(resource, serialcomm)))
269 return SR_ERR;
9bd4c956 270
ae1bc1cc 271 if (sr_scpi_open(scpi) != SR_OK) {
10afee13 272 sr_info("Couldn't open SCPI device.");
ae1bc1cc 273 sr_scpi_free(scpi);
9bd4c956 274 return SR_ERR;
ae1bc1cc 275 };
9bd4c956 276
ae1bc1cc
ML
277 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
278 sr_info("Couldn't get IDN response.");
279 sr_scpi_close(scpi);
280 sr_scpi_free(scpi);
281 return SR_ERR;
ca55277c 282 }
e0b7d23c 283
ca55277c 284 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
10afee13
ML
285 if (!strcasecmp(hw_info->manufacturer, supported_models[i].vendor) &&
286 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 287 model = &supported_models[i];
ca55277c 288 break;
fb6e5ba8 289 }
ca55277c 290 }
fb6e5ba8 291
fcdebbe8
BV
292 if (!strcmp(hw_info->manufacturer, RIGOL))
293 vendor = RIGOL_SHORT;
294 else if (!strcmp(hw_info->manufacturer, AGILENT))
295 vendor = AGILENT_SHORT;
296 else
297 vendor = hw_info->manufacturer;
bafd4890 298 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
fcdebbe8 299 vendor, hw_info->model,
ae1bc1cc
ML
300 hw_info->firmware_version))) {
301 sr_scpi_hw_info_free(hw_info);
b4936bae 302 sr_scpi_close(scpi);
ae1bc1cc 303 sr_scpi_free(scpi);
ca55277c
ML
304 return SR_ERR_NA;
305 }
fb6e5ba8 306
b4936bae 307 sr_scpi_close(scpi);
ae1bc1cc
ML
308
309 sdi->conn = scpi;
fb6e5ba8 310
cc9fd2d2 311 sdi->driver = di;
ae1bc1cc 312 sdi->inst_type = SR_INST_SCPI;
512bb890 313
cc9fd2d2 314 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
ca55277c 315 return SR_ERR_MALLOC;
ae1bc1cc 316
cc9fd2d2 317 devc->limit_frames = 0;
bafd4890 318 devc->model = model;
8dd0b290
BV
319 devc->protocol = model->protocol;
320
321 /* DS1000 models with firmware before 0.2.4 used the old
322 * legacy protocol. */
323 if (model->series == RIGOL_DS1000) {
324 version = g_strsplit(hw_info->firmware_version, ".", 0);
325 do {
326 if (!version[0] || !version[1] || !version[2])
327 break;
328 if (version[0][0] == 0 || version[1][0] == 0 || version[2][0] == 0)
329 break;
330 for (i = 0; i < 3; i++) {
331 if (sr_atol(version[i], &n[i]) != SR_OK)
332 break;
333 }
334 if (i != 3)
335 break;
336 if (n[0] != 0 || n[1] > 2)
337 break;
338 if (n[1] == 2 && n[2] > 3)
339 break;
340 sr_dbg("Found DS1000 firmware < 0.2.4, using old protocol.");
341 devc->protocol = PROTOCOL_LEGACY;
342 } while(0);
343 g_strfreev(version);
344 }
345
346 sr_scpi_hw_info_free(hw_info);
512bb890 347
821fbcad
ML
348 for (i = 0; i < model->analog_channels; i++) {
349 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
ca55277c 350 return SR_ERR_MALLOC;
821fbcad 351 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
ca55277c 352 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
353 devc->analog_groups[i].name = channel_name;
354 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
355 sdi->probe_groups = g_slist_append(sdi->probe_groups,
356 &devc->analog_groups[i]);
ca55277c 357 }
512bb890 358
bafd4890 359 if (devc->model->has_digital) {
ca55277c
ML
360 for (i = 0; i < 16; i++) {
361 if (!(channel_name = g_strdup_printf("D%d", i)))
362 return SR_ERR_MALLOC;
363 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
364 g_free(channel_name);
365 if (!probe)
366 return SR_ERR_MALLOC;
367 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
368 devc->digital_group.probes = g_slist_append(
369 devc->digital_group.probes, probe);
512bb890 370 }
b3916147
ML
371 devc->digital_group.name = "LA";
372 sdi->probe_groups = g_slist_append(sdi->probe_groups,
373 &devc->digital_group);
ca55277c 374 }
bafd4890
ML
375
376 for (i = 0; i < NUM_TIMEBASE; i++) {
377 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
378 devc->timebases = &timebases[i];
379 if (!memcmp(&devc->model->max_timebase, &timebases[i], sizeof(uint64_t[2])))
380 devc->num_timebases = &timebases[i] - devc->timebases + 1;
381 }
382
0709197d
ML
383 for (i = 0; i < NUM_VDIV; i++)
384 if (!memcmp(&devc->model->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
6ff1394e 385 devc->vdivs = &vdivs[i];
bafd4890 386
babab622
ML
387 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
388 return SR_ERR_MALLOC;
389 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
390 return SR_ERR_MALLOC;
391
392 devc->data_source = DATA_SOURCE_LIVE;
393
cc9fd2d2
BV
394 sdi->priv = devc;
395
396 *devices = g_slist_append(NULL, sdi);
512bb890 397
ca55277c
ML
398 return SR_OK;
399}
512bb890 400
6078d2c9 401static GSList *scan(GSList *options)
ca55277c
ML
402{
403 struct drv_context *drvc;
ca55277c 404 struct sr_config *src;
cc9fd2d2 405 GSList *l, *devices;
ca55277c 406 GDir *dir;
ca55277c 407 int ret;
cc9fd2d2
BV
408 const gchar *dev_name;
409 gchar *port = NULL;
0dc7b43e 410 gchar *serialcomm = NULL;
fb6e5ba8 411
ca55277c 412 drvc = di->priv;
d2e0b1fa 413
ca55277c
ML
414 for (l = options; l; l = l->next) {
415 src = l->data;
0dc7b43e
ML
416 switch (src->key) {
417 case SR_CONF_CONN:
cc9fd2d2 418 port = (char *)g_variant_get_string(src->data, NULL);
ca55277c 419 break;
0dc7b43e
ML
420 case SR_CONF_SERIALCOMM:
421 serialcomm = (char *)g_variant_get_string(src->data, NULL);
422 break;
fb6e5ba8 423 }
ca55277c 424 }
fb6e5ba8 425
46a743c1 426 devices = NULL;
cc9fd2d2 427 if (port) {
0dc7b43e
ML
428 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
429 g_free(port);
430 if (serialcomm)
431 g_free(serialcomm);
ca55277c 432 return NULL;
0dc7b43e 433 }
ca55277c 434 } else {
da970d24
BV
435 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
436 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
437 return NULL;
ca55277c 438 while ((dev_name = g_dir_read_name(dir))) {
cc9fd2d2 439 if (strncmp(dev_name, "usbtmc", 6))
ca55277c 440 continue;
cc9fd2d2 441 port = g_strconcat("/dev/", dev_name, NULL);
0dc7b43e 442 ret = probe_port(port, serialcomm, &devices);
cc9fd2d2 443 g_free(port);
0dc7b43e
ML
444 if (serialcomm)
445 g_free(serialcomm);
ca55277c
ML
446 if (ret == SR_ERR_MALLOC) {
447 g_dir_close(dir);
ca55277c 448 return NULL;
6bb192bc
ML
449 }
450 }
ca55277c
ML
451 g_dir_close(dir);
452 }
f4816ac6 453
46a743c1
BV
454 /* Tack a copy of the newly found devices onto the driver list. */
455 l = g_slist_copy(devices);
456 drvc->instances = g_slist_concat(drvc->instances, l);
cc9fd2d2 457
f4816ac6
ML
458 return devices;
459}
460
6078d2c9 461static GSList *dev_list(void)
f4816ac6 462{
0e94d524 463 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
464}
465
6078d2c9 466static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 467{
ae1bc1cc 468 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 469
ae1bc1cc 470 if (sr_scpi_open(scpi) < 0)
e0b7d23c 471 return SR_ERR;
e0b7d23c 472
3086efdd 473 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
254dd102 474 return SR_ERR;
f4816ac6 475
46a743c1 476 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 477
f4816ac6
ML
478 return SR_OK;
479}
480
6078d2c9 481static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 482{
ae1bc1cc 483 struct sr_scpi_dev_inst *scpi;
22c19688 484 struct dev_context *devc;
ae1bc1cc
ML
485
486 scpi = sdi->conn;
22c19688
ML
487 devc = sdi->priv;
488
489 if (devc->model->series != RIGOL_VS5000)
490 set_cfg(sdi, ":KEY:LOCK DISABLE");
e0b7d23c 491
ae1bc1cc
ML
492 if (scpi) {
493 if (sr_scpi_close(scpi) < 0)
494 return SR_ERR;
cc9fd2d2
BV
495 sdi->status = SR_ST_INACTIVE;
496 }
f4816ac6
ML
497
498 return SR_OK;
499}
500
6078d2c9 501static int cleanup(void)
f4816ac6 502{
3b412e3a 503 return dev_clear();
f4816ac6
ML
504}
505
5415e602
ML
506static int analog_frame_size(const struct sr_dev_inst *sdi)
507{
508 struct dev_context *devc = sdi->priv;
509 struct sr_probe *probe;
510 int analog_probes = 0;
511 GSList *l;
512
470140fc
ML
513 switch (devc->model->series) {
514 case RIGOL_VS5000:
515 return VS5000_ANALOG_LIVE_WAVEFORM_SIZE;
516 case RIGOL_DS1000:
517 return DS1000_ANALOG_LIVE_WAVEFORM_SIZE;
518 default:
5415e602
ML
519 for (l = sdi->probes; l; l = l->next) {
520 probe = l->data;
521 if (probe->type == SR_PROBE_ANALOG && probe->enabled)
522 analog_probes++;
523 }
524 if (devc->data_source == DATA_SOURCE_MEMORY) {
525 if (analog_probes == 1)
526 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
527 else
528 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
529 } else {
530 if (devc->model->series == AGILENT_DSO1000)
531 return DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
532 else
533 return DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
534 }
535 }
536}
537
d22250a9
ML
538static int digital_frame_size(const struct sr_dev_inst *sdi)
539{
540 struct dev_context *devc = sdi->priv;
541
542 switch (devc->model->series) {
543 case RIGOL_VS5000:
544 return VS5000_DIGITAL_WAVEFORM_SIZE;
545 case RIGOL_DS1000:
546 return DS1000_DIGITAL_WAVEFORM_SIZE;
547 default:
548 return 0;
549 }
550}
551
8f996b89
ML
552static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
553 const struct sr_probe_group *probe_group)
d62d7ad1 554{
e43fdd8d 555 struct dev_context *devc;
2b0e4a46
AJ
556 struct sr_probe *probe;
557 const char *tmp_str;
c2b394d5 558 uint64_t samplerate;
2b0e4a46
AJ
559 int analog_channel = -1;
560 float smallest_diff = 0.0000000001;
561 int idx = -1;
562 unsigned i;
d62d7ad1 563
e43fdd8d
BV
564 if (!sdi || !(devc = sdi->priv))
565 return SR_ERR_ARG;
566
be60a9e4 567 /* If a probe group is specified, it must be a valid one. */
c2b394d5 568 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
569 sr_err("Invalid probe group specified.");
570 return SR_ERR;
be60a9e4
BV
571 }
572
2b0e4a46
AJ
573 if (probe_group) {
574 probe = g_slist_nth_data(probe_group->probes, 0);
575 if (!probe)
576 return SR_ERR;
577 if (probe->type == SR_PROBE_ANALOG) {
578 if (probe->name[2] < '1' || probe->name[2] > '4')
579 return SR_ERR;
580 analog_channel = probe->name[2] - '1';
581 }
582 }
583
d62d7ad1
BV
584 switch (id) {
585 case SR_CONF_NUM_TIMEBASE:
0709197d 586 *data = g_variant_new_int32(devc->model->num_horizontal_divs);
d62d7ad1
BV
587 break;
588 case SR_CONF_NUM_VDIV:
72ecba02 589 *data = g_variant_new_int32(NUM_VDIV);
babab622
ML
590 case SR_CONF_DATA_SOURCE:
591 if (devc->data_source == DATA_SOURCE_LIVE)
592 *data = g_variant_new_string("Live");
593 else if (devc->data_source == DATA_SOURCE_MEMORY)
594 *data = g_variant_new_string("Memory");
595 else
596 *data = g_variant_new_string("Segmented");
597 break;
4914dd4b
ML
598 case SR_CONF_SAMPLERATE:
599 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 600 samplerate = analog_frame_size(sdi) /
4914dd4b
ML
601 (devc->timebase * devc->model->num_horizontal_divs);
602 *data = g_variant_new_uint64(samplerate);
c2b394d5 603 } else {
4914dd4b 604 return SR_ERR_NA;
c2b394d5 605 }
4914dd4b 606 break;
2b0e4a46
AJ
607 case SR_CONF_TRIGGER_SOURCE:
608 if (!strcmp(devc->trigger_source, "ACL"))
609 tmp_str = "AC Line";
610 else if (!strcmp(devc->trigger_source, "CHAN1"))
611 tmp_str = "CH1";
612 else if (!strcmp(devc->trigger_source, "CHAN2"))
613 tmp_str = "CH2";
614 else if (!strcmp(devc->trigger_source, "CHAN3"))
615 tmp_str = "CH3";
616 else if (!strcmp(devc->trigger_source, "CHAN4"))
617 tmp_str = "CH4";
618 else
619 tmp_str = devc->trigger_source;
620 *data = g_variant_new_string(tmp_str);
621 break;
622 case SR_CONF_TIMEBASE:
623 for (i = 0; i < devc->num_timebases; i++) {
624 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
625 float diff = fabs(devc->timebase - tb);
626 if (diff < smallest_diff) {
627 smallest_diff = diff;
628 idx = i;
629 }
630 }
631 if (idx < 0)
632 return SR_ERR_NA;
633 *data = g_variant_new("(tt)", devc->timebases[idx][0],
634 devc->timebases[idx][1]);
635 break;
636 case SR_CONF_VDIV:
637 if (analog_channel < 0)
638 return SR_ERR_NA;
639 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
640 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
641 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
642 if (diff < smallest_diff) {
643 smallest_diff = diff;
644 idx = i;
645 }
646 }
647 if (idx < 0)
648 return SR_ERR_NA;
649 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
650 break;
651 case SR_CONF_COUPLING:
652 if (analog_channel < 0)
653 return SR_ERR_NA;
654 *data = g_variant_new_string(devc->coupling[analog_channel]);
655 break;
d62d7ad1 656 default:
bd6fbf62 657 return SR_ERR_NA;
d62d7ad1
BV
658 }
659
660 return SR_OK;
661}
662
8f996b89
ML
663static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
664 const struct sr_probe_group *probe_group)
f4816ac6 665{
29d957ce 666 struct dev_context *devc;
f6a0ac9f 667 uint64_t tmp_u64, p, q;
254dd102 668 double t_dbl;
f48e0249 669 unsigned int i, j;
254dd102
BV
670 int ret;
671 const char *tmp_str;
889ef4a0 672 char buffer[16];
f4816ac6 673
e43fdd8d
BV
674 if (!(devc = sdi->priv))
675 return SR_ERR_ARG;
29d957ce 676
e73ffd42
BV
677 if (sdi->status != SR_ST_ACTIVE)
678 return SR_ERR_DEV_CLOSED;
f4816ac6 679
be60a9e4 680 /* If a probe group is specified, it must be a valid one. */
c2b394d5 681 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
682 sr_err("Invalid probe group specified.");
683 return SR_ERR;
be60a9e4
BV
684 }
685
f4816ac6 686 ret = SR_OK;
035a1078 687 switch (id) {
1953564a 688 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 689 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 690 break;
1953564a 691 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 692 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
693 if (tmp_u64 != 0 && tmp_u64 != 1)
694 return SR_ERR;
695 g_free(devc->trigger_slope);
696 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
697 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 698 break;
1953564a 699 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
700 t_dbl = g_variant_get_double(data);
701 if (t_dbl < 0.0 || t_dbl > 1.0)
702 return SR_ERR;
703 devc->horiz_triggerpos = t_dbl;
704 /* We have the trigger offset as a percentage of the frame, but
705 * need to express this in seconds. */
bafd4890 706 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
889ef4a0
AJ
707 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
708 ret = set_cfg(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 709 break;
1953564a 710 case SR_CONF_TIMEBASE:
f6a0ac9f 711 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
712 for (i = 0; i < devc->num_timebases; i++) {
713 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 714 devc->timebase = (float)p / q;
889ef4a0
AJ
715 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
716 devc->timebase);
717 ret = set_cfg(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
718 break;
719 }
720 }
bafd4890 721 if (i == devc->num_timebases)
254dd102 722 ret = SR_ERR_ARG;
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;
742 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
743 break;
744 }
4e108ace 745 }
254dd102
BV
746 if (i == ARRAY_SIZE(trigger_sources))
747 ret = SR_ERR_ARG;
e0b7d23c 748 break;
1953564a 749 case SR_CONF_VDIV:
be60a9e4
BV
750 if (!probe_group) {
751 sr_err("No probe group specified.");
752 return SR_ERR_PROBE_GROUP;
753 }
f6a0ac9f 754 g_variant_get(data, "(tt)", &p, &q);
f48e0249 755 for (i = 0; i < 2; i++) {
78bcc55a
BV
756 if (probe_group == &devc->analog_groups[i]) {
757 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
758 if (vdivs[j][0] != p || vdivs[j][1] != q)
759 continue;
760 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
761 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
762 devc->vdiv[i]);
763 return set_cfg(sdi, ":CHAN%d:SCAL %s", i + 1,
764 buffer);
f48e0249
ML
765 }
766 return SR_ERR_ARG;
767 }
e0b7d23c 768 }
f48e0249 769 return SR_ERR_NA;
1953564a 770 case SR_CONF_COUPLING:
78bcc55a
BV
771 if (!probe_group) {
772 sr_err("No probe group specified.");
773 return SR_ERR_PROBE_GROUP;
774 }
f6a0ac9f 775 tmp_str = g_variant_get_string(data, NULL);
f48e0249 776 for (i = 0; i < 2; i++) {
78bcc55a
BV
777 if (probe_group == &devc->analog_groups[i]) {
778 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
779 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
780 g_free(devc->coupling[i]);
781 devc->coupling[i] = g_strdup(coupling[j]);
782 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
783 devc->coupling[i]);
784 }
785 }
786 return SR_ERR_ARG;
e0b7d23c
ML
787 }
788 }
f48e0249 789 return SR_ERR_NA;
babab622
ML
790 case SR_CONF_DATA_SOURCE:
791 tmp_str = g_variant_get_string(data, NULL);
792 if (!strcmp(tmp_str, "Live"))
793 devc->data_source = DATA_SOURCE_LIVE;
794 else if (!strcmp(tmp_str, "Memory"))
795 devc->data_source = DATA_SOURCE_MEMORY;
470140fc 796 else if (devc->model->series >= RIGOL_DS1000Z
babab622
ML
797 && !strcmp(tmp_str, "Segmented"))
798 devc->data_source = DATA_SOURCE_SEGMENTED;
799 else
800 return SR_ERR;
801 break;
f4816ac6 802 default:
bd6fbf62 803 ret = SR_ERR_NA;
29d957ce 804 break;
f4816ac6
ML
805 }
806
807 return ret;
808}
809
8f996b89
ML
810static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
811 const struct sr_probe_group *probe_group)
a1c743fc 812{
861c447b
BV
813 GVariant *tuple, *rational[2];
814 GVariantBuilder gvb;
815 unsigned int i;
7cc1a550
ML
816 struct dev_context *devc = NULL;
817
818 if (sdi)
819 devc = sdi->priv;
8f996b89 820
e43fdd8d 821 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
822 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
823 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
824 return SR_OK;
825 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
826 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
827 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
828 return SR_OK;
829 }
830
831 /* Every other option requires a valid device instance. */
832 if (!sdi || !(devc = sdi->priv))
833 return SR_ERR_ARG;
834
be60a9e4
BV
835 /* If a probe group is specified, it must be a valid one. */
836 if (probe_group) {
837 if (probe_group != &devc->analog_groups[0]
838 && probe_group != &devc->analog_groups[1]) {
839 sr_err("Invalid probe group specified.");
840 return SR_ERR;
841 }
842 }
843
e43fdd8d 844 switch (key) {
9a6517d1 845 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
846 if (!probe_group) {
847 sr_err("No probe group specified.");
848 return SR_ERR_PROBE_GROUP;
849 }
e43fdd8d 850 if (probe_group == &devc->digital_group) {
f48e0249
ML
851 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
852 NULL, 0, sizeof(int32_t));
853 return SR_OK;
854 } else {
855 for (i = 0; i < 2; i++) {
856 if (probe_group == &devc->analog_groups[i]) {
857 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
858 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
859 return SR_OK;
860 }
861 }
862 return SR_ERR_NA;
863 }
5f77dffc 864 break;
2a7b113d 865 case SR_CONF_COUPLING:
be60a9e4
BV
866 if (!probe_group) {
867 sr_err("No probe group specified.");
868 return SR_ERR_PROBE_GROUP;
f48e0249 869 }
58f43369
BV
870 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
871 break;
e4f2b2ad 872 case SR_CONF_VDIV:
7cc1a550
ML
873 if (!devc)
874 /* Can't know this until we have the exact model. */
875 return SR_ERR_ARG;
be60a9e4
BV
876 if (!probe_group) {
877 sr_err("No probe group specified.");
878 return SR_ERR_PROBE_GROUP;
861c447b 879 }
58f43369 880 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 881 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
882 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
883 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
884 tuple = g_variant_new_tuple(rational, 2);
885 g_variant_builder_add_value(&gvb, tuple);
886 }
887 *data = g_variant_builder_end(&gvb);
888 break;
41f5bd09 889 case SR_CONF_TIMEBASE:
7cc1a550
ML
890 if (!devc)
891 /* Can't know this until we have the exact model. */
892 return SR_ERR_ARG;
a31b2ccb
AJ
893 if (devc->num_timebases <= 0)
894 return SR_ERR_NA;
861c447b 895 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
896 for (i = 0; i < devc->num_timebases; i++) {
897 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
898 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
899 tuple = g_variant_new_tuple(rational, 2);
900 g_variant_builder_add_value(&gvb, tuple);
901 }
902 *data = g_variant_builder_end(&gvb);
41f5bd09 903 break;
328bafab 904 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
905 if (!devc)
906 /* Can't know this until we have the exact model. */
907 return SR_ERR_ARG;
f6a0ac9f 908 *data = g_variant_new_strv(trigger_sources,
bafd4890 909 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 910 break;
babab622
ML
911 case SR_CONF_DATA_SOURCE:
912 if (!devc)
913 /* Can't know this until we have the exact model. */
914 return SR_ERR_ARG;
915 /* This needs tweaking by series/model! */
916 if (devc->model->series == RIGOL_DS2000)
917 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
918 else
919 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
920 break;
a1c743fc 921 default:
bd6fbf62 922 return SR_ERR_NA;
a1c743fc
BV
923 }
924
925 return SR_OK;
926}
927
254dd102 928static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 929{
ae1bc1cc 930 struct sr_scpi_dev_inst *scpi;
29d957ce 931 struct dev_context *devc;
254dd102 932 struct sr_probe *probe;
f76c24f6 933 struct sr_datafeed_packet packet;
254dd102 934 GSList *l;
29d957ce 935
e73ffd42
BV
936 if (sdi->status != SR_ST_ACTIVE)
937 return SR_ERR_DEV_CLOSED;
e0b7d23c 938
ae1bc1cc 939 scpi = sdi->conn;
29d957ce
UH
940 devc = sdi->priv;
941
51b294cd
ML
942 devc->num_frames = 0;
943
254dd102
BV
944 for (l = sdi->probes; l; l = l->next) {
945 probe = l->data;
6bb192bc
ML
946 sr_dbg("handling probe %s", probe->name);
947 if (probe->type == SR_PROBE_ANALOG) {
948 if (probe->enabled)
949 devc->enabled_analog_probes = g_slist_append(
950 devc->enabled_analog_probes, probe);
951 if (probe->enabled != devc->analog_channels[probe->index]) {
952 /* Enabled channel is currently disabled, or vice versa. */
6396b0a7
ML
953 if (set_cfg(sdi, ":CHAN%d:DISP %s", probe->index + 1,
954 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 955 return SR_ERR;
904fd29b 956 devc->analog_channels[probe->index] = probe->enabled;
6bb192bc
ML
957 }
958 } else if (probe->type == SR_PROBE_LOGIC) {
04e8e01e 959 if (probe->enabled) {
6bb192bc
ML
960 devc->enabled_digital_probes = g_slist_append(
961 devc->enabled_digital_probes, probe);
04e8e01e
ML
962 /* Turn on LA module if currently off. */
963 if (!devc->la_enabled) {
964 if (set_cfg(sdi, ":LA:DISP ON") != SR_OK)
965 return SR_ERR;
966 devc->la_enabled = TRUE;
967 }
968 }
6bb192bc
ML
969 if (probe->enabled != devc->digital_channels[probe->index]) {
970 /* Enabled channel is currently disabled, or vice versa. */
6396b0a7
ML
971 if (set_cfg(sdi, ":DIG%d:TURN %s", probe->index,
972 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 973 return SR_ERR;
904fd29b 974 devc->digital_channels[probe->index] = probe->enabled;
6bb192bc 975 }
254dd102
BV
976 }
977 }
1fed20cb 978
6bb192bc 979 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 980 return SR_ERR;
e0b7d23c 981
04e8e01e
ML
982 /* Turn off LA module if on and no digital probes selected. */
983 if (devc->la_enabled && !devc->enabled_digital_probes)
984 if (set_cfg(sdi, ":LA:DISP OFF") != SR_OK)
985 return SR_ERR;
986
1fed20cb 987 if (devc->data_source == DATA_SOURCE_LIVE) {
6396b0a7 988 if (set_cfg(sdi, ":RUN") != SR_OK)
1fed20cb
ML
989 return SR_ERR;
990 } else if (devc->data_source == DATA_SOURCE_MEMORY) {
991 if (devc->model->series != RIGOL_DS2000) {
992 sr_err("Data source 'Memory' not supported for this device");
993 return SR_ERR;
994 }
995 } else if (devc->data_source == DATA_SOURCE_SEGMENTED) {
996 sr_err("Data source 'Segmented' not yet supported");
997 return SR_ERR;
998 }
999
ae1bc1cc 1000 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
1001
1002 /* Send header packet to the session bus. */
29a27196 1003 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 1004
821fbcad
ML
1005 if (devc->enabled_analog_probes)
1006 devc->channel_entry = devc->enabled_analog_probes;
1007 else
1008 devc->channel_entry = devc->enabled_digital_probes;
1009
5415e602 1010 devc->analog_frame_size = analog_frame_size(sdi);
d22250a9 1011 devc->digital_frame_size = digital_frame_size(sdi);
5415e602 1012
470140fc 1013 if (devc->model->series < RIGOL_DS1000Z) {
bafd4890 1014 /* Fetch the first frame. */
677f85d0
ML
1015 if (rigol_ds_channel_start(sdi) != SR_OK)
1016 return SR_ERR;
6bb192bc 1017 } else {
bafd4890 1018 if (devc->enabled_analog_probes) {
c2b394d5 1019 if (devc->data_source == DATA_SOURCE_MEMORY) {
babab622
ML
1020 /* Apparently for the DS2000 the memory
1021 * depth can only be set in Running state -
1022 * this matches the behaviour of the UI. */
6396b0a7 1023 if (set_cfg(sdi, ":RUN") != SR_OK)
babab622 1024 return SR_ERR;
6396b0a7 1025 if (set_cfg(sdi, "ACQ:MDEP %d", devc->analog_frame_size) != SR_OK)
babab622 1026 return SR_ERR;
6396b0a7 1027 if (set_cfg(sdi, ":STOP") != SR_OK)
babab622 1028 return SR_ERR;
0d9f5a12 1029 }
babab622 1030 if (rigol_ds_capture_start(sdi) != SR_OK)
bafd4890
ML
1031 return SR_ERR;
1032 }
6bb192bc 1033 }
f4816ac6 1034
f76c24f6
ML
1035 /* Start of first frame. */
1036 packet.type = SR_DF_FRAME_BEGIN;
1037 sr_session_send(cb_data, &packet);
1038
f4816ac6
ML
1039 return SR_OK;
1040}
1041
254dd102 1042static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 1043{
29d957ce 1044 struct dev_context *devc;
ae1bc1cc 1045 struct sr_scpi_dev_inst *scpi;
b751cf7a 1046 struct sr_datafeed_packet packet;
29d957ce 1047
f4816ac6
ML
1048 (void)cb_data;
1049
29d957ce
UH
1050 devc = sdi->priv;
1051
f4816ac6
ML
1052 if (sdi->status != SR_ST_ACTIVE) {
1053 sr_err("Device inactive, can't stop acquisition.");
1054 return SR_ERR;
1055 }
1056
b751cf7a
ML
1057 /* End of last frame. */
1058 packet.type = SR_DF_END;
1059 sr_session_send(sdi, &packet);
1060
6bb192bc
ML
1061 g_slist_free(devc->enabled_analog_probes);
1062 g_slist_free(devc->enabled_digital_probes);
1063 devc->enabled_analog_probes = NULL;
1064 devc->enabled_digital_probes = NULL;
ae1bc1cc
ML
1065 scpi = sdi->conn;
1066 sr_scpi_source_remove(scpi);
f4816ac6
ML
1067
1068 return SR_OK;
1069}
1070
3086efdd
ML
1071SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1072 .name = "rigol-ds",
1073 .longname = "Rigol DS",
f4816ac6 1074 .api_version = 1,
6078d2c9
UH
1075 .init = init,
1076 .cleanup = cleanup,
1077 .scan = scan,
1078 .dev_list = dev_list,
3b412e3a 1079 .dev_clear = dev_clear,
d62d7ad1 1080 .config_get = config_get,
035a1078 1081 .config_set = config_set,
a1c743fc 1082 .config_list = config_list,
6078d2c9
UH
1083 .dev_open = dev_open,
1084 .dev_close = dev_close,
254dd102
BV
1085 .dev_acquisition_start = dev_acquisition_start,
1086 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1087 .priv = NULL,
1088};