/* * Returns the size of the EEPROM (assuming one is present). * *data == 0 means it uses 8 bit addresses (or there is no EEPROM), * *data == 1 means it uses 16 bit addresses */ static inline int ezusb_get_eeprom_type (int fd, unsigned char *data) { return ezusb_read (fd, "get EEPROM size", GET_EEPROM_SIZE, 0, data, 1); }
/* * 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], blBuf[4], rBuf[4096]; FILE *image; image = fopen(path, "rb"); if (image == NULL) { logerror("unable to open '%s' for input\n", path); return -2; } else if (verbose) logerror("open firmware image %s for RAM upload\n", path); // Read header if (fread(hBuf, sizeof(char), sizeof(hBuf), image) != sizeof(hBuf)) { logerror("could not read image header"); return -3; } // check "CY" signature byte and format if ((hBuf[0] != 'C') || (hBuf[1] != 'Y')) { logerror("image doesn't have a CYpress signature\n"); return -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 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 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 bBuf = (unsigned char*) dImageBuf; while (dLength > 0) { dLen = 4096; // 4K max if (dLen > dLength) dLen = dLength; 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("verify error"); free(dImageBuf); return -6; } } dLength -= dLen; bBuf += dLen; dAddress += dLen; } free(dImageBuf); } // read pre-computed checksum data if ((fread(&dExpectedCheckSum, sizeof(uint32_t), 1, image) != 1) || (dCheckSum != dExpectedCheckSum)) { logerror("checksum error\n"); return -7; } // transfer execution to Program Entry if (!ezusb_fx3_jump(device, dAddress)) { return -6; } return 0; }
/* * Returns the size of the EEPROM (assuming one is present). * *data == 0 means it uses 8 bit addresses (or there is no EEPROM), * *data == 1 means it uses 16 bit addresses */ static inline int ezusb_get_eeprom_type (usb_dev_handle *device, unsigned char *data) { return ezusb_read (device, "get EEPROM size", GET_EEPROM_SIZE, 0, data, 1); }