]> sigrok.org Git - libsigrok.git/blob - hardware/fx2lafw/fx2lafw.c
fx2lafw: Compile fix.
[libsigrok.git] / hardware / fx2lafw / fx2lafw.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdbool.h>
23 #include <inttypes.h>
24 #include <glib.h>
25 #include <libusb.h>
26
27 #include "config.h"
28 #include "sigrok.h"
29 #include "sigrok-internal.h"
30 #include "fx2lafw.h"
31
32 static struct fx2lafw_profile supported_fx2[] = {
33         /* USBee AX */
34         { 0x08a9, 0x0014, "CWAV", "USBee AX", NULL, 8 },
35         { 0, 0, 0, 0, 0, 0 }
36 };
37
38 static int fx2lafw_capabilities[] = {
39         SR_HWCAP_LOGIC_ANALYZER,
40         SR_HWCAP_SAMPLERATE,
41
42         /* These are really implemented in the driver, not the hardware. */
43         SR_HWCAP_LIMIT_SAMPLES,
44         SR_HWCAP_CONTINUOUS,
45         0
46 };
47
48 static const char *fx2lafw_probe_names[] = {
49         "D0",
50         "D1",
51         "D2",
52         "D3",
53         "D4",
54         "D5",
55         "D6",
56         "D7",
57         NULL
58 };
59
60 static uint64_t fx2lafw_supported_samplerates[] = {
61         SR_MHZ(1),
62         SR_MHZ(2),
63         SR_MHZ(3),
64         SR_MHZ(4),
65         SR_MHZ(6),
66         SR_MHZ(8),
67         SR_MHZ(12),
68         SR_MHZ(16),
69         SR_MHZ(24)
70 };
71
72 static struct sr_samplerates fx2lafw_samplerates = {
73         SR_MHZ(1),
74         SR_MHZ(24),
75         SR_HZ(0),
76         fx2lafw_supported_samplerates
77 };
78
79 static GSList *dev_insts = NULL;
80 static libusb_context *usb_context = NULL;
81
82 static int hw_dev_acquisition_stop(int dev_index, gpointer session_dev_id);
83
84 /**
85  * Check the USB configuration to determine if this is an fx2lafw device.
86  *
87  * @return true if the device's configuration profile match fx2lafw
88  *         configuration, flase otherwise.
89  */
90 static bool check_conf_profile(libusb_device *dev)
91 {
92         struct libusb_device_descriptor des;
93         struct libusb_config_descriptor *conf_dsc = NULL;
94         const struct libusb_interface_descriptor *intf_dsc;
95         bool ret = false;
96
97         while (!ret) {
98                 /* Assume it's not a Saleae Logic unless proven wrong. */
99                 ret = 0;
100
101                 if (libusb_get_device_descriptor(dev, &des) != 0)
102                         break;
103
104                 if (des.bNumConfigurations != 1)
105                         /* Need exactly 1 configuration. */
106                         break;
107
108                 if (libusb_get_config_descriptor(dev, 0, &conf_dsc) != 0)
109                         break;
110
111                 if (conf_dsc->bNumInterfaces != 1)
112                         /* Need exactly 1 interface. */
113                         break;
114
115                 if (conf_dsc->interface[0].num_altsetting != 1)
116                         /* Need just one alternate setting. */
117                         break;
118
119                 intf_dsc = &(conf_dsc->interface[0].altsetting[0]);
120                 if (intf_dsc->bNumEndpoints != 3)
121                         /* Need exactly 3 end points. */
122                         break;
123
124                 if ((intf_dsc->endpoint[0].bEndpointAddress & 0x8f) !=
125                     (1 | LIBUSB_ENDPOINT_OUT))
126                         /* The first endpoint should be 1 (outbound). */
127                         break;
128
129                 if ((intf_dsc->endpoint[1].bEndpointAddress & 0x8f) !=
130                     (2 | LIBUSB_ENDPOINT_IN))
131                         /* The second endpoint should be 2 (inbound). */
132                         break;
133
134                 /* TODO: Check the debug channel... */
135
136                 /* If we made it here, it must be an fx2lafw. */
137                 ret = true;
138         }
139
140         if (conf_dsc)
141                 libusb_free_config_descriptor(conf_dsc);
142
143         return ret;
144 }
145
146 static int fx2lafw_open_dev(int dev_index)
147 {
148         libusb_device **devlist;
149         struct libusb_device_descriptor des;
150         struct sr_dev_inst *sdi;
151         struct fx2lafw_device *ctx;
152         int err, skip, i;
153
154         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
155                 return SR_ERR;
156         ctx = sdi->priv;
157
158         if (sdi->status == SR_ST_ACTIVE)
159                 /* already in use */
160                 return SR_ERR;
161
162         skip = 0;
163         libusb_get_device_list(usb_context, &devlist);
164         for (i = 0; devlist[i]; i++) {
165                 if ((err = libusb_get_device_descriptor(devlist[i], &des))) {
166                         sr_err("fx2lafw: failed to get device descriptor: %d", err);
167                         continue;
168                 }
169
170                 if (des.idVendor != FIRMWARE_VID
171                     || des.idProduct != FIRMWARE_PID)
172                         continue;
173
174                 if (sdi->status == SR_ST_INITIALIZING) {
175                         if (skip != dev_index) {
176                                 /* Skip devices of this type that aren't the one we want. */
177                                 skip += 1;
178                                 continue;
179                         }
180                 } else if (sdi->status == SR_ST_INACTIVE) {
181                         /*
182                          * This device is fully enumerated, so we need to find
183                          * this device by vendor, product, bus and address.
184                          */
185                         if (libusb_get_bus_number(devlist[i]) != ctx->usb->bus
186                                 || libusb_get_device_address(devlist[i]) != ctx->usb->address)
187                                 /* this is not the one */
188                                 continue;
189                 }
190
191                 if (!(err = libusb_open(devlist[i], &ctx->usb->devhdl))) {
192                         if (ctx->usb->address == 0xff)
193                                 /*
194                                  * first time we touch this device after firmware upload,
195                                  * so we don't know the address yet.
196                                  */
197                                 ctx->usb->address = libusb_get_device_address(devlist[i]);
198
199                         sdi->status = SR_ST_ACTIVE;
200                         sr_info("fx2lafw: opened device %d on %d.%d interface %d",
201                                 sdi->index, ctx->usb->bus,
202                                 ctx->usb->address, USB_INTERFACE);
203                 } else {
204                         sr_err("fx2lafw: failed to open device: %d", err);
205                 }
206
207                 /* if we made it here, we handled the device one way or another */
208                 break;
209         }
210         libusb_free_device_list(devlist, 1);
211
212         if (sdi->status != SR_ST_ACTIVE)
213                 return SR_ERR;
214
215         return SR_OK;
216 }
217
218 static void close_dev(struct sr_dev_inst *sdi)
219 {
220         struct fx2lafw_device *ctx;
221
222         ctx = sdi->priv;
223
224         if (ctx->usb->devhdl == NULL)
225                 return;
226
227         sr_info("fx2lafw: closing device %d on %d.%d interface %d", sdi->index,
228                 ctx->usb->bus, ctx->usb->address, USB_INTERFACE);
229         libusb_release_interface(ctx->usb->devhdl, USB_INTERFACE);
230         libusb_close(ctx->usb->devhdl);
231         ctx->usb->devhdl = NULL;
232         sdi->status = SR_ST_INACTIVE;
233 }
234
235 static struct fx2lafw_device* fx2lafw_device_new(void)
236 {
237         struct fx2lafw_device *fx2lafw;
238
239         if (!(fx2lafw = g_try_malloc0(sizeof(struct fx2lafw_device)))) {
240                 sr_err("fx2lafw: %s: fx2lafw_device malloc failed", __func__);
241                 return NULL;
242         }
243
244         return fx2lafw;
245 }
246
247 /*
248  * API callbacks
249  */
250
251 static int hw_init(const char *deviceinfo)
252 {
253         struct sr_dev_inst *sdi;
254         struct libusb_device_descriptor des;
255         struct fx2lafw_profile *fx2lafw_prof;
256         struct fx2lafw_device *ctx;
257         libusb_device **devlist;
258         int err;
259         int devcnt = 0;
260         int i, j;
261
262         /* Avoid compiler warnings. */
263         (void)deviceinfo;
264
265         if (libusb_init(&usb_context) != 0) {
266                 sr_warn("Failed to initialize USB.");
267                 return 0;
268         }
269
270         /* Find all fx2lafw compatible devices and upload firware to all of them. */
271         libusb_get_device_list(usb_context, &devlist);
272         for (i = 0; devlist[i]; i++) {
273
274                 if ((err = libusb_get_device_descriptor(
275                         devlist[i], &des)) != 0) {
276                         sr_warn("failed to get device descriptor: %d", err);
277                         continue;
278                 }
279
280                 fx2lafw_prof = NULL;
281                 for (j = 0; supported_fx2[j].vid; j++) {
282                         if (des.idVendor == supported_fx2[j].vid &&
283                                 des.idProduct == supported_fx2[j].pid) {
284                                 fx2lafw_prof = &supported_fx2[j];
285                         }
286                 }
287
288                 /* Skip if the device was not found */
289                 if(!fx2lafw_prof)
290                         continue;
291
292                 sdi = sr_dev_inst_new(devcnt, SR_ST_INITIALIZING,
293                         fx2lafw_prof->vendor, fx2lafw_prof->model,
294                         fx2lafw_prof->model_version);
295                 if(!sdi)
296                         return 0;
297
298                 ctx = fx2lafw_device_new();
299                 ctx->profile = fx2lafw_prof;
300                 sdi->priv = ctx;
301                 dev_insts = g_slist_append(dev_insts, sdi);
302
303                 if (check_conf_profile(devlist[i])) {
304                         /* Already has the firmware, so fix the new address. */
305                         sr_dbg("fx2lafw: Found a fx2lafw device.");
306                         sdi->status = SR_ST_INACTIVE;
307                         ctx->usb = sr_usb_dev_inst_new
308                             (libusb_get_bus_number(devlist[i]),
309                              libusb_get_device_address(devlist[i]), NULL);
310                 } else {
311                         if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, FIRMWARE) == SR_OK)
312                                 /* Remember when the firmware on this device was updated */
313                                 g_get_current_time(&ctx->fw_updated);
314                         else
315                                 sr_err("fx2lafw: firmware upload failed for "
316                                        "device %d", devcnt);
317                         ctx->usb = sr_usb_dev_inst_new
318                                 (libusb_get_bus_number(devlist[i]), 0xff, NULL);
319                 }
320
321                 devcnt++;
322         }
323         libusb_free_device_list(devlist, 1);
324
325         return devcnt;
326 }
327
328 static int hw_dev_open(int device_index)
329 {
330         GTimeVal cur_time;
331         struct sr_dev_inst *sdi;
332         struct fx2lafw_device *ctx;
333         int timediff, err;
334
335         if (!(sdi = sr_dev_inst_get(dev_insts, device_index)))
336                 return SR_ERR;
337         ctx = sdi->priv;
338
339         /*
340          * if the firmware was recently uploaded, wait up to MAX_RENUM_DELAY ms
341          * for the FX2 to renumerate
342          */
343         err = 0;
344         if (GTV_TO_MSEC(ctx->fw_updated) > 0) {
345                 sr_info("fx2lafw: waiting for device to reset");
346                 /* takes at least 300ms for the FX2 to be gone from the USB bus */
347                 g_usleep(300 * 1000);
348                 timediff = 0;
349                 while (timediff < MAX_RENUM_DELAY) {
350                         if ((err = fx2lafw_open_dev(device_index)) == SR_OK)
351                                 break;
352                         g_usleep(100 * 1000);
353                         g_get_current_time(&cur_time);
354                         timediff = GTV_TO_MSEC(cur_time) - GTV_TO_MSEC(ctx->fw_updated);
355                 }
356                 sr_info("fx2lafw: device came back after %d ms", timediff);
357         } else {
358                 err = fx2lafw_open_dev(device_index);
359         }
360
361         if (err != SR_OK) {
362                 sr_err("fx2lafw: unable to open device");
363                 return SR_ERR;
364         }
365         ctx = sdi->priv;
366
367         err = libusb_claim_interface(ctx->usb->devhdl, USB_INTERFACE);
368         if (err != 0) {
369                 sr_err("fx2lafw: Unable to claim interface: %d", err);
370                 return SR_ERR;
371         }
372
373         return SR_OK;
374 }
375
376 static int hw_dev_close(int dev_index)
377 {
378         struct sr_dev_inst *sdi;
379
380         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) {
381                 sr_err("fx2lafw: %s: sdi was NULL", __func__);
382                 return SR_ERR; /* TODO: SR_ERR_ARG? */
383         }
384
385         /* TODO */
386         close_dev(sdi);
387
388         return SR_OK;
389 }
390
391 static int hw_cleanup(void)
392 {
393         GSList *l;
394         struct sr_dev_inst *sdi;
395         struct fx2lafw_device *ctx;
396         int ret = SR_OK;
397
398         for(l = dev_insts; l; l = l->next) {
399                 if (!(sdi = l->data)) {
400                         /* Log error, but continue cleaning up the rest. */
401                         sr_err("fx2lafw: %s: sdi was NULL, continuing", __func__);
402                         ret = SR_ERR_BUG;
403                         continue;
404                 }
405                 if (!(ctx = sdi->priv)) {
406                         /* Log error, but continue cleaning up the rest. */
407                         sr_err("fx2lafw: %s: sdi->priv was NULL, continuing",
408                                __func__);
409                         ret = SR_ERR_BUG;
410                         continue;
411                 }
412                 close_dev(sdi);
413                 sdi = l->data;
414                 sr_dev_inst_free(sdi);
415         }
416
417         g_slist_free(dev_insts);
418         dev_insts = NULL;
419
420         if(usb_context)
421                 libusb_exit(usb_context);
422         usb_context = NULL;
423
424         return ret;
425 }
426
427 static void *hw_dev_info_get(int device_index, int device_info_id)
428 {
429         struct sr_dev_inst *sdi;
430         struct fx2lafw_device *ctx;
431
432         if (!(sdi = sr_dev_inst_get(dev_insts, device_index)))
433                 return NULL;
434         ctx = sdi->priv;
435
436         switch (device_info_id) {
437         case SR_DI_INST:
438                 return sdi;
439         case SR_DI_NUM_PROBES:
440                 return GINT_TO_POINTER(ctx->profile->num_probes);
441         case SR_DI_PROBE_NAMES:
442                 return fx2lafw_probe_names;
443         case SR_DI_SAMPLERATES:
444                 return &fx2lafw_samplerates;
445         case SR_DI_TRIGGER_TYPES:
446                 return TRIGGER_TYPES;
447         }
448
449         return NULL;
450 }
451
452 static int hw_dev_status_get(int device_index)
453 {
454         const struct sr_dev_inst *const sdi =
455                 sr_dev_inst_get(dev_insts, device_index);
456
457         if (!sdi)
458                 return SR_ST_NOT_FOUND;
459
460         return sdi->status;
461 }
462
463 static int *hw_hwcap_get_all(void)
464 {
465         return fx2lafw_capabilities;
466 }
467
468 static int hw_dev_config_set(int dev_index, int hwcap, void *value)
469 {
470         struct sr_dev_inst *sdi;
471         struct fx2lafw_device *ctx;
472         int ret;
473
474         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
475                 return SR_ERR;
476         ctx = sdi->priv;
477
478         if (hwcap == SR_HWCAP_LIMIT_SAMPLES) {
479                 ctx->limit_samples = *(uint64_t *)value;
480                 ret = SR_OK;
481         } else {
482                 ret = SR_ERR;
483         }
484
485         return ret;
486 }
487
488 static int receive_data(int fd, int revents, void *user_data)
489 {
490         struct timeval tv;
491
492         /* Avoid compiler warnings. */
493         (void)fd;
494         (void)revents;
495         (void)user_data;
496
497         tv.tv_sec = tv.tv_usec = 0;
498         libusb_handle_events_timeout(usb_context, &tv);
499
500         return TRUE;
501 }
502
503 static void receive_transfer(struct libusb_transfer *transfer)
504 {
505         /* TODO: These statics have to move to the ctx struct. */
506         static int num_samples = 0;
507         static int empty_transfer_count = 0;
508         struct sr_datafeed_packet packet;
509         struct sr_datafeed_logic logic;
510         struct fx2lafw_device *ctx;
511         int cur_buflen;
512         unsigned char *cur_buf, *new_buf;
513
514         /* hw_dev_acquisition_stop() is telling us to stop. */
515         if (transfer == NULL)
516                 num_samples = -1;
517
518         /*
519          * If acquisition has already ended, just free any queued up
520          * transfer that come in.
521          */
522         if (num_samples == -1) {
523                 if (transfer)
524                         libusb_free_transfer(transfer);
525                 return;
526         }
527
528         sr_info("fx2lafw: receive_transfer(): status %d received %d bytes",
529                 transfer->status, transfer->actual_length);
530
531         /* Save incoming transfer before reusing the transfer struct. */
532         cur_buf = transfer->buffer;
533         cur_buflen = transfer->actual_length;
534         ctx = transfer->user_data;
535
536         /* Fire off a new request. */
537         if (!(new_buf = g_try_malloc(4096))) {
538                 sr_err("fx2lafw: %s: new_buf malloc failed", __func__);
539                 return; /* TODO: SR_ERR_MALLOC */
540         }
541
542         transfer->buffer = new_buf;
543         transfer->length = 4096;
544         if (libusb_submit_transfer(transfer) != 0) {
545                 /* TODO: Stop session? */
546                 /* TODO: Better error message. */
547                 sr_err("fx2lafw: %s: libusb_submit_transfer error", __func__);
548         }
549
550         if (cur_buflen == 0) {
551                 empty_transfer_count++;
552                 if (empty_transfer_count > MAX_EMPTY_TRANSFERS) {
553                         /*
554                          * The FX2 gave up. End the acquisition, the frontend
555                          * will work out that the samplecount is short.
556                          */
557                         hw_dev_acquisition_stop(-1, ctx->session_data);
558                 }
559                 return;
560         } else {
561                 empty_transfer_count = 0;
562         }
563
564         /* Send the incoming transfer to the session bus. */
565         packet.type = SR_DF_LOGIC;
566         packet.payload = &logic;
567         logic.length = cur_buflen;
568         logic.unitsize = 1;
569         logic.data = cur_buf;
570         sr_session_bus(ctx->session_data, &packet);
571         g_free(cur_buf);
572
573         num_samples += cur_buflen;
574         if (ctx->limit_samples &&
575                 (unsigned int) num_samples > ctx->limit_samples) {
576                 hw_dev_acquisition_stop(-1, ctx->session_data);
577         }
578 }
579
580 static int hw_dev_acquisition_start(int dev_index, gpointer session_data)
581 {
582         struct sr_dev_inst *sdi;
583         struct sr_datafeed_packet *packet;
584         struct sr_datafeed_header *header;
585         struct fx2lafw_device *ctx;
586         struct libusb_transfer *transfer;
587         const struct libusb_pollfd **lupfd;
588         int size, i;
589         unsigned char *buf;
590
591         if (!(sdi = sr_dev_inst_get(dev_insts, dev_index)))
592                 return SR_ERR;
593         ctx = sdi->priv;
594         ctx->session_data = session_data;
595
596         if (!(packet = g_try_malloc(sizeof(struct sr_datafeed_packet)))) {
597                 sr_err("fx2lafw: %s: packet malloc failed", __func__);
598                 return SR_ERR_MALLOC;
599         }
600
601         if (!(header = g_try_malloc(sizeof(struct sr_datafeed_header)))) {
602                 sr_err("fx2lafw: %s: header malloc failed", __func__);
603                 return SR_ERR_MALLOC;
604         }
605
606         /* Start with 2K transfer, subsequently increased to 4K. */
607         size = 2048;
608         for (i = 0; i < NUM_SIMUL_TRANSFERS; i++) {
609                 if (!(buf = g_try_malloc(size))) {
610                         sr_err("fx2lafw: %s: buf malloc failed", __func__);
611                         return SR_ERR_MALLOC;
612                 }
613                 transfer = libusb_alloc_transfer(0);
614                 libusb_fill_bulk_transfer(transfer, ctx->usb->devhdl,
615                                 2 | LIBUSB_ENDPOINT_IN, buf, size,
616                                 receive_transfer, ctx, 40);
617                 if (libusb_submit_transfer(transfer) != 0) {
618                         /* TODO: Free them all. */
619                         libusb_free_transfer(transfer);
620                         g_free(buf);
621                         return SR_ERR;
622                 }
623                 size = 4096;
624         }
625
626         lupfd = libusb_get_pollfds(usb_context);
627         for (i = 0; lupfd[i]; i++)
628                 sr_source_add(lupfd[i]->fd, lupfd[i]->events,
629                               40, receive_data, NULL);
630         free(lupfd); /* NOT g_free()! */
631
632         packet->type = SR_DF_HEADER;
633         packet->payload = header;
634         header->feed_version = 1;
635         gettimeofday(&header->starttime, NULL);
636         header->samplerate = 24000000UL;
637         header->num_logic_probes = ctx->profile->num_probes;
638         sr_session_bus(session_data, packet);
639         g_free(header);
640         g_free(packet);
641
642         return SR_OK;
643 }
644
645 /* This stops acquisition on ALL devices, ignoring device_index. */
646 static int hw_dev_acquisition_stop(int dev_index, gpointer session_data)
647 {
648         struct sr_datafeed_packet packet;
649
650         /* Avoid compiler warnings. */
651         (void)dev_index;
652
653         packet.type = SR_DF_END;
654         sr_session_bus(session_data, &packet);
655
656         receive_transfer(NULL);
657
658         /* TODO: Need to cancel and free any queued up transfers. */
659
660         return SR_OK;
661 }
662
663 SR_PRIV struct sr_dev_plugin fx2lafw_plugin_info = {
664         .name = "fx2lafw",
665         .longname = "fx2lafw",
666         .api_version = 1,
667         .init = hw_init,
668         .cleanup = hw_cleanup,
669         .dev_open = hw_dev_open,
670         .dev_close = hw_dev_close,
671         .dev_info_get = hw_dev_info_get,
672         .dev_status_get = hw_dev_status_get,
673         .hwcap_get_all = hw_hwcap_get_all,
674         .dev_config_set = hw_dev_config_set,
675         .dev_acquisition_start = hw_dev_acquisition_start,
676         .dev_acquisition_stop = hw_dev_acquisition_stop,
677 };