]> sigrok.org Git - libsigrok.git/blame - hardware/rigol-ds/api.c
rigol-ds: Send FRAME_BEGIN and FRAME_END per frame, not per channel.
[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
51bfe536 234 return sr_scpi_get_opc(sdi->conn);
254dd102
BV
235}
236
6078d2c9 237static int init(struct sr_context *sr_ctx)
f4816ac6 238{
f6beaac5 239 return std_init(sr_ctx, di, LOG_PREFIX);
f4816ac6
ML
240}
241
3520422f 242static int probe_port(const char *resource, const char *serialcomm, GSList **devices)
f4816ac6 243{
cc9fd2d2
BV
244 struct dev_context *devc;
245 struct sr_dev_inst *sdi;
ae1bc1cc
ML
246 struct sr_scpi_dev_inst *scpi;
247 struct sr_scpi_hw_info *hw_info;
cc9fd2d2 248 struct sr_probe *probe;
f6a0ac9f 249 unsigned int i;
bafd4890 250 const struct rigol_ds_model *model = NULL;
ae1bc1cc 251 gchar *channel_name;
fb6e5ba8 252
46a743c1 253 *devices = NULL;
0dc7b43e 254
c3515cea
AJ
255 if (!(scpi = scpi_dev_inst_new(resource, serialcomm)))
256 return SR_ERR;
9bd4c956 257
ae1bc1cc 258 if (sr_scpi_open(scpi) != SR_OK) {
10afee13 259 sr_info("Couldn't open SCPI device.");
ae1bc1cc 260 sr_scpi_free(scpi);
9bd4c956 261 return SR_ERR;
ae1bc1cc 262 };
9bd4c956 263
ae1bc1cc
ML
264 if (sr_scpi_get_hw_id(scpi, &hw_info) != SR_OK) {
265 sr_info("Couldn't get IDN response.");
266 sr_scpi_close(scpi);
267 sr_scpi_free(scpi);
268 return SR_ERR;
ca55277c 269 }
e0b7d23c 270
ca55277c 271 for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
10afee13
ML
272 if (!strcasecmp(hw_info->manufacturer, supported_models[i].vendor) &&
273 !strcmp(hw_info->model, supported_models[i].name)) {
bafd4890 274 model = &supported_models[i];
ca55277c 275 break;
fb6e5ba8 276 }
ca55277c 277 }
fb6e5ba8 278
bafd4890 279 if (!model || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
ae1bc1cc
ML
280 hw_info->manufacturer, hw_info->model,
281 hw_info->firmware_version))) {
282 sr_scpi_hw_info_free(hw_info);
b4936bae 283 sr_scpi_close(scpi);
ae1bc1cc 284 sr_scpi_free(scpi);
ca55277c
ML
285 return SR_ERR_NA;
286 }
fb6e5ba8 287
ae1bc1cc 288 sr_scpi_hw_info_free(hw_info);
b4936bae 289 sr_scpi_close(scpi);
ae1bc1cc
ML
290
291 sdi->conn = scpi;
fb6e5ba8 292
cc9fd2d2 293 sdi->driver = di;
ae1bc1cc 294 sdi->inst_type = SR_INST_SCPI;
512bb890 295
cc9fd2d2 296 if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
ca55277c 297 return SR_ERR_MALLOC;
ae1bc1cc 298
cc9fd2d2 299 devc->limit_frames = 0;
bafd4890 300 devc->model = model;
512bb890 301
821fbcad
ML
302 for (i = 0; i < model->analog_channels; i++) {
303 if (!(channel_name = g_strdup_printf("CH%d", i + 1)))
ca55277c 304 return SR_ERR_MALLOC;
821fbcad 305 probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE, channel_name);
ca55277c 306 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
307 devc->analog_groups[i].name = channel_name;
308 devc->analog_groups[i].probes = g_slist_append(NULL, probe);
309 sdi->probe_groups = g_slist_append(sdi->probe_groups,
310 &devc->analog_groups[i]);
ca55277c 311 }
512bb890 312
bafd4890 313 if (devc->model->has_digital) {
ca55277c
ML
314 for (i = 0; i < 16; i++) {
315 if (!(channel_name = g_strdup_printf("D%d", i)))
316 return SR_ERR_MALLOC;
317 probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
318 g_free(channel_name);
319 if (!probe)
320 return SR_ERR_MALLOC;
321 sdi->probes = g_slist_append(sdi->probes, probe);
3d3a601e
ML
322 devc->digital_group.probes = g_slist_append(
323 devc->digital_group.probes, probe);
512bb890 324 }
b3916147
ML
325 devc->digital_group.name = "LA";
326 sdi->probe_groups = g_slist_append(sdi->probe_groups,
327 &devc->digital_group);
ca55277c 328 }
bafd4890
ML
329
330 for (i = 0; i < NUM_TIMEBASE; i++) {
331 if (!memcmp(&devc->model->min_timebase, &timebases[i], sizeof(uint64_t[2])))
332 devc->timebases = &timebases[i];
333 if (!memcmp(&devc->model->max_timebase, &timebases[i], sizeof(uint64_t[2])))
334 devc->num_timebases = &timebases[i] - devc->timebases + 1;
335 }
336
0709197d
ML
337 for (i = 0; i < NUM_VDIV; i++)
338 if (!memcmp(&devc->model->min_vdiv, &vdivs[i], sizeof(uint64_t[2])))
6ff1394e 339 devc->vdivs = &vdivs[i];
bafd4890 340
babab622
ML
341 if (!(devc->buffer = g_try_malloc(ACQ_BUFFER_SIZE)))
342 return SR_ERR_MALLOC;
343 if (!(devc->data = g_try_malloc(ACQ_BUFFER_SIZE * sizeof(float))))
344 return SR_ERR_MALLOC;
345
346 devc->data_source = DATA_SOURCE_LIVE;
347
cc9fd2d2
BV
348 sdi->priv = devc;
349
350 *devices = g_slist_append(NULL, sdi);
512bb890 351
ca55277c
ML
352 return SR_OK;
353}
512bb890 354
6078d2c9 355static GSList *scan(GSList *options)
ca55277c
ML
356{
357 struct drv_context *drvc;
ca55277c 358 struct sr_config *src;
cc9fd2d2 359 GSList *l, *devices;
ca55277c 360 GDir *dir;
ca55277c 361 int ret;
cc9fd2d2
BV
362 const gchar *dev_name;
363 gchar *port = NULL;
0dc7b43e 364 gchar *serialcomm = NULL;
fb6e5ba8 365
ca55277c 366 drvc = di->priv;
d2e0b1fa 367
ca55277c
ML
368 for (l = options; l; l = l->next) {
369 src = l->data;
0dc7b43e
ML
370 switch (src->key) {
371 case SR_CONF_CONN:
cc9fd2d2 372 port = (char *)g_variant_get_string(src->data, NULL);
ca55277c 373 break;
0dc7b43e
ML
374 case SR_CONF_SERIALCOMM:
375 serialcomm = (char *)g_variant_get_string(src->data, NULL);
376 break;
fb6e5ba8 377 }
ca55277c 378 }
fb6e5ba8 379
46a743c1 380 devices = NULL;
cc9fd2d2 381 if (port) {
0dc7b43e
ML
382 if (probe_port(port, serialcomm, &devices) == SR_ERR_MALLOC) {
383 g_free(port);
384 if (serialcomm)
385 g_free(serialcomm);
ca55277c 386 return NULL;
0dc7b43e 387 }
ca55277c 388 } else {
da970d24
BV
389 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
390 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
391 return NULL;
ca55277c 392 while ((dev_name = g_dir_read_name(dir))) {
cc9fd2d2 393 if (strncmp(dev_name, "usbtmc", 6))
ca55277c 394 continue;
cc9fd2d2 395 port = g_strconcat("/dev/", dev_name, NULL);
0dc7b43e 396 ret = probe_port(port, serialcomm, &devices);
cc9fd2d2 397 g_free(port);
0dc7b43e
ML
398 if (serialcomm)
399 g_free(serialcomm);
ca55277c
ML
400 if (ret == SR_ERR_MALLOC) {
401 g_dir_close(dir);
ca55277c 402 return NULL;
6bb192bc
ML
403 }
404 }
ca55277c
ML
405 g_dir_close(dir);
406 }
f4816ac6 407
46a743c1
BV
408 /* Tack a copy of the newly found devices onto the driver list. */
409 l = g_slist_copy(devices);
410 drvc->instances = g_slist_concat(drvc->instances, l);
cc9fd2d2 411
f4816ac6
ML
412 return devices;
413}
414
6078d2c9 415static GSList *dev_list(void)
f4816ac6 416{
0e94d524 417 return ((struct drv_context *)(di->priv))->instances;
f4816ac6
ML
418}
419
6078d2c9 420static int dev_open(struct sr_dev_inst *sdi)
f4816ac6 421{
ae1bc1cc 422 struct sr_scpi_dev_inst *scpi = sdi->conn;
9bd4c956 423
ae1bc1cc 424 if (sr_scpi_open(scpi) < 0)
e0b7d23c 425 return SR_ERR;
e0b7d23c 426
3086efdd 427 if (rigol_ds_get_dev_cfg(sdi) != SR_OK)
254dd102 428 return SR_ERR;
f4816ac6 429
46a743c1 430 sdi->status = SR_ST_ACTIVE;
cc9fd2d2 431
f4816ac6
ML
432 return SR_OK;
433}
434
6078d2c9 435static int dev_close(struct sr_dev_inst *sdi)
f4816ac6 436{
ae1bc1cc
ML
437 struct sr_scpi_dev_inst *scpi;
438
439 scpi = sdi->conn;
e0b7d23c 440
ae1bc1cc
ML
441 if (scpi) {
442 if (sr_scpi_close(scpi) < 0)
443 return SR_ERR;
cc9fd2d2
BV
444 sdi->status = SR_ST_INACTIVE;
445 }
f4816ac6
ML
446
447 return SR_OK;
448}
449
6078d2c9 450static int cleanup(void)
f4816ac6 451{
3b412e3a 452 return dev_clear();
f4816ac6
ML
453}
454
5415e602
ML
455static int analog_frame_size(const struct sr_dev_inst *sdi)
456{
457 struct dev_context *devc = sdi->priv;
458 struct sr_probe *probe;
459 int analog_probes = 0;
460 GSList *l;
461
470140fc
ML
462 switch (devc->model->series) {
463 case RIGOL_VS5000:
464 return VS5000_ANALOG_LIVE_WAVEFORM_SIZE;
465 case RIGOL_DS1000:
466 return DS1000_ANALOG_LIVE_WAVEFORM_SIZE;
467 default:
5415e602
ML
468 for (l = sdi->probes; l; l = l->next) {
469 probe = l->data;
470 if (probe->type == SR_PROBE_ANALOG && probe->enabled)
471 analog_probes++;
472 }
473 if (devc->data_source == DATA_SOURCE_MEMORY) {
474 if (analog_probes == 1)
475 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_1C;
476 else
477 return DS2000_ANALOG_MEM_WAVEFORM_SIZE_2C;
478 } else {
479 if (devc->model->series == AGILENT_DSO1000)
480 return DSO1000_ANALOG_LIVE_WAVEFORM_SIZE;
481 else
482 return DS2000_ANALOG_LIVE_WAVEFORM_SIZE;
483 }
484 }
485}
486
d22250a9
ML
487static int digital_frame_size(const struct sr_dev_inst *sdi)
488{
489 struct dev_context *devc = sdi->priv;
490
491 switch (devc->model->series) {
492 case RIGOL_VS5000:
493 return VS5000_DIGITAL_WAVEFORM_SIZE;
494 case RIGOL_DS1000:
495 return DS1000_DIGITAL_WAVEFORM_SIZE;
496 default:
497 return 0;
498 }
499}
500
8f996b89
ML
501static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
502 const struct sr_probe_group *probe_group)
d62d7ad1 503{
e43fdd8d 504 struct dev_context *devc;
c2b394d5 505 uint64_t samplerate;
d62d7ad1 506
e43fdd8d
BV
507 if (!sdi || !(devc = sdi->priv))
508 return SR_ERR_ARG;
509
be60a9e4 510 /* If a probe group is specified, it must be a valid one. */
c2b394d5 511 if (probe_group && !g_slist_find(sdi->probe_groups, probe_group)) {
969edf63
ML
512 sr_err("Invalid probe group specified.");
513 return SR_ERR;
be60a9e4
BV
514 }
515
d62d7ad1
BV
516 switch (id) {
517 case SR_CONF_NUM_TIMEBASE:
0709197d 518 *data = g_variant_new_int32(devc->model->num_horizontal_divs);
d62d7ad1
BV
519 break;
520 case SR_CONF_NUM_VDIV:
0709197d 521 *data = g_variant_new_int32(8);
babab622
ML
522 case SR_CONF_DATA_SOURCE:
523 if (devc->data_source == DATA_SOURCE_LIVE)
524 *data = g_variant_new_string("Live");
525 else if (devc->data_source == DATA_SOURCE_MEMORY)
526 *data = g_variant_new_string("Memory");
527 else
528 *data = g_variant_new_string("Segmented");
529 break;
4914dd4b
ML
530 case SR_CONF_SAMPLERATE:
531 if (devc->data_source == DATA_SOURCE_LIVE) {
c2b394d5 532 samplerate = analog_frame_size(sdi) /
4914dd4b
ML
533 (devc->timebase * devc->model->num_horizontal_divs);
534 *data = g_variant_new_uint64(samplerate);
c2b394d5 535 } else {
4914dd4b 536 return SR_ERR_NA;
c2b394d5 537 }
4914dd4b 538 break;
d62d7ad1 539 default:
bd6fbf62 540 return SR_ERR_NA;
d62d7ad1
BV
541 }
542
543 return SR_OK;
544}
545
8f996b89
ML
546static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi,
547 const struct sr_probe_group *probe_group)
f4816ac6 548{
29d957ce 549 struct dev_context *devc;
f6a0ac9f 550 uint64_t tmp_u64, p, q;
254dd102 551 double t_dbl;
f48e0249 552 unsigned int i, j;
254dd102
BV
553 int ret;
554 const char *tmp_str;
f4816ac6 555
e43fdd8d
BV
556 if (!(devc = sdi->priv))
557 return SR_ERR_ARG;
29d957ce 558
e73ffd42
BV
559 if (sdi->status != SR_ST_ACTIVE)
560 return SR_ERR_DEV_CLOSED;
f4816ac6 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
f4816ac6 568 ret = SR_OK;
035a1078 569 switch (id) {
1953564a 570 case SR_CONF_LIMIT_FRAMES:
f6a0ac9f 571 devc->limit_frames = g_variant_get_uint64(data);
e0b7d23c 572 break;
1953564a 573 case SR_CONF_TRIGGER_SLOPE:
f6a0ac9f 574 tmp_u64 = g_variant_get_uint64(data);
254dd102
BV
575 if (tmp_u64 != 0 && tmp_u64 != 1)
576 return SR_ERR;
577 g_free(devc->trigger_slope);
578 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
579 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
e0b7d23c 580 break;
1953564a 581 case SR_CONF_HORIZ_TRIGGERPOS:
254dd102
BV
582 t_dbl = g_variant_get_double(data);
583 if (t_dbl < 0.0 || t_dbl > 1.0)
584 return SR_ERR;
585 devc->horiz_triggerpos = t_dbl;
586 /* We have the trigger offset as a percentage of the frame, but
587 * need to express this in seconds. */
bafd4890 588 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * devc->num_timebases;
254dd102 589 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
e0b7d23c 590 break;
1953564a 591 case SR_CONF_TIMEBASE:
f6a0ac9f 592 g_variant_get(data, "(tt)", &p, &q);
bafd4890
ML
593 for (i = 0; i < devc->num_timebases; i++) {
594 if (devc->timebases[i][0] == p && devc->timebases[i][1] == q) {
254dd102
BV
595 devc->timebase = (float)p / q;
596 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
f6a0ac9f
BV
597 break;
598 }
599 }
bafd4890 600 if (i == devc->num_timebases)
254dd102 601 ret = SR_ERR_ARG;
e0b7d23c 602 break;
1953564a 603 case SR_CONF_TRIGGER_SOURCE:
f6a0ac9f 604 tmp_str = g_variant_get_string(data, NULL);
254dd102
BV
605 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
606 if (!strcmp(trigger_sources[i], tmp_str)) {
607 g_free(devc->trigger_source);
608 devc->trigger_source = g_strdup(trigger_sources[i]);
609 if (!strcmp(devc->trigger_source, "AC Line"))
610 tmp_str = "ACL";
611 else if (!strcmp(devc->trigger_source, "CH1"))
612 tmp_str = "CHAN1";
613 else if (!strcmp(devc->trigger_source, "CH2"))
614 tmp_str = "CHAN2";
821fbcad
ML
615 else if (!strcmp(devc->trigger_source, "CH3"))
616 tmp_str = "CHAN3";
617 else if (!strcmp(devc->trigger_source, "CH4"))
618 tmp_str = "CHAN4";
254dd102
BV
619 else
620 tmp_str = (char *)devc->trigger_source;
621 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
622 break;
623 }
4e108ace 624 }
254dd102
BV
625 if (i == ARRAY_SIZE(trigger_sources))
626 ret = SR_ERR_ARG;
e0b7d23c 627 break;
1953564a 628 case SR_CONF_VDIV:
be60a9e4
BV
629 if (!probe_group) {
630 sr_err("No probe group specified.");
631 return SR_ERR_PROBE_GROUP;
632 }
f6a0ac9f 633 g_variant_get(data, "(tt)", &p, &q);
f48e0249 634 for (i = 0; i < 2; i++) {
78bcc55a
BV
635 if (probe_group == &devc->analog_groups[i]) {
636 for (j = 0; j < ARRAY_SIZE(vdivs); j++) {
f48e0249
ML
637 if (vdivs[j][0] != p || vdivs[j][1] != q)
638 continue;
639 devc->vdiv[i] = (float)p / q;
640 return set_cfg(sdi, ":CHAN%d:SCAL %.3f", i + 1,
641 devc->vdiv[i]);
642 }
643 return SR_ERR_ARG;
644 }
e0b7d23c 645 }
f48e0249 646 return SR_ERR_NA;
1953564a 647 case SR_CONF_COUPLING:
78bcc55a
BV
648 if (!probe_group) {
649 sr_err("No probe group specified.");
650 return SR_ERR_PROBE_GROUP;
651 }
f6a0ac9f 652 tmp_str = g_variant_get_string(data, NULL);
f48e0249 653 for (i = 0; i < 2; i++) {
78bcc55a
BV
654 if (probe_group == &devc->analog_groups[i]) {
655 for (j = 0; j < ARRAY_SIZE(coupling); j++) {
656 if (!strcmp(tmp_str, coupling[j])) {
f48e0249
ML
657 g_free(devc->coupling[i]);
658 devc->coupling[i] = g_strdup(coupling[j]);
659 return set_cfg(sdi, ":CHAN%d:COUP %s", i + 1,
660 devc->coupling[i]);
661 }
662 }
663 return SR_ERR_ARG;
e0b7d23c
ML
664 }
665 }
f48e0249 666 return SR_ERR_NA;
babab622
ML
667 case SR_CONF_DATA_SOURCE:
668 tmp_str = g_variant_get_string(data, NULL);
669 if (!strcmp(tmp_str, "Live"))
670 devc->data_source = DATA_SOURCE_LIVE;
671 else if (!strcmp(tmp_str, "Memory"))
672 devc->data_source = DATA_SOURCE_MEMORY;
470140fc 673 else if (devc->model->series >= RIGOL_DS1000Z
babab622
ML
674 && !strcmp(tmp_str, "Segmented"))
675 devc->data_source = DATA_SOURCE_SEGMENTED;
676 else
677 return SR_ERR;
678 break;
f4816ac6 679 default:
bd6fbf62 680 ret = SR_ERR_NA;
29d957ce 681 break;
f4816ac6
ML
682 }
683
684 return ret;
685}
686
8f996b89
ML
687static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi,
688 const struct sr_probe_group *probe_group)
a1c743fc 689{
861c447b
BV
690 GVariant *tuple, *rational[2];
691 GVariantBuilder gvb;
692 unsigned int i;
7cc1a550
ML
693 struct dev_context *devc = NULL;
694
695 if (sdi)
696 devc = sdi->priv;
8f996b89 697
e43fdd8d 698 if (key == SR_CONF_SCAN_OPTIONS) {
ca55277c
ML
699 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
700 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
e43fdd8d
BV
701 return SR_OK;
702 } else if (key == SR_CONF_DEVICE_OPTIONS && probe_group == NULL) {
703 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
704 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
705 return SR_OK;
706 }
707
708 /* Every other option requires a valid device instance. */
709 if (!sdi || !(devc = sdi->priv))
710 return SR_ERR_ARG;
711
be60a9e4
BV
712 /* If a probe group is specified, it must be a valid one. */
713 if (probe_group) {
714 if (probe_group != &devc->analog_groups[0]
715 && probe_group != &devc->analog_groups[1]) {
716 sr_err("Invalid probe group specified.");
717 return SR_ERR;
718 }
719 }
720
e43fdd8d 721 switch (key) {
9a6517d1 722 case SR_CONF_DEVICE_OPTIONS:
be60a9e4
BV
723 if (!probe_group) {
724 sr_err("No probe group specified.");
725 return SR_ERR_PROBE_GROUP;
726 }
e43fdd8d 727 if (probe_group == &devc->digital_group) {
f48e0249
ML
728 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
729 NULL, 0, sizeof(int32_t));
730 return SR_OK;
731 } else {
732 for (i = 0; i < 2; i++) {
733 if (probe_group == &devc->analog_groups[i]) {
734 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
735 analog_hwcaps, ARRAY_SIZE(analog_hwcaps), sizeof(int32_t));
736 return SR_OK;
737 }
738 }
739 return SR_ERR_NA;
740 }
5f77dffc 741 break;
2a7b113d 742 case SR_CONF_COUPLING:
be60a9e4
BV
743 if (!probe_group) {
744 sr_err("No probe group specified.");
745 return SR_ERR_PROBE_GROUP;
f48e0249 746 }
58f43369
BV
747 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
748 break;
e4f2b2ad 749 case SR_CONF_VDIV:
7cc1a550
ML
750 if (!devc)
751 /* Can't know this until we have the exact model. */
752 return SR_ERR_ARG;
be60a9e4
BV
753 if (!probe_group) {
754 sr_err("No probe group specified.");
755 return SR_ERR_PROBE_GROUP;
861c447b 756 }
58f43369 757 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
0709197d 758 for (i = 0; i < NUM_VDIV; i++) {
bafd4890
ML
759 rational[0] = g_variant_new_uint64(devc->vdivs[i][0]);
760 rational[1] = g_variant_new_uint64(devc->vdivs[i][1]);
58f43369
BV
761 tuple = g_variant_new_tuple(rational, 2);
762 g_variant_builder_add_value(&gvb, tuple);
763 }
764 *data = g_variant_builder_end(&gvb);
765 break;
41f5bd09 766 case SR_CONF_TIMEBASE:
7cc1a550
ML
767 if (!devc)
768 /* Can't know this until we have the exact model. */
769 return SR_ERR_ARG;
a31b2ccb
AJ
770 if (devc->num_timebases <= 0)
771 return SR_ERR_NA;
861c447b 772 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
bafd4890
ML
773 for (i = 0; i < devc->num_timebases; i++) {
774 rational[0] = g_variant_new_uint64(devc->timebases[i][0]);
775 rational[1] = g_variant_new_uint64(devc->timebases[i][1]);
861c447b
BV
776 tuple = g_variant_new_tuple(rational, 2);
777 g_variant_builder_add_value(&gvb, tuple);
778 }
779 *data = g_variant_builder_end(&gvb);
41f5bd09 780 break;
328bafab 781 case SR_CONF_TRIGGER_SOURCE:
7cc1a550
ML
782 if (!devc)
783 /* Can't know this until we have the exact model. */
784 return SR_ERR_ARG;
f6a0ac9f 785 *data = g_variant_new_strv(trigger_sources,
bafd4890 786 devc->model->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
328bafab 787 break;
babab622
ML
788 case SR_CONF_DATA_SOURCE:
789 if (!devc)
790 /* Can't know this until we have the exact model. */
791 return SR_ERR_ARG;
792 /* This needs tweaking by series/model! */
793 if (devc->model->series == RIGOL_DS2000)
794 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources));
795 else
796 *data = g_variant_new_strv(data_sources, ARRAY_SIZE(data_sources) - 1);
797 break;
a1c743fc 798 default:
bd6fbf62 799 return SR_ERR_NA;
a1c743fc
BV
800 }
801
802 return SR_OK;
803}
804
254dd102 805static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
f4816ac6 806{
ae1bc1cc 807 struct sr_scpi_dev_inst *scpi;
29d957ce 808 struct dev_context *devc;
254dd102 809 struct sr_probe *probe;
f76c24f6 810 struct sr_datafeed_packet packet;
254dd102 811 GSList *l;
29d957ce 812
e73ffd42
BV
813 if (sdi->status != SR_ST_ACTIVE)
814 return SR_ERR_DEV_CLOSED;
e0b7d23c 815
ae1bc1cc 816 scpi = sdi->conn;
29d957ce
UH
817 devc = sdi->priv;
818
51b294cd
ML
819 devc->num_frames = 0;
820
254dd102
BV
821 for (l = sdi->probes; l; l = l->next) {
822 probe = l->data;
6bb192bc
ML
823 sr_dbg("handling probe %s", probe->name);
824 if (probe->type == SR_PROBE_ANALOG) {
825 if (probe->enabled)
826 devc->enabled_analog_probes = g_slist_append(
827 devc->enabled_analog_probes, probe);
828 if (probe->enabled != devc->analog_channels[probe->index]) {
829 /* Enabled channel is currently disabled, or vice versa. */
6396b0a7
ML
830 if (set_cfg(sdi, ":CHAN%d:DISP %s", probe->index + 1,
831 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 832 return SR_ERR;
904fd29b 833 devc->analog_channels[probe->index] = probe->enabled;
6bb192bc
ML
834 }
835 } else if (probe->type == SR_PROBE_LOGIC) {
04e8e01e 836 if (probe->enabled) {
6bb192bc
ML
837 devc->enabled_digital_probes = g_slist_append(
838 devc->enabled_digital_probes, probe);
04e8e01e
ML
839 /* Turn on LA module if currently off. */
840 if (!devc->la_enabled) {
841 if (set_cfg(sdi, ":LA:DISP ON") != SR_OK)
842 return SR_ERR;
843 devc->la_enabled = TRUE;
844 }
845 }
6bb192bc
ML
846 if (probe->enabled != devc->digital_channels[probe->index]) {
847 /* Enabled channel is currently disabled, or vice versa. */
6396b0a7
ML
848 if (set_cfg(sdi, ":DIG%d:TURN %s", probe->index,
849 probe->enabled ? "ON" : "OFF") != SR_OK)
6bb192bc 850 return SR_ERR;
904fd29b 851 devc->digital_channels[probe->index] = probe->enabled;
6bb192bc 852 }
254dd102
BV
853 }
854 }
1fed20cb 855
6bb192bc 856 if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
254dd102 857 return SR_ERR;
e0b7d23c 858
04e8e01e
ML
859 /* Turn off LA module if on and no digital probes selected. */
860 if (devc->la_enabled && !devc->enabled_digital_probes)
861 if (set_cfg(sdi, ":LA:DISP OFF") != SR_OK)
862 return SR_ERR;
863
1fed20cb 864 if (devc->data_source == DATA_SOURCE_LIVE) {
6396b0a7 865 if (set_cfg(sdi, ":RUN") != SR_OK)
1fed20cb
ML
866 return SR_ERR;
867 } else if (devc->data_source == DATA_SOURCE_MEMORY) {
868 if (devc->model->series != RIGOL_DS2000) {
869 sr_err("Data source 'Memory' not supported for this device");
870 return SR_ERR;
871 }
872 } else if (devc->data_source == DATA_SOURCE_SEGMENTED) {
873 sr_err("Data source 'Segmented' not yet supported");
874 return SR_ERR;
875 }
876
ae1bc1cc 877 sr_scpi_source_add(scpi, G_IO_IN, 50, rigol_ds_receive, (void *)sdi);
e0b7d23c
ML
878
879 /* Send header packet to the session bus. */
29a27196 880 std_session_send_df_header(cb_data, LOG_PREFIX);
e0b7d23c 881
821fbcad
ML
882 if (devc->enabled_analog_probes)
883 devc->channel_entry = devc->enabled_analog_probes;
884 else
885 devc->channel_entry = devc->enabled_digital_probes;
886
5415e602 887 devc->analog_frame_size = analog_frame_size(sdi);
d22250a9 888 devc->digital_frame_size = digital_frame_size(sdi);
5415e602 889
470140fc 890 if (devc->model->series < RIGOL_DS1000Z) {
bafd4890 891 /* Fetch the first frame. */
677f85d0
ML
892 if (rigol_ds_channel_start(sdi) != SR_OK)
893 return SR_ERR;
6bb192bc 894 } else {
bafd4890 895 if (devc->enabled_analog_probes) {
c2b394d5 896 if (devc->data_source == DATA_SOURCE_MEMORY) {
babab622
ML
897 /* Apparently for the DS2000 the memory
898 * depth can only be set in Running state -
899 * this matches the behaviour of the UI. */
6396b0a7 900 if (set_cfg(sdi, ":RUN") != SR_OK)
babab622 901 return SR_ERR;
6396b0a7 902 if (set_cfg(sdi, "ACQ:MDEP %d", devc->analog_frame_size) != SR_OK)
babab622 903 return SR_ERR;
6396b0a7 904 if (set_cfg(sdi, ":STOP") != SR_OK)
babab622 905 return SR_ERR;
0d9f5a12 906 }
babab622 907 if (rigol_ds_capture_start(sdi) != SR_OK)
bafd4890
ML
908 return SR_ERR;
909 }
6bb192bc 910 }
f4816ac6 911
f76c24f6
ML
912 /* Start of first frame. */
913 packet.type = SR_DF_FRAME_BEGIN;
914 sr_session_send(cb_data, &packet);
915
f4816ac6
ML
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};