aboutsummaryrefslogtreecommitdiffstats
path: root/examples/ezusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ezusb.c')
-rw-r--r--examples/ezusb.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/examples/ezusb.c b/examples/ezusb.c
index 13404ee..2ab7188 100644
--- a/examples/ezusb.c
+++ b/examples/ezusb.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
@@ -142,6 +143,29 @@ static int ezusb_write(libusb_device_handle *device, const char *label,
}
/*
+ * Issues the specified vendor-specific read request.
+ */
+static int ezusb_read(libusb_device_handle *device, const char *label,
+ uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len)
+{
+ int status;
+
+ if (verbose)
+ 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,
+ opcode, addr & 0xFFFF, addr >> 16,
+ (unsigned char*)data, (uint16_t)len, 1000);
+ if (status != len) {
+ if (status < 0)
+ logerror("%s: %s\n", label, libusb_error_name(status));
+ else
+ logerror("%s ==> %d\n", label, status);
+ }
+ return (status < 0) ? -EIO : 0;
+}
+
+/*
* Modifies the CPUCS register to stop or reset the CPU.
* Returns false on error.
*/
@@ -503,6 +527,80 @@ 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.
+ */
+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];
+ unsigned char *bBuf, rBuf[4096];
+ FILE *image;
+
+ image = fopen(path, "rb");
+ if (image == NULL) {
+ logerror("%s: unable to open for input.\n", path);
+ return -2;
+ } 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");
+ 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 (dLength == 0)
+ break; // done
+
+ // read sections
+ fread(dImageBuf, 4, dLength, image);
+ for (i = 0; i < dLength; i++)
+ dCheckSum += dImageBuf[i];
+ dLength <<= 2; // convert to Byte length
+ bBuf = (unsigned char*) dImageBuf;
+
+ while (dLength > 0) {
+ 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);
+ // Verify data: rBuf with bBuf
+ for (i = 0; i < dLen; i++) {
+ if (rBuf[i] != bBuf[i]) {
+ logerror("Fail to verify image");
+ return -3;
+ }
+ }
+
+ dLength -= dLen;
+ bBuf += dLen;
+ dAddress += dLen;
+ }
+ }
+
+ // read pre-computed checksum data
+ fread(&dExpectedCheckSum, 4, 1, image);
+ if (dCheckSum != dExpectedCheckSum) {
+ logerror("Fail to boot due to checksum error\n");
+ return -4;
+ }
+
+ // transfer execution to Program Entry
+ ezusb_write(device, "Jump command", RW_INTERNAL, dAddress, NULL, 0);
+
+ logerror("Done!\n");
+ return 0;
+}
+
+/*
* Load a firmware file into target RAM. device is the open libusbx
* device, and the path is the name of the source file. Open the file,
* parse the bytes, and write them in one or two phases.
@@ -525,6 +623,9 @@ int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type,
int status;
uint8_t iic_header[8] = { 0 };
+ if (fx_type == FX_TYPE_FX3)
+ return fx3_load_ram(device, path);
+
image = fopen(path, "rb");
if (image == NULL) {
logerror("%s: unable to open for input.\n", path);