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