]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
brymen-dmm: Make protocol parser locale-independent.
[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
ML
483 struct sr_scpi_dev_inst *scpi;
484
485 scpi = sdi->conn;
e0b7d23c 486
ae1bc1cc
ML
487 if (scpi) {
488 if (sr_scpi_close(scpi) < 0)
489 return SR_ERR;
cc9fd2d2
BV
490 sdi->status = SR_ST_INACTIVE;
491 }
f4816ac6
ML
492
493 return SR_OK;
494}
495
6078d2c9 496static int cleanup(void)
f4816ac6 497{
3b412e3a 498 return dev_clear();
f4816ac6
ML
499}
500
5415e602
ML
501static int analog_frame_size(const struct sr_dev_inst *sdi)
502{
503 struct dev_context *devc = sdi->priv;
504 struct sr_probe *probe;
505 int analog_probes = 0;
506 GSList *l;
507
470140fc
ML
508 switch (devc->model->series) {
509 case RIGOL_VS5000:
510 return VS5000_ANALOG_LIVE_WAVEFORM_SIZE;
511 case RIGOL_DS1000:
512 return DS1000_ANALOG_LIVE_WAVEFORM_SIZE;
513 default:
5415e602
ML
514 for (l = sdi->probes; l; l = l->next) {
515 probe = l->data;
516 if (probe->type == SR_PROBE_ANALOG && probe->enabled)
517 analog_probes++;
518 }
519 if (devc->data_source == DATA_SOURCE_MEMORY) {
520 if (analog_probes == 1)
521 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
522 else
523 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
524 } else {
525 if (devc->model->series == AGILENT_DSO1000)
526 return DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
527 else
528 return DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
529 }
530 }
531}
532
d22250a9
ML
533static int digital_frame_size(const struct sr_dev_inst *sdi)
534{
535 struct dev_context *devc = sdi->priv;
536
537 switch (devc->model->series) {
538 case RIGOL_VS5000:
539 return VS5000_DIGITAL_WAVEFORM_SIZE;
540 case RIGOL_DS1000:
541 return DS1000_DIGITAL_WAVEFORM_SIZE;
542 default:
543 return 0;
544 }
545}
546
8f996b89
ML
547static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
548 const struct sr_probe_group *probe_group)
d62d7ad1 549{
e43fdd8d 550 struct dev_context *devc;
2b0e4a46
AJ
551 struct sr_probe *probe;
552 const char *tmp_str;
c2b394d5 553 uint64_t samplerate;
2b0e4a46
AJ
554 int analog_channel = -1;
555 float smallest_diff = 0.0000000001;
556 int idx = -1;
557 unsigned i;
d62d7ad1 558
e43fdd8d
BV
559 if (!sdi || !(devc = sdi->priv))
560 return SR_ERR_ARG;
561
be60a9e4 562 /* If a probe group is specified, it must be a valid one. */
c2b394d5 563 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
564 sr_err("Invalid probe group specified.");
565 return SR_ERR;
be60a9e4
BV
566 }
567
2b0e4a46
AJ
568 if (probe_group) {
569 probe = g_slist_nth_data(probe_group->probes, 0);
570 if (!probe)
571 return SR_ERR;
572 if (probe->type == SR_PROBE_ANALOG) {
573 if (probe->name[2] < '1' || probe->name[2] > '4')
574 return SR_ERR;
575 analog_channel = probe->name[2] - '1';
576 }
577 }
578
d62d7ad1
BV
579 switch (id) {
580 case SR_CONF_NUM_TIMEBASE:
0709197d 581 *data = g_variant_new_int32(devc->model->num_horizontal_divs);
d62d7ad1
BV
582 break;
583 case SR_CONF_NUM_VDIV:
72ecba02 584 *data = g_variant_new_int32(NUM_VDIV);
babab622
ML
585 case SR_CONF_DATA_SOURCE:
586 if (devc->data_source == DATA_SOURCE_LIVE)
587 *data = g_variant_new_string("Live");
588 else if (devc->data_source == DATA_SOURCE_MEMORY)
589 *data = g_variant_new_string("Memory");
590 else
591 *data = g_variant_new_string("Segmented");
592 break;
4914dd4b
ML
593 case SR_CONF_SAMPLERATE:
594 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 595 samplerate = analog_frame_size(sdi) /
4914dd4b
ML
596 (devc->timebase * devc->model->num_horizontal_divs);
597 *data = g_variant_new_uint64(samplerate);
c2b394d5 598 } else {
4914dd4b 599 return SR_ERR_NA;
c2b394d5 600 }
4914dd4b 601 break;
2b0e4a46
AJ
602 case SR_CONF_TRIGGER_SOURCE:
603 if (!strcmp(devc->trigger_source, "ACL"))
604 tmp_str = "AC Line";
605 else if (!strcmp(devc->trigger_source, "CHAN1"))
606 tmp_str = "CH1";
607 else if (!strcmp(devc->trigger_source, "CHAN2"))
608 tmp_str = "CH2";
609 else if (!strcmp(devc->trigger_source, "CHAN3"))
610 tmp_str = "CH3";
611 else if (!strcmp(devc->trigger_source, "CHAN4"))
612 tmp_str = "CH4";
613 else
614 tmp_str = devc->trigger_source;
615 *data = g_variant_new_string(tmp_str);
616 break;
617 case SR_CONF_TIMEBASE:
618 for (i = 0; i < devc->num_timebases; i++) {
619 float tb = (float)devc->timebases[i][0] / devc->timebases[i][1];
620 float diff = fabs(devc->timebase - tb);
621 if (diff < smallest_diff) {
622 smallest_diff = diff;
623 idx = i;
624 }
625 }
626 if (idx < 0)
627 return SR_ERR_NA;
628 *data = g_variant_new("(tt)", devc->timebases[idx][0],
629 devc->timebases[idx][1]);
630 break;
631 case SR_CONF_VDIV:
632 if (analog_channel < 0)
633 return SR_ERR_NA;
634 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
635 float vdiv = (float)vdivs[i][0] / vdivs[i][1];
636 float diff = fabs(devc->vdiv[analog_channel] - vdiv);
637 if (diff < smallest_diff) {
638 smallest_diff = diff;
639 idx = i;
640 }
641 }
642 if (idx < 0)
643 return SR_ERR_NA;
644 *data = g_variant_new("(tt)", vdivs[idx][0], vdivs[idx][1]);
645 break;
646 case SR_CONF_COUPLING:
647 if (analog_channel < 0)
648 return SR_ERR_NA;
649 *data = g_variant_new_string(devc->coupling[analog_channel]);
650 break;
d62d7ad1 651 default:
bd6fbf62 652 return SR_ERR_NA;
d62d7ad1
BV
653 }
654
655 return SR_OK;
656}
657
8f996b89
ML
658static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
659 const struct sr_probe_group *probe_group)
f4816ac6 660{
29d957ce 661 struct dev_context *devc;
f6a0ac9f 662 uint64_t tmp_u64, p, q;
254dd102 663 double t_dbl;
f48e0249 664 unsigned int i, j;
254dd102
BV
665 int ret;
666 const char *tmp_str;
889ef4a0 667 char buffer[16];
f4816ac6 668
e43fdd8d
BV
669 if (!(devc = sdi->priv))
670 return SR_ERR_ARG;
29d957ce 671
e73ffd42
BV
672 if (sdi->status != SR_ST_ACTIVE)
673 return SR_ERR_DEV_CLOSED;
f4816ac6 674
be60a9e4 675 /* If a probe group is specified, it must be a valid one. */
c2b394d5 676 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
677 sr_err("Invalid probe group specified.");
678 return SR_ERR;
be60a9e4
BV
679 }
680
f4816ac6 681 ret = SR_OK;
035a1078 682 switch (id) {
1953564a 683 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 684 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 685 break;
1953564a 686 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 687 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
688 if (tmp_u64 != 0 && tmp_u64 != 1)
689 return SR_ERR;
690 g_free(devc->trigger_slope);
691 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
692 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 693 break;
1953564a 694 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
695 t_dbl = g_variant_get_double(data);
696 if (t_dbl < 0.0 || t_dbl > 1.0)
697 return SR_ERR;
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
AJ
702 g_ascii_formatd(buffer, sizeof(buffer), "%.6f", t_dbl);
703 ret = set_cfg(sdi, ":TIM:OFFS %s", buffer);
e0b7d23c 704 break;
1953564a 705 case SR_CONF_TIMEBASE:
f6a0ac9f 706 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
707 for (i = 0; i < devc->num_timebases; i++) {
708 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102 709 devc->timebase = (float)p / q;
889ef4a0
AJ
710 g_ascii_formatd(buffer, sizeof(buffer), "%.9f",
711 devc->timebase);
712 ret = set_cfg(sdi, ":TIM:SCAL %s", buffer);
f6a0ac9f
BV
713 break;
714 }
715 }
bafd4890 716 if (i == devc->num_timebases)
254dd102 717 ret = SR_ERR_ARG;
e0b7d23c 718 break;
1953564a 719 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 720 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
721 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
722 if (!strcmp(trigger_sources[i], tmp_str)) {
723 g_free(devc->trigger_source);
724 devc->trigger_source = g_strdup(trigger_sources[i]);
725 if (!strcmp(devc->trigger_source, "AC Line"))
726 tmp_str = "ACL";
727 else if (!strcmp(devc->trigger_source, "CH1"))
728 tmp_str = "CHAN1";
729 else if (!strcmp(devc->trigger_source, "CH2"))
730 tmp_str = "CHAN2";
821fbcad
ML
731 else if (!strcmp(devc->trigger_source, "CH3"))
732 tmp_str = "CHAN3";
733 else if (!strcmp(devc->trigger_source, "CH4"))
734 tmp_str = "CHAN4";
254dd102
BV
735 else
736 tmp_str = (char *)devc->trigger_source;
737 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
738 break;
739 }
4e108ace 740 }
254dd102
BV
741 if (i == ARRAY_SIZE(trigger_sources))
742 ret = SR_ERR_ARG;
e0b7d23c 743 break;
1953564a 744 case SR_CONF_VDIV:
be60a9e4
BV
745 if (!probe_group) {
746 sr_err("No probe group specified.");
747 return SR_ERR_PROBE_GROUP;
748 }
f6a0ac9f 749 g_variant_get(data, "(tt)", &p, &q);
f48e0249 750 for (i = 0; i < 2; i++) {
78bcc55a
BV
751 if (probe_group == &devc->analog_groups[i]) {
752 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
753 if (vdivs[j][0] != p || vdivs[j][1] != q)
754 continue;
755 devc->vdiv[i] = (float)p / q;
889ef4a0
AJ
756 g_ascii_formatd(buffer, sizeof(buffer), "%.3f",
757 devc->vdiv[i]);
758 return set_cfg(sdi, ":CHAN%d:SCAL %s", i + 1,
759 buffer);
f48e0249
ML
760 }
761 return SR_ERR_ARG;
762 }
e0b7d23c 763 }
f48e0249 764 return SR_ERR_NA;
1953564a 765 case SR_CONF_COUPLING:
78bcc55a
BV
766 if (!probe_group) {
767 sr_err("No probe group specified.");
768 return SR_ERR_PROBE_GROUP;
769 }
f6a0ac9f 770 tmp_str = g_variant_get_string(data, NULL);
f48e0249 771 for (i = 0; i < 2; i++) {
78bcc55a
BV
772 if (probe_group == &devc->analog_groups[i]) {
773 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
774 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
775 g_free(devc->coupling[i]);
776 devc->coupling[i] = g_strdup(coupling[j]);
777 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
778 devc->coupling[i]);
779 }
780 }
781 return SR_ERR_ARG;
e0b7d23c
ML
782 }
783 }
f48e0249 784 return SR_ERR_NA;
babab622
ML
785 case SR_CONF_DATA_SOURCE:
786 tmp_str = g_variant_get_string(data, NULL);
787 if (!strcmp(tmp_str, "Live"))
788 devc->data_source = DATA_SOURCE_LIVE;
789 else if (!strcmp(tmp_str, "Memory"))
790 devc->data_source = DATA_SOURCE_MEMORY;
470140fc 791 else if (devc->model->series >= RIGOL_DS1000Z
babab622
ML
792 && !strcmp(tmp_str, "Segmented"))
793 devc->data_source = DATA_SOURCE_SEGMENTED;
794 else
795 return SR_ERR;
796 break;
f4816ac6 797 default:
bd6fbf62 798 ret = SR_ERR_NA;
29d957ce 799 break;
f4816ac6
ML
800 }
801
802 return ret;
803}
804
8f996b89
ML
805static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
806 const struct sr_probe_group *probe_group)
a1c743fc 807{
861c447b
BV
808 GVariant *tuple, *rational[2];
809 GVariantBuilder gvb;
810 unsigned int i;
7cc1a550
ML
811 struct dev_context *devc = NULL;
812
813 if (sdi)
814 devc = sdi->priv;
8f996b89 815
e43fdd8d 816 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
817 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
818 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
819 return SR_OK;
820 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
821 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
822 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
823 return SR_OK;
824 }
825
826 /* Every other option requires a valid device instance. */
827 if (!sdi || !(devc = sdi->priv))
828 return SR_ERR_ARG;
829
be60a9e4
BV
830 /* If a probe group is specified, it must be a valid one. */
831 if (probe_group) {
832 if (probe_group != &devc->analog_groups[0]
833 && probe_group != &devc->analog_groups[1]) {
834 sr_err("Invalid probe group specified.");
835 return SR_ERR;
836 }
837 }
838
e43fdd8d 839 switch (key) {
9a6517d1 840 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
841 if (!probe_group) {
842 sr_err("No probe group specified.");
843 return SR_ERR_PROBE_GROUP;
844 }
e43fdd8d 845 if (probe_group == &devc->digital_group) {
f48e0249
ML
846 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
847 NULL, 0, sizeof(int32_t));
848 return SR_OK;
849 } else {
850 for (i = 0; i < 2; i++) {
851 if (probe_group == &devc->analog_groups[i]) {
852 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
853 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
854 return SR_OK;
855 }
856 }
857 return SR_ERR_NA;
858 }
5f77dffc 859 break;
2a7b113d 860 case SR_CONF_COUPLING:
be60a9e4
BV
861 if (!probe_group) {
862 sr_err("No probe group specified.");
863 return SR_ERR_PROBE_GROUP;
f48e0249 864 }
58f43369
BV
865 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
866 break;
e4f2b2ad 867 case SR_CONF_VDIV:
7cc1a550
ML
868 if (!devc)
869 /* Can't know this until we have the exact model. */
870 return SR_ERR_ARG;
be60a9e4
BV
871 if (!probe_group) {
872 sr_err("No probe group specified.");
873 return SR_ERR_PROBE_GROUP;
861c447b 874 }
58f43369 875 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 876 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
877 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
878 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
879 tuple = g_variant_new_tuple(rational, 2);
880 g_variant_builder_add_value(&gvb, tuple);
881 }
882 *data = g_variant_builder_end(&gvb);
883 break;
41f5bd09 884 case SR_CONF_TIMEBASE:
7cc1a550
ML
885 if (!devc)
886 /* Can't know this until we have the exact model. */
887 return SR_ERR_ARG;
a31b2ccb
AJ
888 if (devc->num_timebases <= 0)
889 return SR_ERR_NA;
861c447b 890 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
891 for (i = 0; i < devc->num_timebases; i++) {
892 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
893 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
894 tuple = g_variant_new_tuple(rational, 2);
895 g_variant_builder_add_value(&gvb, tuple);
896 }
897 *data = g_variant_builder_end(&gvb);
41f5bd09 898 break;
328bafab 899 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
900 if (!devc)
901 /* Can't know this until we have the exact model. */
902 return SR_ERR_ARG;
f6a0ac9f 903 *data = g_variant_new_strv(trigger_sources,
bafd4890 904 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 905 break;
babab622
ML
906 case SR_CONF_DATA_SOURCE:
907 if (!devc)
908 /* Can't know this until we have the exact model. */
909 return SR_ERR_ARG;
910 /* This needs tweaking by series/model! */
911 if (devc->model->series == RIGOL_DS2000)
912 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
913 else
914 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
915 break;
a1c743fc 916 default:
bd6fbf62 917 return SR_ERR_NA;
a1c743fc
BV
918 }
919
920 return SR_OK;
921}
922
254dd102 923static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 924{
ae1bc1cc 925 struct sr_scpi_dev_inst *scpi;
29d957ce 926 struct dev_context *devc;
254dd102 927 struct sr_probe *probe;
f76c24f6 928 struct sr_datafeed_packet packet;
254dd102 929 GSList *l;
29d957ce 930
e73ffd42
BV
931 if (sdi->status != SR_ST_ACTIVE)
932 return SR_ERR_DEV_CLOSED;
e0b7d23c 933
ae1bc1cc 934 scpi = sdi->conn;
29d957ce
UH
935 devc = sdi->priv;
936
51b294cd
ML
937 devc->num_frames = 0;
938
254dd102
BV
939 for (l = sdi->probes; l; l = l->next) {
940 probe = l->data;
6bb192bc
ML
941 sr_dbg("handling probe %s", probe->name);
942 if (probe->type == SR_PROBE_ANALOG) {
943 if (probe->enabled)
944 devc->enabled_analog_probes = g_slist_append(
945 devc->enabled_analog_probes, probe);
946 if (probe->enabled != devc->analog_channels[probe->index]) {
947 /* Enabled channel is currently disabled, or vice versa. */
6396b0a7
ML
948 if (set_cfg(sdi, ":CHAN%d:DISP %s", probe->index + 1,
949 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 950 return SR_ERR;
904fd29b 951 devc->analog_channels[probe->index] = probe->enabled;
6bb192bc
ML
952 }
953 } else if (probe->type == SR_PROBE_LOGIC) {
04e8e01e 954 if (probe->enabled) {
6bb192bc
ML
955 devc->enabled_digital_probes = g_slist_append(
956 devc->enabled_digital_probes, probe);
04e8e01e
ML
957 /* Turn on LA module if currently off. */
958 if (!devc->la_enabled) {
959 if (set_cfg(sdi, ":LA:DISP ON") != SR_OK)
960 return SR_ERR;
961 devc->la_enabled = TRUE;
962 }
963 }
6bb192bc
ML
964 if (probe->enabled != devc->digital_channels[probe->index]) {
965 /* Enabled channel is currently disabled, or vice versa. */
6396b0a7
ML
966 if (set_cfg(sdi, ":DIG%d:TURN %s", probe->index,
967 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 968 return SR_ERR;
904fd29b 969 devc->digital_channels[probe->index] = probe->enabled;
6bb192bc 970 }
254dd102
BV
971 }
972 }
1fed20cb 973
6bb192bc 974 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 975 return SR_ERR;
e0b7d23c 976
04e8e01e
ML
977 /* Turn off LA module if on and no digital probes selected. */
978 if (devc->la_enabled && !devc->enabled_digital_probes)
979 if (set_cfg(sdi, ":LA:DISP OFF") != SR_OK)
980 return SR_ERR;
981
1fed20cb 982 if (devc->data_source == DATA_SOURCE_LIVE) {
6396b0a7 983 if (set_cfg(sdi, ":RUN") != SR_OK)
1fed20cb
ML
984 return SR_ERR;
985 } else if (devc->data_source == DATA_SOURCE_MEMORY) {
986 if (devc->model->series != RIGOL_DS2000) {
987 sr_err("Data source 'Memory' not supported for this device");
988 return SR_ERR;
989 }
990 } else if (devc->data_source == DATA_SOURCE_SEGMENTED) {
991 sr_err("Data source 'Segmented' not yet supported");
992 return SR_ERR;
993 }
994
ae1bc1cc 995 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
996
997 /* Send header packet to the session bus. */
29a27196 998 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 999
821fbcad
ML
1000 if (devc->enabled_analog_probes)
1001 devc->channel_entry = devc->enabled_analog_probes;
1002 else
1003 devc->channel_entry = devc->enabled_digital_probes;
1004
5415e602 1005 devc->analog_frame_size = analog_frame_size(sdi);
d22250a9 1006 devc->digital_frame_size = digital_frame_size(sdi);
5415e602 1007
470140fc 1008 if (devc->model->series < RIGOL_DS1000Z) {
bafd4890 1009 /* Fetch the first frame. */
677f85d0
ML
1010 if (rigol_ds_channel_start(sdi) != SR_OK)
1011 return SR_ERR;
6bb192bc 1012 } else {
bafd4890 1013 if (devc->enabled_analog_probes) {
c2b394d5 1014 if (devc->data_source == DATA_SOURCE_MEMORY) {
babab622
ML
1015 /* Apparently for the DS2000 the memory
1016 * depth can only be set in Running state -
1017 * this matches the behaviour of the UI. */
6396b0a7 1018 if (set_cfg(sdi, ":RUN") != SR_OK)
babab622 1019 return SR_ERR;
6396b0a7 1020 if (set_cfg(sdi, "ACQ:MDEP %d", devc->analog_frame_size) != SR_OK)
babab622 1021 return SR_ERR;
6396b0a7 1022 if (set_cfg(sdi, ":STOP") != SR_OK)
babab622 1023 return SR_ERR;
0d9f5a12 1024 }
babab622 1025 if (rigol_ds_capture_start(sdi) != SR_OK)
bafd4890
ML
1026 return SR_ERR;
1027 }
6bb192bc 1028 }
f4816ac6 1029
f76c24f6
ML
1030 /* Start of first frame. */
1031 packet.type = SR_DF_FRAME_BEGIN;
1032 sr_session_send(cb_data, &packet);
1033
f4816ac6
ML
1034 return SR_OK;
1035}
1036
254dd102 1037static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 1038{
29d957ce 1039 struct dev_context *devc;
ae1bc1cc 1040 struct sr_scpi_dev_inst *scpi;
b751cf7a 1041 struct sr_datafeed_packet packet;
29d957ce 1042
f4816ac6
ML
1043 (void)cb_data;
1044
29d957ce
UH
1045 devc = sdi->priv;
1046
f4816ac6
ML
1047 if (sdi->status != SR_ST_ACTIVE) {
1048 sr_err("Device inactive, can't stop acquisition.");
1049 return SR_ERR;
1050 }
1051
b751cf7a
ML
1052 /* End of last frame. */
1053 packet.type = SR_DF_END;
1054 sr_session_send(sdi, &packet);
1055
6bb192bc
ML
1056 g_slist_free(devc->enabled_analog_probes);
1057 g_slist_free(devc->enabled_digital_probes);
1058 devc->enabled_analog_probes = NULL;
1059 devc->enabled_digital_probes = NULL;
ae1bc1cc
ML
1060 scpi = sdi->conn;
1061 sr_scpi_source_remove(scpi);
f4816ac6
ML
1062
1063 return SR_OK;
1064}
1065
3086efdd
ML
1066SR_PRIV struct sr_dev_driver rigol_ds_driver_info = {
1067 .name = "rigol-ds",
1068 .longname = "Rigol DS",
f4816ac6 1069 .api_version = 1,
6078d2c9
UH
1070 .init = init,
1071 .cleanup = cleanup,
1072 .scan = scan,
1073 .dev_list = dev_list,
3b412e3a 1074 .dev_clear = dev_clear,
d62d7ad1 1075 .config_get = config_get,
035a1078 1076 .config_set = config_set,
a1c743fc 1077 .config_list = config_list,
6078d2c9
UH
1078 .dev_open = dev_open,
1079 .dev_close = dev_close,
254dd102
BV
1080 .dev_acquisition_start = dev_acquisition_start,
1081 .dev_acquisition_stop = dev_acquisition_stop,
f4816ac6
ML
1082 .priv = NULL,
1083};