]> sigrok.org Git - libsigrok.git/commitdiff
fx2lafw: Implemented firmware upload
authorJoel Holdsworth <redacted>
Sat, 25 Feb 2012 11:58:55 +0000 (11:58 +0000)
committerJoel Holdsworth <redacted>
Mon, 27 Feb 2012 21:58:25 +0000 (21:58 +0000)
hardware/fx2lafw/fx2lafw.c
hardware/fx2lafw/fx2lafw.h

index 36362f8daada1d420329d501103d8c5f9710af46..5522a420aa668863a8c2699dd801a7c68009e1c6 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <inttypes.h>
 #include <glib.h>
 #include <libusb.h>
@@ -78,6 +79,68 @@ static struct sr_samplerates fx2lafw_samplerates = {
 static GSList *dev_insts = NULL;
 static libusb_context *usb_context = NULL;
 
+/**
+ * Check the USB configuration to determine if this is an fx2lafw device.
+ *
+ * @return true if the device's configuration profile match fx2lafw
+ *         configuration, flase otherwise.
+ */
+static bool check_conf_profile(libusb_device *dev)
+{
+       struct libusb_device_descriptor des;
+       struct libusb_config_descriptor *conf_dsc = NULL;
+       const struct libusb_interface_descriptor *intf_dsc;
+       bool ret = false;
+
+       while (!ret) {
+               /* Assume it's not a Saleae Logic unless proven wrong. */
+               ret = 0;
+
+               if (libusb_get_device_descriptor(dev, &des) != 0)
+                       break;
+
+               if (des.bNumConfigurations != 1)
+                       /* Need exactly 1 configuration. */
+                       break;
+
+               if (libusb_get_config_descriptor(dev, 0, &conf_dsc) != 0)
+                       break;
+
+               if (conf_dsc->bNumInterfaces != 1)
+                       /* Need exactly 1 interface. */
+                       break;
+
+               if (conf_dsc->interface[0].num_altsetting != 1)
+                       /* Need just one alternate setting. */
+                       break;
+
+               intf_dsc = &(conf_dsc->interface[0].altsetting[0]);
+               if (intf_dsc->bNumEndpoints != 3)
+                       /* Need exactly 3 end points. */
+                       break;
+
+               if ((intf_dsc->endpoint[0].bEndpointAddress & 0x8f) !=
+                   (1 | LIBUSB_ENDPOINT_OUT))
+                       /* The first endpoint should be 1 (outbound). */
+                       break;
+
+               if ((intf_dsc->endpoint[1].bEndpointAddress & 0x8f) !=
+                   (2 | LIBUSB_ENDPOINT_IN))
+                       /* The second endpoint should be 2 (inbound). */
+                       break;
+
+               /* TODO: Check the debug channel... */
+
+               /* If we made it here, it must be an fx2lafw. */
+               ret = true;
+       }
+
+       if (conf_dsc)
+               libusb_free_config_descriptor(conf_dsc);
+
+       return ret;
+}
+
 static struct fx2lafw_device* fx2lafw_device_new(void)
 {
        struct fx2lafw_device *fx2lafw;
@@ -146,6 +209,24 @@ static int hw_init(const char *deviceinfo)
                sdi->priv = ctx;
                device_instances = g_slist_append(dev_insts, sdi);
 
+               if (check_conf_profile(devlist[i])) {
+                       /* Already has the firmware, so fix the new address. */
+                       sr_dbg("fx2lafw: Found a fx2lafw device.");
+                       sdi->status = SR_ST_INACTIVE;
+                       ctx->usb = sr_usb_dev_inst_new
+                           (libusb_get_bus_number(devlist[i]),
+                            libusb_get_device_address(devlist[i]), NULL);
+               } else {
+                       if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, FIRMWARE) == SR_OK)
+                               /* Remember when the firmware on this device was updated */
+                               g_get_current_time(&ctx->fw_updated);
+                       else
+                               sr_err("fx2lafw: firmware upload failed for "
+                                      "device %d", devcnt);
+                       ctx->usb = sr_usb_dev_inst_new
+                               (libusb_get_bus_number(devlist[i]), 0xff, NULL);
+               }
+
                devcnt++;
        }
        libusb_free_device_list(devlist, 1);
index 49d9311557a2a2a6b53d4bbadcfa0efb95945ef9..88536a83c9b2c986398eca036b97be1ee07a0158 100644 (file)
 #ifndef LIBSIGROK_HARDWARE_FX2LAFW
 #define LIBSIGROK_HARDWARE_FX2LAFW
 
-#define TRIGGER_TYPES       "01rf"
+#define USB_INTERFACE          0
+#define USB_CONFIGURATION      1
+#define TRIGGER_TYPES          "01rf"
+#define FIRMWARE               FIRMWARE_DIR "/fx2lafw-cwav-usbeeax.fw"
 
 struct fx2lafw_profile {
        uint16_t vid;
@@ -36,9 +39,17 @@ struct fx2lafw_profile {
 struct fx2lafw_device {
        struct fx2lafw_profile *profile;
 
+       /*
+        * Since we can't keep track of an fx2lafw device after upgrading
+        * the firmware (it re-enumerates into a different device address
+        * after the upgrade) this is like a global lock. No device will open
+        * until a proper delay after the last device was upgraded.
+        */
+       GTimeVal fw_updated;
+
        void *session_data;
 
-       struct sr_usb_device_instance *usb;
+       struct sr_usb_dev_inst *usb;
 };
 
 #endif