fx2lafw: Implemented firmware upload

This commit is contained in:
Joel Holdsworth 2012-02-25 11:58:55 +00:00
parent cdfdd71101
commit b1eeb67e92
2 changed files with 94 additions and 2 deletions

View 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);

View File

@ -20,7 +20,10 @@
#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