From: Joel Holdsworth Date: Sun, 26 Feb 2012 12:39:40 +0000 (+0000) Subject: fx2lafw: Implemented hw_dev_open X-Git-Tag: libsigrok-0.1.0~90 X-Git-Url: https://sigrok.org/gitweb/?a=commitdiff_plain;h=43125c69937d1599985c281de956f630c00525d6;p=libsigrok.git fx2lafw: Implemented hw_dev_open --- diff --git a/hardware/fx2lafw/fx2lafw.c b/hardware/fx2lafw/fx2lafw.c index 5522a420..3efcdb43 100644 --- a/hardware/fx2lafw/fx2lafw.c +++ b/hardware/fx2lafw/fx2lafw.c @@ -141,6 +141,78 @@ static bool check_conf_profile(libusb_device *dev) return ret; } +static int fx2lafw_open_dev(int dev_index) +{ + libusb_device **devlist; + struct libusb_device_descriptor des; + struct sr_dev_inst *sdi; + struct fx2lafw_device *ctx; + int err, skip, i; + + if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) + return SR_ERR; + ctx = sdi->priv; + + if (sdi->status == SR_ST_ACTIVE) + /* already in use */ + return SR_ERR; + + skip = 0; + libusb_get_device_list(usb_context, &devlist); + for (i = 0; devlist[i]; i++) { + if ((err = libusb_get_device_descriptor(devlist[i], &des))) { + sr_err("fx2lafw: failed to get device descriptor: %d", err); + continue; + } + + if (des.idVendor != FIRMWARE_VID + || des.idProduct != FIRMWARE_PID) + continue; + + if (sdi->status == SR_ST_INITIALIZING) { + if (skip != dev_index) { + /* Skip devices of this type that aren't the one we want. */ + skip += 1; + continue; + } + } else if (sdi->status == SR_ST_INACTIVE) { + /* + * This device is fully enumerated, so we need to find + * this device by vendor, product, bus and address. + */ + if (libusb_get_bus_number(devlist[i]) != ctx->usb->bus + || libusb_get_device_address(devlist[i]) != ctx->usb->address) + /* this is not the one */ + continue; + } + + if (!(err = libusb_open(devlist[i], &ctx->usb->devhdl))) { + if (ctx->usb->address == 0xff) + /* + * first time we touch this device after firmware upload, + * so we don't know the address yet. + */ + ctx->usb->address = libusb_get_device_address(devlist[i]); + + sdi->status = SR_ST_ACTIVE; + sr_info("fx2lafw: opened device %d on %d.%d interface %d", + sdi->index, ctx->usb->bus, + ctx->usb->address, USB_INTERFACE); + } else { + sr_err("fx2lafw: failed to open device: %d", err); + } + + /* if we made it here, we handled the device one way or another */ + break; + } + libusb_free_device_list(devlist, 1); + + if (sdi->status != SR_ST_ACTIVE) + return SR_ERR; + + return SR_OK; +} + static struct fx2lafw_device* fx2lafw_device_new(void) { struct fx2lafw_device *fx2lafw; @@ -236,7 +308,49 @@ static int hw_init(const char *deviceinfo) static int hw_dev_open(int device_index) { - (void)device_index; + GTimeVal cur_time; + struct sr_dev_inst *sdi; + struct fx2lafw_device *ctx; + int timediff, err; + + if (!(sdi = sr_dev_inst_get(dev_insts, device_index))) + return SR_ERR; + ctx = sdi->priv; + + /* + * if the firmware was recently uploaded, wait up to MAX_RENUM_DELAY ms + * for the FX2 to renumerate + */ + err = 0; + if (GTV_TO_MSEC(ctx->fw_updated) > 0) { + sr_info("fx2lafw: waiting for device to reset"); + /* takes at least 300ms for the FX2 to be gone from the USB bus */ + g_usleep(300 * 1000); + timediff = 0; + while (timediff < MAX_RENUM_DELAY) { + if ((err = fx2lafw_open_dev(device_index)) == SR_OK) + break; + g_usleep(100 * 1000); + g_get_current_time(&cur_time); + timediff = GTV_TO_MSEC(cur_time) - GTV_TO_MSEC(ctx->fw_updated); + } + sr_info("fx2lafw: device came back after %d ms", timediff); + } else { + err = fx2lafw_open_dev(device_index); + } + + if (err != SR_OK) { + sr_err("fx2lafw: unable to open device"); + return SR_ERR; + } + ctx = sdi->priv; + + err = libusb_claim_interface(ctx->usb->devhdl, USB_INTERFACE); + if (err != 0) { + sr_err("fx2lafw: Unable to claim interface: %d", err); + return SR_ERR; + } + return SR_OK; } diff --git a/hardware/fx2lafw/fx2lafw.h b/hardware/fx2lafw/fx2lafw.h index 88536a83..690c6dee 100644 --- a/hardware/fx2lafw/fx2lafw.h +++ b/hardware/fx2lafw/fx2lafw.h @@ -25,6 +25,11 @@ #define TRIGGER_TYPES "01rf" #define FIRMWARE FIRMWARE_DIR "/fx2lafw-cwav-usbeeax.fw" +#define FIRMWARE_VID 0x0925 +#define FIRMWARE_PID 0x3881 + +#define MAX_RENUM_DELAY 3000 /* ms */ + struct fx2lafw_profile { uint16_t vid; uint16_t pid;