]> sigrok.org Git - libsigrok.git/blob - hardware/rigol-ds1xx2/api.c
e6e923ccfb7f41f2c78f448e9af1994c8f2a173d
[libsigrok.git] / hardware / rigol-ds1xx2 / api.c
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2012 Martin Ling <martin-git@earth.li>
5  * Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <glib.h>
26 #include "libsigrok.h"
27 #include "libsigrok-internal.h"
28 #include "protocol.h"
29
30 #define NUM_TIMEBASE  12
31 #define NUM_VDIV      8
32
33 static const int32_t hwopts[] = {
34         SR_CONF_CONN,
35 };
36
37 static const int32_t hwcaps[] = {
38         SR_CONF_OSCILLOSCOPE,
39         SR_CONF_TIMEBASE,
40         SR_CONF_TRIGGER_SOURCE,
41         SR_CONF_TRIGGER_SLOPE,
42         SR_CONF_HORIZ_TRIGGERPOS,
43         SR_CONF_VDIV,
44         SR_CONF_COUPLING,
45         SR_CONF_NUM_TIMEBASE,
46         SR_CONF_NUM_VDIV,
47 };
48
49 static const uint64_t timebases[][2] = {
50         /* nanoseconds */
51         { 2, 1000000000 },
52         { 5, 1000000000 },
53         { 10, 1000000000 },
54         { 20, 1000000000 },
55         { 50, 1000000000 },
56         { 100, 1000000000 },
57         { 500, 1000000000 },
58         /* microseconds */
59         { 1, 1000000 },
60         { 2, 1000000 },
61         { 5, 1000000 },
62         { 10, 1000000 },
63         { 20, 1000000 },
64         { 50, 1000000 },
65         { 100, 1000000 },
66         { 200, 1000000 },
67         { 500, 1000000 },
68         /* milliseconds */
69         { 1, 1000 },
70         { 2, 1000 },
71         { 5, 1000 },
72         { 10, 1000 },
73         { 20, 1000 },
74         { 50, 1000 },
75         { 100, 1000 },
76         { 200, 1000 },
77         { 500, 1000 },
78         /* seconds */
79         { 1, 1 },
80         { 2, 1 },
81         { 5, 1 },
82         { 10, 1 },
83         { 20, 1 },
84         { 50, 1 },
85 };
86
87 static const uint64_t vdivs[][2] = {
88         /* millivolts */
89         { 2, 1000 },
90         { 5, 1000 },
91         { 10, 1000 },
92         { 20, 1000 },
93         { 50, 1000 },
94         { 100, 1000 },
95         { 200, 1000 },
96         { 500, 1000 },
97         /* volts */
98         { 1, 1 },
99         { 2, 1 },
100         { 5, 1 },
101         { 10, 1 },
102 };
103
104 static const char *trigger_sources[] = {
105         "CH1",
106         "CH2",
107         "EXT",
108         "AC Line",
109         "D0",
110         "D1",
111         "D2",
112         "D3",
113         "D4",
114         "D5",
115         "D6",
116         "D7",
117         "D8",
118         "D9",
119         "D10",
120         "D11",
121         "D12",
122         "D13",
123         "D14",
124         "D15",
125 };
126
127 static const char *coupling[] = {
128         "AC",
129         "DC",
130         "GND",
131 };
132
133 static const char *supported_models[] = {
134         "DS1052E",
135         "DS1102E",
136         "DS1052D",
137         "DS1102D",
138 };
139
140 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
141 static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
142
143 static void clear_helper(void *priv)
144 {
145         struct dev_context *devc;
146
147         devc = priv;
148
149         g_free(devc->coupling[0]);
150         g_free(devc->coupling[1]);
151         g_free(devc->trigger_source);
152         g_free(devc->trigger_slope);
153 }
154
155 static int dev_clear(void)
156 {
157         return std_dev_clear(di, clear_helper);
158 }
159
160 static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
161 {
162         va_list args;
163         char buf[256];
164
165         va_start(args, format);
166         vsnprintf(buf, 255, format, args);
167         va_end(args);
168         if (rigol_ds1xx2_send(sdi, buf) != SR_OK)
169                 return SR_ERR;
170
171         /* When setting a bunch of parameters in a row, the DS1052E scrambles
172          * some of them unless there is at least 100ms delay in between. */
173         sr_spew("delay %dms", 100);
174         g_usleep(100000);
175
176         return SR_OK;
177 }
178
179 static int init(struct sr_context *sr_ctx)
180 {
181         return std_init(sr_ctx, di, LOG_PREFIX);
182 }
183
184 static int probe_port(const char *port, GSList **devices)
185 {
186         struct dev_context *devc;
187         struct sr_dev_inst *sdi;
188         struct sr_serial_dev_inst *serial;
189         struct sr_probe *probe;
190         unsigned int i;
191         int len, num_tokens;
192         gboolean matched, has_digital;
193         const char *manufacturer, *model, *version;
194         char buf[256];
195         gchar **tokens, *channel_name;
196
197         *devices = NULL;
198         if (!(serial = sr_serial_dev_inst_new(port, NULL)))
199                 return SR_ERR_MALLOC;
200
201         if (serial_open(serial, SERIAL_RDWR) != SR_OK)
202                 return SR_ERR;
203         len = serial_write(serial, "*IDN?", 5);
204         len = serial_read(serial, buf, sizeof(buf));
205         if (serial_close(serial) != SR_OK)
206                 return SR_ERR;
207
208         sr_serial_dev_inst_free(serial);
209
210         if (len == 0)
211                 return SR_ERR_NA;
212
213         buf[len] = 0;
214         tokens = g_strsplit(buf, ",", 0);
215         sr_dbg("response: %s [%s]", port, buf);
216
217         for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
218
219         if (num_tokens < 4) {
220                 g_strfreev(tokens);
221                 return SR_ERR_NA;
222         }
223
224         manufacturer = tokens[0];
225         model = tokens[1];
226         version = tokens[3];
227
228         if (strcmp(manufacturer, "Rigol Technologies")) {
229                 g_strfreev(tokens);
230                 return SR_ERR_NA;
231         }
232
233         matched = has_digital = FALSE;
234         for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
235                 if (!strcmp(model, supported_models[i])) {
236                         matched = TRUE;
237                         has_digital = g_str_has_suffix(model, "D");
238                         break;
239                 }
240         }
241
242         if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
243                 manufacturer, model, version))) {
244                 g_strfreev(tokens);
245                 return SR_ERR_NA;
246         }
247
248         g_strfreev(tokens);
249
250         if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
251                 return SR_ERR_MALLOC;
252         sdi->driver = di;
253         sdi->inst_type = SR_INST_SERIAL;
254
255         if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
256                 return SR_ERR_MALLOC;
257         devc->limit_frames = 0;
258         devc->has_digital = has_digital;
259
260         for (i = 0; i < 2; i++) {
261                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
262                                 i == 0 ? "CH1" : "CH2")))
263                         return SR_ERR_MALLOC;
264                 sdi->probes = g_slist_append(sdi->probes, probe);
265         }
266
267         if (devc->has_digital) {
268                 for (i = 0; i < 16; i++) {
269                         if (!(channel_name = g_strdup_printf("D%d", i)))
270                                 return SR_ERR_MALLOC;
271                         probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
272                         g_free(channel_name);
273                         if (!probe)
274                                 return SR_ERR_MALLOC;
275                         sdi->probes = g_slist_append(sdi->probes, probe);
276                 }
277         }
278         sdi->priv = devc;
279
280         *devices = g_slist_append(NULL, sdi);
281
282         return SR_OK;
283 }
284
285 static GSList *scan(GSList *options)
286 {
287         struct drv_context *drvc;
288         struct sr_config *src;
289         GSList *l, *devices;
290         GDir *dir;
291         int ret;
292         const gchar *dev_name;
293         gchar *port = NULL;
294
295         drvc = di->priv;
296
297         for (l = options; l; l = l->next) {
298                 src = l->data;
299                 if (src->key == SR_CONF_CONN) {
300                         port = (char *)g_variant_get_string(src->data, NULL);
301                         break;
302                 }
303         }
304
305         devices = NULL;
306         if (port) {
307                 if (probe_port(port, &devices) == SR_ERR_MALLOC)
308                         return NULL;
309         } else {
310                 if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
311                         return NULL;
312                 while ((dev_name = g_dir_read_name(dir))) {
313                         if (strncmp(dev_name, "usbtmc", 6))
314                                 continue;
315                         port = g_strconcat("/dev/", dev_name, NULL);
316                         ret = probe_port(port, &devices);
317                         g_free(port);
318                         if (ret == SR_ERR_MALLOC) {
319                                 g_dir_close(dir);
320                                 return NULL;
321                         }
322                 }
323                 g_dir_close(dir);
324         }
325
326         /* Tack a copy of the newly found devices onto the driver list. */
327         l = g_slist_copy(devices);
328         drvc->instances = g_slist_concat(drvc->instances, l);
329
330         return devices;
331 }
332
333 static GSList *dev_list(void)
334 {
335         return ((struct drv_context *)(di->priv))->instances;
336 }
337
338 static int dev_open(struct sr_dev_inst *sdi)
339 {
340
341         if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
342                 return SR_ERR;
343
344         if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
345                 return SR_ERR;
346
347         sdi->status = SR_ST_ACTIVE;
348
349         return SR_OK;
350 }
351
352 static int dev_close(struct sr_dev_inst *sdi)
353 {
354         struct sr_serial_dev_inst *serial;
355
356         serial = sdi->conn;
357         if (serial && serial->fd != -1) {
358                 serial_close(serial);
359                 sdi->status = SR_ST_INACTIVE;
360         }
361
362         return SR_OK;
363 }
364
365 static int cleanup(void)
366 {
367         return dev_clear();
368 }
369
370 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
371 {
372
373         (void)sdi;
374
375         switch (id) {
376         case SR_CONF_NUM_TIMEBASE:
377                 *data = g_variant_new_int32(NUM_TIMEBASE);
378                 break;
379         case SR_CONF_NUM_VDIV:
380                 *data = g_variant_new_int32(NUM_VDIV);
381                 break;
382         default:
383                 return SR_ERR_NA;
384         }
385
386         return SR_OK;
387 }
388
389 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
390 {
391         struct dev_context *devc;
392         uint64_t tmp_u64, p, q;
393         double t_dbl;
394         unsigned int i;
395         int ret;
396         const char *tmp_str;
397
398         devc = sdi->priv;
399
400         if (sdi->status != SR_ST_ACTIVE)
401                 return SR_ERR_DEV_CLOSED;
402
403         ret = SR_OK;
404         switch (id) {
405         case SR_CONF_LIMIT_FRAMES:
406                 devc->limit_frames = g_variant_get_uint64(data);
407                 break;
408         case SR_CONF_TRIGGER_SLOPE:
409                 tmp_u64 = g_variant_get_uint64(data);
410                 if (tmp_u64 != 0 && tmp_u64 != 1)
411                         return SR_ERR;
412                 g_free(devc->trigger_slope);
413                 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
414                 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
415                 break;
416         case SR_CONF_HORIZ_TRIGGERPOS:
417                 t_dbl = g_variant_get_double(data);
418                 if (t_dbl < 0.0 || t_dbl > 1.0)
419                         return SR_ERR;
420                 devc->horiz_triggerpos = t_dbl;
421                 /* We have the trigger offset as a percentage of the frame, but
422                  * need to express this in seconds. */
423                 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
424                 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
425                 break;
426         case SR_CONF_TIMEBASE:
427                 g_variant_get(data, "(tt)", &p, &q);
428                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
429                         if (timebases[i][0] == p && timebases[i][1] == q) {
430                                 devc->timebase = (float)p / q;
431                                 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
432                                 break;
433                         }
434                 }
435                 if (i == ARRAY_SIZE(timebases))
436                         ret = SR_ERR_ARG;
437                 break;
438         case SR_CONF_TRIGGER_SOURCE:
439                 tmp_str = g_variant_get_string(data, NULL);
440                 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
441                         if (!strcmp(trigger_sources[i], tmp_str)) {
442                                 g_free(devc->trigger_source);
443                                 devc->trigger_source = g_strdup(trigger_sources[i]);
444                                 if (!strcmp(devc->trigger_source, "AC Line"))
445                                         tmp_str = "ACL";
446                                 else if (!strcmp(devc->trigger_source, "CH1"))
447                                         tmp_str = "CHAN1";
448                                 else if (!strcmp(devc->trigger_source, "CH2"))
449                                         tmp_str = "CHAN2";
450                                 else
451                                         tmp_str = (char *)devc->trigger_source;
452                                 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
453                                 break;
454                         }
455                 }
456                 if (i == ARRAY_SIZE(trigger_sources))
457                         ret = SR_ERR_ARG;
458                 break;
459         case SR_CONF_VDIV:
460                 g_variant_get(data, "(tt)", &p, &q);
461                 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
462                         if (vdivs[i][0] != p || vdivs[i][1] != q)
463                                 continue;
464                         devc->vdiv[0] = devc->vdiv[1] = (float)p / q;
465                         set_cfg(sdi, ":CHAN1:SCAL %.3f", devc->vdiv[0]);
466                         ret = set_cfg(sdi, ":CHAN2:SCAL %.3f", devc->vdiv[1]);
467                         break;
468                 }
469                 if (i == ARRAY_SIZE(vdivs))
470                         ret = SR_ERR_ARG;
471                 break;
472         case SR_CONF_COUPLING:
473                 /* TODO: Not supporting coupling per channel yet. */
474                 tmp_str = g_variant_get_string(data, NULL);
475                 for (i = 0; i < ARRAY_SIZE(coupling); i++) {
476                         if (!strcmp(tmp_str, coupling[i])) {
477                                 g_free(devc->coupling[0]);
478                                 g_free(devc->coupling[1]);
479                                 devc->coupling[0] = g_strdup(coupling[i]);
480                                 devc->coupling[1] = g_strdup(coupling[i]);
481                                 set_cfg(sdi, ":CHAN1:COUP %s", devc->coupling[0]);
482                                 ret = set_cfg(sdi, ":CHAN2:COUP %s", devc->coupling[1]);
483                                 break;
484                         }
485                 }
486                 if (i == ARRAY_SIZE(coupling))
487                         ret = SR_ERR_ARG;
488                 break;
489         default:
490                 ret = SR_ERR_NA;
491                 break;
492         }
493
494         return ret;
495 }
496
497 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
498 {
499         GVariant *tuple, *rational[2];
500         GVariantBuilder gvb;
501         unsigned int i;
502         struct dev_context *devc;
503
504         switch (key) {
505         case SR_CONF_SCAN_OPTIONS:
506                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
507                                 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
508                 break;
509         case SR_CONF_DEVICE_OPTIONS:
510                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
511                                 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
512                 break;
513         case SR_CONF_COUPLING:
514                 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
515                 break;
516         case SR_CONF_VDIV:
517                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
518                 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
519                         rational[0] = g_variant_new_uint64(vdivs[i][0]);
520                         rational[1] = g_variant_new_uint64(vdivs[i][1]);
521                         tuple = g_variant_new_tuple(rational, 2);
522                         g_variant_builder_add_value(&gvb, tuple);
523                 }
524                 *data = g_variant_builder_end(&gvb);
525                 break;
526         case SR_CONF_TIMEBASE:
527                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
528                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
529                         rational[0] = g_variant_new_uint64(timebases[i][0]);
530                         rational[1] = g_variant_new_uint64(timebases[i][1]);
531                         tuple = g_variant_new_tuple(rational, 2);
532                         g_variant_builder_add_value(&gvb, tuple);
533                 }
534                 *data = g_variant_builder_end(&gvb);
535                 break;
536         case SR_CONF_TRIGGER_SOURCE:
537                 if (!sdi || !sdi->priv)
538                         /* Can't know this until we have the exact model. */
539                         return SR_ERR_ARG;
540                 devc = sdi->priv;
541                 *data = g_variant_new_strv(trigger_sources,
542                                 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
543                 break;
544         default:
545                 return SR_ERR_NA;
546         }
547
548         return SR_OK;
549 }
550
551 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
552 {
553         struct sr_serial_dev_inst *serial;
554         struct dev_context *devc;
555         struct sr_probe *probe;
556         GSList *l;
557         char cmd[256];
558
559         if (sdi->status != SR_ST_ACTIVE)
560                 return SR_ERR_DEV_CLOSED;
561
562         serial = sdi->conn;
563         devc = sdi->priv;
564
565         for (l = sdi->probes; l; l = l->next) {
566                 probe = l->data;
567                 sr_dbg("handling probe %s", probe->name);
568                 if (probe->type == SR_PROBE_ANALOG) {
569                         if (probe->enabled)
570                                 devc->enabled_analog_probes = g_slist_append(
571                                                 devc->enabled_analog_probes, probe);
572                         if (probe->enabled != devc->analog_channels[probe->index]) {
573                                 /* Enabled channel is currently disabled, or vice versa. */
574                                 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
575                                                 probe->enabled ? "ON" : "OFF");
576                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
577                                         return SR_ERR;
578                         }
579                 } else if (probe->type == SR_PROBE_LOGIC) {
580                         if (probe->enabled)
581                                 devc->enabled_digital_probes = g_slist_append(
582                                                 devc->enabled_digital_probes, probe);
583                         if (probe->enabled != devc->digital_channels[probe->index]) {
584                                 /* Enabled channel is currently disabled, or vice versa. */
585                                 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
586                                                 probe->enabled ? "ON" : "OFF");
587                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
588                                         return SR_ERR;
589                         }
590                 }
591         }
592         if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
593                 return SR_ERR;
594
595         sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
596
597         /* Send header packet to the session bus. */
598         std_session_send_df_header(cb_data, LOG_PREFIX);
599
600         /* Fetch the first frame. */
601         if (devc->enabled_analog_probes) {
602                 devc->channel_frame = devc->enabled_analog_probes->data;
603                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
604                                 devc->channel_frame->index + 1) != SR_OK)
605                         return SR_ERR;
606         } else {
607                 devc->channel_frame = devc->enabled_digital_probes->data;
608                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
609                         return SR_ERR;
610         }
611
612         devc->num_frame_bytes = 0;
613
614         return SR_OK;
615 }
616
617 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
618 {
619         struct dev_context *devc;
620         struct sr_serial_dev_inst *serial;
621
622         (void)cb_data;
623
624         devc = sdi->priv;
625
626         if (sdi->status != SR_ST_ACTIVE) {
627                 sr_err("Device inactive, can't stop acquisition.");
628                 return SR_ERR;
629         }
630
631         g_slist_free(devc->enabled_analog_probes);
632         g_slist_free(devc->enabled_digital_probes);
633         devc->enabled_analog_probes = NULL;
634         devc->enabled_digital_probes = NULL;
635         serial = sdi->conn;
636         sr_source_remove(serial->fd);
637
638         return SR_OK;
639 }
640
641 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
642         .name = "rigol-ds1xx2",
643         .longname = "Rigol DS1xx2",
644         .api_version = 1,
645         .init = init,
646         .cleanup = cleanup,
647         .scan = scan,
648         .dev_list = dev_list,
649         .dev_clear = dev_clear,
650         .config_get = config_get,
651         .config_set = config_set,
652         .config_list = config_list,
653         .dev_open = dev_open,
654         .dev_close = dev_close,
655         .dev_acquisition_start = dev_acquisition_start,
656         .dev_acquisition_stop = dev_acquisition_stop,
657         .priv = NULL,
658 };