From d345a1ed6bbef289b27862c3d0eff58d5ab76674 Mon Sep 17 00:00:00 2001 From: Federico Manzan Date: Sun, 10 Mar 2013 07:56:56 +0000 Subject: Samples: fxload improvements and cleanup * fix C++ compilation * use stdint types * allow to specify bus:address as a parameter * allocate a buffer when transferring FX3 image and check for R/W errors --- examples/ezusb.c | 64 +++++++++++++++++++++++++++++++++++---------------- examples/ezusb.h | 9 ++++++++ examples/fxload.c | 57 +++++++++++++++++++++++++++------------------ libusb/version_nano.h | 2 +- 4 files changed, 89 insertions(+), 43 deletions(-) diff --git a/examples/ezusb.c b/examples/ezusb.c index 2ab7188..d80422f 100644 --- a/examples/ezusb.c +++ b/examples/ezusb.c @@ -532,9 +532,9 @@ static int ram_poke(void *context, uint32_t addr, bool external, */ int fx3_load_ram(libusb_device_handle *device, const char *path) { - unsigned int dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength; - unsigned short wSignature; - unsigned int dImageBuf[512 * 1024]; + uint32_t dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength; + uint16_t wSignature; + uint32_t* dImageBuf; unsigned char *bBuf, rBuf[4096]; FILE *image; @@ -545,22 +545,38 @@ int fx3_load_ram(libusb_device_handle *device, const char *path) } else if (verbose) logerror("open firmware image %s for RAM upload\n", path); - fread(&wSignature, 1, 2, image); // read signature bytes - if (wSignature != 0x5943) { // check CY signature byte - logerror("Invalid image"); + if ((fread(&wSignature, sizeof(uint16_t), 1, image) != 1) || + (wSignature != 0x5943)) { // check "CY" signature byte + logerror("invalid image (signature error)"); + return -3; + } + if (fread(&i, 1, 2, image) != 2) { // skip 2 dummy bytes + logerror("could not read image"); return -3; } - fread(&i, 2, 1, image); // skip 2 dummy bytes dCheckSum = 0; while (1) { - fread(&dLength, 4, 1, image); // read dLength - fread(&dAddress, 4, 1, image); // read dAddress + if ((fread(&dLength, sizeof(uint32_t), 1, image) != 1) || // read dLength + (fread(&dAddress, sizeof(uint32_t), 1, image) != 1)) { // read dAddress + logerror("could not read image"); + return -3; + } if (dLength == 0) break; // done + dImageBuf = calloc(dLength, sizeof(uint32_t)); + if (dImageBuf == NULL) { + logerror("could not allocate buffer for image chunk\n"); + return -4; + } + // read sections - fread(dImageBuf, 4, dLength, image); + if (fread(dImageBuf, sizeof(uint32_t), dLength, image) != dLength) { + logerror("could not read image"); + free(dImageBuf); + return -3; + } for (i = 0; i < dLength; i++) dCheckSum += dImageBuf[i]; dLength <<= 2; // convert to Byte length @@ -570,13 +586,18 @@ int fx3_load_ram(libusb_device_handle *device, const char *path) dLen = 4096; // 4K max if (dLen > dLength) dLen = dLength; - ezusb_write(device, "Write firmware", RW_INTERNAL, dAddress, bBuf, dLen); - ezusb_read(device, "Read firmware", RW_INTERNAL, dAddress, rBuf, dLen); + if ((ezusb_write(device, "write firmware", RW_INTERNAL, dAddress, bBuf, dLen) < 0) || + (ezusb_read(device, "read firmware", RW_INTERNAL, dAddress, rBuf, dLen) < 0)) { + logerror("R/W error\n"); + free(dImageBuf); + return -5; + } // Verify data: rBuf with bBuf for (i = 0; i < dLen; i++) { if (rBuf[i] != bBuf[i]) { - logerror("Fail to verify image"); - return -3; + logerror("verify error"); + free(dImageBuf); + return -6; } } @@ -584,19 +605,22 @@ int fx3_load_ram(libusb_device_handle *device, const char *path) bBuf += dLen; dAddress += dLen; } + free(dImageBuf); } // read pre-computed checksum data - fread(&dExpectedCheckSum, 4, 1, image); - if (dCheckSum != dExpectedCheckSum) { - logerror("Fail to boot due to checksum error\n"); - return -4; + if ((fread(&dExpectedCheckSum, sizeof(uint32_t), 1, image) != 1) || + (dCheckSum != dExpectedCheckSum)) { + logerror("checksum error\n"); + return -7; } // transfer execution to Program Entry - ezusb_write(device, "Jump command", RW_INTERNAL, dAddress, NULL, 0); + if (ezusb_write(device, "Jump command", RW_INTERNAL, dAddress, NULL, 0) < 0) { + logerror("failed to send jump command\n"); + return -6; + } - logerror("Done!\n"); return 0; } diff --git a/examples/ezusb.h b/examples/ezusb.h index 2bbe979..c5d9868 100644 --- a/examples/ezusb.h +++ b/examples/ezusb.h @@ -55,6 +55,10 @@ #define IMG_TYPE_MAX 4 #define IMG_TYPE_NAMES { "Intel HEX", "Cypress 8051 IIC", "Cypress 8051 BIX", "Cypress IMG format" } +#ifdef __cplusplus +extern "C" { +#endif + /* * Automatically identified devices (VID, PID, type, designation). * TODO: Could use some validation. Also where's the FX2? @@ -108,4 +112,9 @@ extern int ezusb_load_eeprom(libusb_device_handle *device, /* boolean flag, says whether to write extra messages to stderr */ extern int verbose; + +#ifdef __cplusplus +} +#endif + #endif diff --git a/examples/fxload.c b/examples/fxload.c index 7086fe7..d69eea4 100644 --- a/examples/fxload.c +++ b/examples/fxload.c @@ -3,6 +3,7 @@ * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net) * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net) * Copyright © 2012 Pete Batard (pete@akeo.ie) + * Copyright © 2013 Federico Manzan (f.manzan@gmail.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -20,16 +21,6 @@ * 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, fx3 - * - * -D -- Use this device, instead of $DEVICE - * - * -V -- Print version ID for program - */ #include #include #include @@ -79,24 +70,39 @@ 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 *device_id = NULL; + const char *device_path = 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; + unsigned busnum = 0, devaddr = 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) + while ((opt = getopt(argc, argv, "vV?hd:a:i:I:t:")) != EOF) switch (opt) { - case 'D': + case 'd': device_id = optarg; + if (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 ) { + fputs ("please specify VID & PID as \"vid:pid\", in hexadecimal format\n", stderr); + return -1; + } break; + case 'a': + device_path = optarg; + if (sscanf(device_path, "%u:%u", &busnum, &devaddr) != 2 ) { + fputs ("please specify bus number & device address as \"bus:addr\", in decimal format\n", stderr); + return -1; + } + break; + + case 'i': case 'I': path[FIRMWARE] = optarg; break; @@ -114,6 +120,7 @@ int main(int argc, char*argv[]) break; case '?': + case 'h': default: goto usage; @@ -122,13 +129,13 @@ int main(int argc, char*argv[]) 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, fx3\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); + fprintf(stderr, "\nUsage: fxload [-v] [-V] [-t type] [-d vid:pid] [-a bus:addr] -i firmware\n"); + fprintf(stderr, " -i -- Firmware to upload\n"); + fprintf(stderr, " -t -- Target type: an21, fx, fx2, fx2lp, fx3\n"); + fprintf(stderr, " -d -- Target device, as an USB VID:PID\n"); + fprintf(stderr, " -a -- Target device, as a libusbx bus and address\n"); + fprintf(stderr, " -v -- Increase verbosity\n"); + fprintf(stderr, " -V -- Print program version\n"); return -1; } @@ -155,12 +162,17 @@ usage: libusb_set_debug(NULL, verbose); /* try to pick up missing parameters from known devices */ - if ((type == NULL) || (device_id == NULL)) { + if (device_path || (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++) { + if (device_path) { + if ((libusb_get_bus_number(dev) == busnum) && (libusb_get_device_address(dev) == devaddr)) + break; + continue; + } status = libusb_get_device_descriptor(dev, &desc); if (status >= 0) { if (verbose >= 2) @@ -195,7 +207,7 @@ usage: } if (dev == NULL) { libusb_free_device_list(devs, 1); - logerror("could not find a known device - please specify type and/or vid:pid\n"); + logerror("could not find a known device - please specify type and/or vid:pid or bus:addr\n"); goto usage; } status = libusb_open(dev, &device); @@ -211,6 +223,7 @@ usage: goto err; } } + /* We need to claim the first interface */ status = libusb_claim_interface(device, 0); #if defined(__linux__) diff --git a/libusb/version_nano.h b/libusb/version_nano.h index bd8f428..e652d0e 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 10628 +#define LIBUSB_NANO 10629 -- cgit v1.2.1