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