/* * Copyright © 2001 Stephen Williams (steve@icarus.com) * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net) * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net) * Copyright © 2012 Pete Batard (pete@akeo.ie) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This program supports uploading firmware into a target USB device. * * -I -- Upload this firmware * -t -- uController type: an21, fx, fx2, fx2lp * * -D -- Use this device, instead of $DEVICE * * -V -- Print version ID for program */ #include #include #include #include #include #include #include #include #include "ezusb.h" #if !defined(_WIN32) || defined(__CYGWIN__ ) #include static bool dosyslog = false; #include #define _stricmp strcasecmp #endif #ifndef FXLOAD_VERSION #define FXLOAD_VERSION (__DATE__ " (development)") #endif #ifndef ARRAYSIZE #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) #endif void logerror(const char *format, ...) __attribute__ ((format (__printf__, 1, 2))); void logerror(const char *format, ...) { va_list ap; va_start(ap, format); #if !defined(_WIN32) || defined(__CYGWIN__ ) if (dosyslog) vsyslog(LOG_ERR, format, ap); else #endif vfprintf(stderr, format, ap); va_end(ap); } #define FIRMWARE 0 #define LOADER 1 int main(int argc, char*argv[]) { fx_known_device known_device[] = FX_KNOWN_DEVICES; const char *path[] = { NULL, NULL }; const char *device_id = getenv("DEVICE"); const char *type = NULL; const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES; const char *ext, *img_name[] = IMG_TYPE_NAMES; int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)]; int i, j, opt, status; unsigned vid = 0, pid = 0; libusb_device *dev, **devs; libusb_device_handle *device = NULL; struct libusb_device_descriptor desc; while ((opt = getopt(argc, argv, "vV?D:I:c:s:t:")) != EOF) switch (opt) { case 'D': device_id = optarg; break; case 'I': path[FIRMWARE] = optarg; break; case 'V': puts(FXLOAD_VERSION); return 0; case 't': type = optarg; break; case 'v': verbose++; break; case '?': default: goto usage; } if (path[FIRMWARE] == NULL) { logerror("no firmware specified!\n"); usage: fprintf(stderr, "\nusage: %s [-vV] [-t type] [-D vid:pid] -I firmware\n", argv[0]); fprintf(stderr, " type: one of an21, fx, fx2, fx2lp\n"); return -1; } if ((device_id != NULL) && (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 )) { fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr); return -1; } /* determine the target type */ if (type != NULL) { for (i=0; i= FX_TYPE_MAX) { logerror("illegal microcontroller type: %s\n", type); goto usage; } } /* open the device using libusbx */ status = libusb_init(NULL); if (status < 0) { logerror("libusb_init() failed: %s\n", libusb_error_name(status)); return -1; } libusb_set_debug(NULL, verbose); /* try to pick up missing parameters from known devices */ if ((type == NULL) || (device_id == NULL)) { if (libusb_get_device_list(NULL, &devs) < 0) { logerror("libusb_get_device_list() failed: %s\n", libusb_error_name(status)); goto err; } for (i=0; (dev=devs[i]) != NULL; i++) { status = libusb_get_device_descriptor(dev, &desc); if (status >= 0) { if (verbose >= 2) logerror("trying to match against %04x:%04x\n", desc.idVendor, desc.idProduct); for (j=0; j