static int ram_poke ( void *context, unsigned short addr, int external, const unsigned char *data, size_t len ) { struct ram_poke_context *ctx = context; int rc; unsigned retry = 0; switch (ctx->mode) { case internal_only: /* CPU should be stopped */ if (external) { fprintf (stderr, "can't write %d bytes external memory at 0x%04x\n", len, addr); return -EINVAL; } break; case skip_internal: /* CPU must be running */ if (!external) { if (verbose >= 2) { fprintf (stderr, "SKIP on-chip RAM, %d bytes at 0x%04x\n", len, addr); } return 0; } break; case skip_external: /* CPU should be stopped */ if (external) { if (verbose >= 2) { fprintf (stderr, "SKIP external RAM, %d bytes at 0x%04x\n", len, addr); } return 0; } break; default: fprintf (stderr, "bug\n"); return -EDOM; } ctx->total += len; ctx->count++; /* Retry this till we get a real error. Control messages are not * NAKed (just dropped) so time out means is a real problem. */ while ((rc = ezusb_write (ctx->device, external ? "write external" : "write on-chip", external ? RW_MEMORY : RW_INTERNAL, addr, data, len)) < 0 && retry < RETRY_LIMIT) { if (errno != ETIMEDOUT) break; retry += 1; } return (rc < 0) ? -errno : 0; }
static int ram_poke(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len) { struct ram_poke_context *ctx = (struct ram_poke_context*)context; int rc; unsigned retry = 0; switch (ctx->mode) { case internal_only: /* CPU should be stopped */ if (external) { logerror("can't write %u bytes external memory at 0x%08x\n", (unsigned)len, addr); return -EINVAL; } break; case skip_internal: /* CPU must be running */ if (!external) { if (verbose >= 2) { logerror("SKIP on-chip RAM, %u bytes at 0x%08x\n", (unsigned)len, addr); } return 0; } break; case skip_external: /* CPU should be stopped */ if (external) { if (verbose >= 2) { logerror("SKIP external RAM, %u bytes at 0x%08x\n", (unsigned)len, addr); } return 0; } break; case _undef: default: logerror("bug\n"); return -EDOM; } ctx->total += len; ctx->count++; /* Retry this till we get a real error. Control messages are not * NAKed (just dropped) so time out means is a real problem. */ while ((rc = ezusb_write(ctx->device, external ? "write external" : "write on-chip", external ? RW_MEMORY : RW_INTERNAL, addr, data, len)) < 0 && retry < RETRY_LIMIT) { if (rc != LIBUSB_ERROR_TIMEOUT) break; retry += 1; } return rc; }
static int ezusb_poke(usb_dev_handle * dev, unsigned short addr, const unsigned char *data, size_t len) { int ret, retry = 0; /* Control messages aren't NAKd, they are just dropped, so retry */ while ((ret = ezusb_write(dev, addr, data, len)) < 0 && retry < 5) { if (ret != -1) break; retry++; } return ret; }
/* * 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; }
/* Write to the CPUCS register to stop or reset the CPU */ static int ezusb_cpucs(usb_dev_handle * dev, int run) { unsigned char data = !run; return ezusb_write(dev, CPUCS_ADDR, &data, 1); }