summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorPete Batard <pete@akeo.ie>2013-04-14 22:38:52 +0100
committerPete Batard <pete@akeo.ie>2013-04-14 22:38:52 +0100
commit77a37cba5493de44f042095d69aaa200d9ff5fd5 (patch)
tree82bc41b1fa96c484517b864849394876d30deb87 /examples
parente68c66679293a86da62a2636df54b43bbde1daa4 (diff)
downloadlibusb-77a37cba5493de44f042095d69aaa200d9ff5fd5.tar.gz
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
Diffstat (limited to 'examples')
-rw-r--r--examples/ezusb.c72
-rw-r--r--examples/ezusb.h2
-rw-r--r--examples/fxload.c17
3 files changed, 73 insertions, 18 deletions
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 <path> -- Firmware to upload\n");
fprintf(stderr, " -t <type> -- Target type: an21, fx, fx2, fx2lp, fx3\n");
fprintf(stderr, " -d <vid:pid> -- Target device, as an USB VID:PID\n");
fprintf(stderr, " -p <bus,addr> -- 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<ARRAYSIZE(known_device); j++) {
@@ -274,7 +279,7 @@ int main(int argc, char*argv[])
}
/* single stage, put into internal memory */
- if (verbose)
+ if (verbose > 1)
logerror("single stage: load on-chip memory\n");
status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0);