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