]> sigrok.org Git - libsigrok.git/blob - hardware/rigol-ds1xx2/api.c
rigol-ds1xx2: detect Rigol DS1xx2 with upgraded bandwith
[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         "DS1152E",
137         "DS1052D",
138         "DS1102D",
139         "DS1152D",
140 };
141
142 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info;
143 static struct sr_dev_driver *di = &rigol_ds1xx2_driver_info;
144
145 static void clear_helper(void *priv)
146 {
147         struct dev_context *devc;
148
149         devc = priv;
150
151         g_free(devc->coupling[0]);
152         g_free(devc->coupling[1]);
153         g_free(devc->trigger_source);
154         g_free(devc->trigger_slope);
155 }
156
157 static int dev_clear(void)
158 {
159         return std_dev_clear(di, clear_helper);
160 }
161
162 static int set_cfg(const struct sr_dev_inst *sdi, const char *format, ...)
163 {
164         va_list args;
165         char buf[256];
166
167         va_start(args, format);
168         vsnprintf(buf, 255, format, args);
169         va_end(args);
170         if (rigol_ds1xx2_send(sdi, buf) != SR_OK)
171                 return SR_ERR;
172
173         /* When setting a bunch of parameters in a row, the DS1052E scrambles
174          * some of them unless there is at least 100ms delay in between. */
175         sr_spew("delay %dms", 100);
176         g_usleep(100000);
177
178         return SR_OK;
179 }
180
181 static int init(struct sr_context *sr_ctx)
182 {
183         return std_init(sr_ctx, di, LOG_PREFIX);
184 }
185
186 static int probe_port(const char *port, GSList **devices)
187 {
188         struct dev_context *devc;
189         struct sr_dev_inst *sdi;
190         struct sr_serial_dev_inst *serial;
191         struct sr_probe *probe;
192         unsigned int i;
193         int len, num_tokens;
194         gboolean matched, has_digital;
195         const char *manufacturer, *model, *version;
196         char buf[256];
197         gchar **tokens, *channel_name;
198
199         *devices = NULL;
200         if (!(serial = sr_serial_dev_inst_new(port, NULL)))
201                 return SR_ERR_MALLOC;
202
203         if (serial_open(serial, SERIAL_RDWR) != SR_OK)
204                 return SR_ERR;
205         len = serial_write(serial, "*IDN?", 5);
206         len = serial_read(serial, buf, sizeof(buf));
207         if (serial_close(serial) != SR_OK)
208                 return SR_ERR;
209
210         sr_serial_dev_inst_free(serial);
211
212         if (len == 0)
213                 return SR_ERR_NA;
214
215         buf[len] = 0;
216         tokens = g_strsplit(buf, ",", 0);
217         sr_dbg("response: %s [%s]", port, buf);
218
219         for (num_tokens = 0; tokens[num_tokens] != NULL; num_tokens++);
220
221         if (num_tokens < 4) {
222                 g_strfreev(tokens);
223                 return SR_ERR_NA;
224         }
225
226         manufacturer = tokens[0];
227         model = tokens[1];
228         version = tokens[3];
229
230         if (strcmp(manufacturer, "Rigol Technologies")) {
231                 g_strfreev(tokens);
232                 return SR_ERR_NA;
233         }
234
235         matched = has_digital = FALSE;
236         for (i = 0; i < ARRAY_SIZE(supported_models); i++) {
237                 if (!strcmp(model, supported_models[i])) {
238                         matched = TRUE;
239                         has_digital = g_str_has_suffix(model, "D");
240                         break;
241                 }
242         }
243
244         if (!matched || !(sdi = sr_dev_inst_new(0, SR_ST_ACTIVE,
245                 manufacturer, model, version))) {
246                 g_strfreev(tokens);
247                 return SR_ERR_NA;
248         }
249
250         g_strfreev(tokens);
251
252         if (!(sdi->conn = sr_serial_dev_inst_new(port, NULL)))
253                 return SR_ERR_MALLOC;
254         sdi->driver = di;
255         sdi->inst_type = SR_INST_SERIAL;
256
257         if (!(devc = g_try_malloc0(sizeof(struct dev_context))))
258                 return SR_ERR_MALLOC;
259         devc->limit_frames = 0;
260         devc->has_digital = has_digital;
261
262         for (i = 0; i < 2; i++) {
263                 if (!(probe = sr_probe_new(i, SR_PROBE_ANALOG, TRUE,
264                                 i == 0 ? "CH1" : "CH2")))
265                         return SR_ERR_MALLOC;
266                 sdi->probes = g_slist_append(sdi->probes, probe);
267         }
268
269         if (devc->has_digital) {
270                 for (i = 0; i < 16; i++) {
271                         if (!(channel_name = g_strdup_printf("D%d", i)))
272                                 return SR_ERR_MALLOC;
273                         probe = sr_probe_new(i, SR_PROBE_LOGIC, TRUE, channel_name);
274                         g_free(channel_name);
275                         if (!probe)
276                                 return SR_ERR_MALLOC;
277                         sdi->probes = g_slist_append(sdi->probes, probe);
278                 }
279         }
280         sdi->priv = devc;
281
282         *devices = g_slist_append(NULL, sdi);
283
284         return SR_OK;
285 }
286
287 static GSList *scan(GSList *options)
288 {
289         struct drv_context *drvc;
290         struct sr_config *src;
291         GSList *l, *devices;
292         GDir *dir;
293         int ret;
294         const gchar *dev_name;
295         gchar *port = NULL;
296
297         drvc = di->priv;
298
299         for (l = options; l; l = l->next) {
300                 src = l->data;
301                 if (src->key == SR_CONF_CONN) {
302                         port = (char *)g_variant_get_string(src->data, NULL);
303                         break;
304                 }
305         }
306
307         devices = NULL;
308         if (port) {
309                 if (probe_port(port, &devices) == SR_ERR_MALLOC)
310                         return NULL;
311         } else {
312                 if (!(dir = g_dir_open("/sys/class/usbmisc/", 0, NULL)))
313                         if (!(dir = g_dir_open("/sys/class/usb/", 0, NULL)))
314                                 return NULL;
315                 while ((dev_name = g_dir_read_name(dir))) {
316                         if (strncmp(dev_name, "usbtmc", 6))
317                                 continue;
318                         port = g_strconcat("/dev/", dev_name, NULL);
319                         ret = probe_port(port, &devices);
320                         g_free(port);
321                         if (ret == SR_ERR_MALLOC) {
322                                 g_dir_close(dir);
323                                 return NULL;
324                         }
325                 }
326                 g_dir_close(dir);
327         }
328
329         /* Tack a copy of the newly found devices onto the driver list. */
330         l = g_slist_copy(devices);
331         drvc->instances = g_slist_concat(drvc->instances, l);
332
333         return devices;
334 }
335
336 static GSList *dev_list(void)
337 {
338         return ((struct drv_context *)(di->priv))->instances;
339 }
340
341 static int dev_open(struct sr_dev_inst *sdi)
342 {
343
344         if (serial_open(sdi->conn, SERIAL_RDWR) != SR_OK)
345                 return SR_ERR;
346
347         if (rigol_ds1xx2_get_dev_cfg(sdi) != SR_OK)
348                 return SR_ERR;
349
350         sdi->status = SR_ST_ACTIVE;
351
352         return SR_OK;
353 }
354
355 static int dev_close(struct sr_dev_inst *sdi)
356 {
357         struct sr_serial_dev_inst *serial;
358
359         serial = sdi->conn;
360         if (serial && serial->fd != -1) {
361                 serial_close(serial);
362                 sdi->status = SR_ST_INACTIVE;
363         }
364
365         return SR_OK;
366 }
367
368 static int cleanup(void)
369 {
370         return dev_clear();
371 }
372
373 static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
374 {
375
376         (void)sdi;
377
378         switch (id) {
379         case SR_CONF_NUM_TIMEBASE:
380                 *data = g_variant_new_int32(NUM_TIMEBASE);
381                 break;
382         case SR_CONF_NUM_VDIV:
383                 *data = g_variant_new_int32(NUM_VDIV);
384                 break;
385         default:
386                 return SR_ERR_NA;
387         }
388
389         return SR_OK;
390 }
391
392 static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi)
393 {
394         struct dev_context *devc;
395         uint64_t tmp_u64, p, q;
396         double t_dbl;
397         unsigned int i;
398         int ret;
399         const char *tmp_str;
400
401         devc = sdi->priv;
402
403         if (sdi->status != SR_ST_ACTIVE)
404                 return SR_ERR_DEV_CLOSED;
405
406         ret = SR_OK;
407         switch (id) {
408         case SR_CONF_LIMIT_FRAMES:
409                 devc->limit_frames = g_variant_get_uint64(data);
410                 break;
411         case SR_CONF_TRIGGER_SLOPE:
412                 tmp_u64 = g_variant_get_uint64(data);
413                 if (tmp_u64 != 0 && tmp_u64 != 1)
414                         return SR_ERR;
415                 g_free(devc->trigger_slope);
416                 devc->trigger_slope = g_strdup(tmp_u64 ? "POS" : "NEG");
417                 ret = set_cfg(sdi, ":TRIG:EDGE:SLOP %s", devc->trigger_slope);
418                 break;
419         case SR_CONF_HORIZ_TRIGGERPOS:
420                 t_dbl = g_variant_get_double(data);
421                 if (t_dbl < 0.0 || t_dbl > 1.0)
422                         return SR_ERR;
423                 devc->horiz_triggerpos = t_dbl;
424                 /* We have the trigger offset as a percentage of the frame, but
425                  * need to express this in seconds. */
426                 t_dbl = -(devc->horiz_triggerpos - 0.5) * devc->timebase * NUM_TIMEBASE;
427                 ret = set_cfg(sdi, ":TIM:OFFS %.6f", t_dbl);
428                 break;
429         case SR_CONF_TIMEBASE:
430                 g_variant_get(data, "(tt)", &p, &q);
431                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
432                         if (timebases[i][0] == p && timebases[i][1] == q) {
433                                 devc->timebase = (float)p / q;
434                                 ret = set_cfg(sdi, ":TIM:SCAL %.9f", devc->timebase);
435                                 break;
436                         }
437                 }
438                 if (i == ARRAY_SIZE(timebases))
439                         ret = SR_ERR_ARG;
440                 break;
441         case SR_CONF_TRIGGER_SOURCE:
442                 tmp_str = g_variant_get_string(data, NULL);
443                 for (i = 0; i < ARRAY_SIZE(trigger_sources); i++) {
444                         if (!strcmp(trigger_sources[i], tmp_str)) {
445                                 g_free(devc->trigger_source);
446                                 devc->trigger_source = g_strdup(trigger_sources[i]);
447                                 if (!strcmp(devc->trigger_source, "AC Line"))
448                                         tmp_str = "ACL";
449                                 else if (!strcmp(devc->trigger_source, "CH1"))
450                                         tmp_str = "CHAN1";
451                                 else if (!strcmp(devc->trigger_source, "CH2"))
452                                         tmp_str = "CHAN2";
453                                 else
454                                         tmp_str = (char *)devc->trigger_source;
455                                 ret = set_cfg(sdi, ":TRIG:EDGE:SOUR %s", tmp_str);
456                                 break;
457                         }
458                 }
459                 if (i == ARRAY_SIZE(trigger_sources))
460                         ret = SR_ERR_ARG;
461                 break;
462         case SR_CONF_VDIV:
463                 g_variant_get(data, "(tt)", &p, &q);
464                 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
465                         if (vdivs[i][0] != p || vdivs[i][1] != q)
466                                 continue;
467                         devc->vdiv[0] = devc->vdiv[1] = (float)p / q;
468                         set_cfg(sdi, ":CHAN1:SCAL %.3f", devc->vdiv[0]);
469                         ret = set_cfg(sdi, ":CHAN2:SCAL %.3f", devc->vdiv[1]);
470                         break;
471                 }
472                 if (i == ARRAY_SIZE(vdivs))
473                         ret = SR_ERR_ARG;
474                 break;
475         case SR_CONF_COUPLING:
476                 /* TODO: Not supporting coupling per channel yet. */
477                 tmp_str = g_variant_get_string(data, NULL);
478                 for (i = 0; i < ARRAY_SIZE(coupling); i++) {
479                         if (!strcmp(tmp_str, coupling[i])) {
480                                 g_free(devc->coupling[0]);
481                                 g_free(devc->coupling[1]);
482                                 devc->coupling[0] = g_strdup(coupling[i]);
483                                 devc->coupling[1] = g_strdup(coupling[i]);
484                                 set_cfg(sdi, ":CHAN1:COUP %s", devc->coupling[0]);
485                                 ret = set_cfg(sdi, ":CHAN2:COUP %s", devc->coupling[1]);
486                                 break;
487                         }
488                 }
489                 if (i == ARRAY_SIZE(coupling))
490                         ret = SR_ERR_ARG;
491                 break;
492         default:
493                 ret = SR_ERR_NA;
494                 break;
495         }
496
497         return ret;
498 }
499
500 static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi)
501 {
502         GVariant *tuple, *rational[2];
503         GVariantBuilder gvb;
504         unsigned int i;
505         struct dev_context *devc;
506
507         switch (key) {
508         case SR_CONF_SCAN_OPTIONS:
509                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
510                                 hwopts, ARRAY_SIZE(hwopts), sizeof(int32_t));
511                 break;
512         case SR_CONF_DEVICE_OPTIONS:
513                 *data = g_variant_new_fixed_array(G_VARIANT_TYPE_INT32,
514                                 hwcaps, ARRAY_SIZE(hwcaps), sizeof(int32_t));
515                 break;
516         case SR_CONF_COUPLING:
517                 *data = g_variant_new_strv(coupling, ARRAY_SIZE(coupling));
518                 break;
519         case SR_CONF_VDIV:
520                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
521                 for (i = 0; i < ARRAY_SIZE(vdivs); i++) {
522                         rational[0] = g_variant_new_uint64(vdivs[i][0]);
523                         rational[1] = g_variant_new_uint64(vdivs[i][1]);
524                         tuple = g_variant_new_tuple(rational, 2);
525                         g_variant_builder_add_value(&gvb, tuple);
526                 }
527                 *data = g_variant_builder_end(&gvb);
528                 break;
529         case SR_CONF_TIMEBASE:
530                 g_variant_builder_init(&gvb, G_VARIANT_TYPE_ARRAY);
531                 for (i = 0; i < ARRAY_SIZE(timebases); i++) {
532                         rational[0] = g_variant_new_uint64(timebases[i][0]);
533                         rational[1] = g_variant_new_uint64(timebases[i][1]);
534                         tuple = g_variant_new_tuple(rational, 2);
535                         g_variant_builder_add_value(&gvb, tuple);
536                 }
537                 *data = g_variant_builder_end(&gvb);
538                 break;
539         case SR_CONF_TRIGGER_SOURCE:
540                 if (!sdi || !sdi->priv)
541                         /* Can't know this until we have the exact model. */
542                         return SR_ERR_ARG;
543                 devc = sdi->priv;
544                 *data = g_variant_new_strv(trigger_sources,
545                                 devc->has_digital ? ARRAY_SIZE(trigger_sources) : 4);
546                 break;
547         default:
548                 return SR_ERR_NA;
549         }
550
551         return SR_OK;
552 }
553
554 static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
555 {
556         struct sr_serial_dev_inst *serial;
557         struct dev_context *devc;
558         struct sr_probe *probe;
559         GSList *l;
560         char cmd[256];
561
562         if (sdi->status != SR_ST_ACTIVE)
563                 return SR_ERR_DEV_CLOSED;
564
565         serial = sdi->conn;
566         devc = sdi->priv;
567
568         for (l = sdi->probes; l; l = l->next) {
569                 probe = l->data;
570                 sr_dbg("handling probe %s", probe->name);
571                 if (probe->type == SR_PROBE_ANALOG) {
572                         if (probe->enabled)
573                                 devc->enabled_analog_probes = g_slist_append(
574                                                 devc->enabled_analog_probes, probe);
575                         if (probe->enabled != devc->analog_channels[probe->index]) {
576                                 /* Enabled channel is currently disabled, or vice versa. */
577                                 sprintf(cmd, ":CHAN%d:DISP %s", probe->index + 1,
578                                                 probe->enabled ? "ON" : "OFF");
579                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
580                                         return SR_ERR;
581                         }
582                 } else if (probe->type == SR_PROBE_LOGIC) {
583                         if (probe->enabled)
584                                 devc->enabled_digital_probes = g_slist_append(
585                                                 devc->enabled_digital_probes, probe);
586                         if (probe->enabled != devc->digital_channels[probe->index]) {
587                                 /* Enabled channel is currently disabled, or vice versa. */
588                                 sprintf(cmd, ":DIG%d:TURN %s", probe->index,
589                                                 probe->enabled ? "ON" : "OFF");
590                                 if (rigol_ds1xx2_send(sdi, cmd) != SR_OK)
591                                         return SR_ERR;
592                         }
593                 }
594         }
595         if (!devc->enabled_analog_probes && !devc->enabled_digital_probes)
596                 return SR_ERR;
597
598         sr_source_add(serial->fd, G_IO_IN, 50, rigol_ds1xx2_receive, (void *)sdi);
599
600         /* Send header packet to the session bus. */
601         std_session_send_df_header(cb_data, LOG_PREFIX);
602
603         /* Fetch the first frame. */
604         if (devc->enabled_analog_probes) {
605                 devc->channel_frame = devc->enabled_analog_probes->data;
606                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? CHAN%d",
607                                 devc->channel_frame->index + 1) != SR_OK)
608                         return SR_ERR;
609         } else {
610                 devc->channel_frame = devc->enabled_digital_probes->data;
611                 if (rigol_ds1xx2_send(sdi, ":WAV:DATA? DIG") != SR_OK)
612                         return SR_ERR;
613         }
614
615         devc->num_frame_bytes = 0;
616
617         return SR_OK;
618 }
619
620 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
621 {
622         struct dev_context *devc;
623         struct sr_serial_dev_inst *serial;
624
625         (void)cb_data;
626
627         devc = sdi->priv;
628
629         if (sdi->status != SR_ST_ACTIVE) {
630                 sr_err("Device inactive, can't stop acquisition.");
631                 return SR_ERR;
632         }
633
634         g_slist_free(devc->enabled_analog_probes);
635         g_slist_free(devc->enabled_digital_probes);
636         devc->enabled_analog_probes = NULL;
637         devc->enabled_digital_probes = NULL;
638         serial = sdi->conn;
639         sr_source_remove(serial->fd);
640
641         return SR_OK;
642 }
643
644 SR_PRIV struct sr_dev_driver rigol_ds1xx2_driver_info = {
645         .name = "rigol-ds1xx2",
646         .longname = "Rigol DS1xx2",
647         .api_version = 1,
648         .init = init,
649         .cleanup = cleanup,
650         .scan = scan,
651         .dev_list = dev_list,
652         .dev_clear = dev_clear,
653         .config_get = config_get,
654         .config_set = config_set,
655         .config_list = config_list,
656         .dev_open = dev_open,
657         .dev_close = dev_close,
658         .dev_acquisition_start = dev_acquisition_start,
659         .dev_acquisition_stop = dev_acquisition_stop,
660         .priv = NULL,
661 };