From 77a37cba5493de44f042095d69aaa200d9ff5fd5 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sun, 14 Apr 2013 22:38:52 +0100 Subject: Samples: Fix timeout error on FX3 and logging improvements for fxload * Add a specific ezusb_fx3_jump() that handles timeout as a non-error This is required as a successful jump call makes the device disconnect from the bus * Set default verbosity to 1 and adjust some messages' verbosity level * Add a new -q option to decrease verbosity * Add readout of the bootloader version for FX3 devices * Filter the image types actually supported for FX3 * Fix the "errcode shadows a global variable" warning on some systems --- examples/ezusb.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--------- examples/ezusb.h | 2 +- examples/fxload.c | 17 ++++++++----- 3 files changed, 73 insertions(+), 18 deletions(-) (limited to 'examples') diff --git a/examples/ezusb.c b/examples/ezusb.c index 5086da1..931a86a 100644 --- a/examples/ezusb.c +++ b/examples/ezusb.c @@ -47,7 +47,7 @@ extern void logerror(const char *format, ...) * The Cypress FX parts are largely compatible with the Anchorhip ones. */ -int verbose; +int verbose = 1; /* * return true if [addr,addr+len] includes external RAM @@ -127,7 +127,7 @@ static int ezusb_write(libusb_device_handle *device, const char *label, { int status; - if (verbose) + if (verbose > 1) logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len); status = libusb_control_transfer(device, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, @@ -150,7 +150,7 @@ static int ezusb_read(libusb_device_handle *device, const char *label, { int status; - if (verbose) + if (verbose > 1) logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len); status = libusb_control_transfer(device, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, @@ -194,6 +194,33 @@ static bool ezusb_cpucs(libusb_device_handle *device, uint32_t addr, bool doRun) return true; } +/* + * Send an FX3 jumpt to address command + * Returns false on error. + */ +static bool ezusb_fx3_jump(libusb_device_handle *device, uint32_t addr) +{ + int status; + + if (verbose) + logerror("transfer execution to Program Entry at 0x%08x\n", addr); + status = libusb_control_transfer(device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + RW_INTERNAL, addr & 0xFFFF, addr >> 16, + NULL, 0, 1000); + /* We may get an I/O error from libusbx as the device disappears */ + if ((status != 0) && (status != LIBUSB_ERROR_IO)) + { + const char *mesg = "failed to send jump command"; + if (status < 0) + logerror("%s: %s\n", mesg, libusb_error_name(status)); + else + logerror("%s\n", mesg); + return false; + } else + return true; +} + /*****************************************************************************/ /* @@ -527,14 +554,14 @@ static int ram_poke(void *context, uint32_t addr, bool external, } /* - * Load an Cypress Image file into target RAM. - * The file is assumed to be in Cypress IMG format. + * Load a Cypress Image file into target RAM. + * See http://www.cypress.com/?docID=41351 (AN76405 PDF) for more info. */ static int fx3_load_ram(libusb_device_handle *device, const char *path) { uint32_t dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength; uint32_t* dImageBuf; - unsigned char *bBuf, hBuf[4], rBuf[4096]; + unsigned char *bBuf, hBuf[4], blBuf[4], rBuf[4096]; FILE *image; image = fopen(path, "rb"); @@ -555,12 +582,36 @@ static int fx3_load_ram(libusb_device_handle *device, const char *path) logerror("image doesn't have a CYpress signature\n"); return -3; } - if (hBuf[3] != 0xB0) { - logerror("invalid file format 0x%02X, expected 0xB0\n", hBuf[3]); + + // Check bImageType + switch(hBuf[3]) { + case 0xB0: + if (verbose) + logerror("normal FW binary %s image with checksum\n", (hBuf[2]&0x01)?"data":"executable"); + break; + case 0xB1: + logerror("security binary image is not currently supported\n"); return -3; + case 0xB2: + logerror("VID:PID image is not currently supported\n"); + return -3; + default: + logerror("invalid image type 0x%02X\n", hBuf[3]); + return -3; + } + + // Read the bootloader version + if (verbose) { + if ((ezusb_read(device, "read bootloader version", RW_INTERNAL, 0xFFFF0020, blBuf, 4) < 0)) { + logerror("Could not read bootloader version\n"); + return -8; + } + logerror("FX3 bootloader version: 0x%02X%02X%02X%02X\n", blBuf[3], blBuf[2], blBuf[1], blBuf[0]); } dCheckSum = 0; + if (verbose) + logerror("writing image...\n"); while (1) { if ((fread(&dLength, sizeof(uint32_t), 1, image) != 1) || // read dLength (fread(&dAddress, sizeof(uint32_t), 1, image) != 1)) { // read dAddress @@ -621,8 +672,7 @@ static int fx3_load_ram(libusb_device_handle *device, const char *path) } // transfer execution to Program Entry - if (ezusb_write(device, "Jump command", RW_INTERNAL, dAddress, NULL, 0) < 0) { - logerror("failed to send jump command\n"); + if (!ezusb_fx3_jump(device, dAddress)) { return -6; } @@ -659,7 +709,7 @@ int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type, if (image == NULL) { logerror("%s: unable to open for input.\n", path); return -2; - } else if (verbose) + } else if (verbose > 1) logerror("open firmware image %s for RAM upload\n", path); if (img_type == IMG_TYPE_IIC) { diff --git a/examples/ezusb.h b/examples/ezusb.h index c5d9868..cd0776d 100644 --- a/examples/ezusb.h +++ b/examples/ezusb.h @@ -110,7 +110,7 @@ extern int ezusb_load_ram(libusb_device_handle *device, extern int ezusb_load_eeprom(libusb_device_handle *device, const char *path, int fx_type, int img_type, int config); -/* boolean flag, says whether to write extra messages to stderr */ +/* Verbosity level (default 1). Can be increased or decreased with options v/q */ extern int verbose; #ifdef __cplusplus diff --git a/examples/fxload.c b/examples/fxload.c index 8537ca2..d8e9941 100644 --- a/examples/fxload.c +++ b/examples/fxload.c @@ -64,15 +64,16 @@ void logerror(const char *format, ...) va_end(ap); } -static int print_usage(int errcode) { +static int print_usage(int error_code) { fprintf(stderr, "\nUsage: fxload [-v] [-V] [-t type] [-d vid:pid] [-p 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, " -p -- Target device, as a libusbx bus number and device address path\n"); fprintf(stderr, " -v -- Increase verbosity\n"); + fprintf(stderr, " -q -- Decrease verbosity (silent mode)\n"); fprintf(stderr, " -V -- Print program version\n"); - return errcode; + return error_code; } #define FIRMWARE 0 @@ -94,7 +95,7 @@ int main(int argc, char*argv[]) libusb_device_handle *device = NULL; struct libusb_device_descriptor desc; - while ((opt = getopt(argc, argv, "vV?hd:p:i:I:t:")) != EOF) + while ((opt = getopt(argc, argv, "qvV?hd:p:i:I:t:")) != EOF) switch (opt) { case 'd': @@ -130,6 +131,10 @@ int main(int argc, char*argv[]) verbose++; break; + case 'q': + verbose--; + break; + case '?': case 'h': default: @@ -184,8 +189,8 @@ int main(int argc, char*argv[]) } else { status = libusb_get_device_descriptor(dev, &desc); if (status >= 0) { - if (verbose >= 2) { - logerror("trying to match against %04x:%04x (%d,%d)\n", + if (verbose >= 3) { + logerror("examining %04x:%04x (%d,%d)\n", desc.idVendor, desc.idProduct, _busnum, _devaddr); } for (j=0; j 1) logerror("single stage: load on-chip memory\n"); status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0); -- cgit v1.2.1