int main(int argc, const char *argv[]) { int retVal = 0; struct USBDevice *device = NULL; const char *error = NULL; const char *vp; USBStatus uStatus; if ( argc != 2 ) { fprintf(stderr, "Synopsis: %s <VID:PID>\n", argv[0]); FAIL(1, cleanup); } vp = argv[1]; uStatus = usbInitialise(0, &error); CHECK_STATUS(uStatus, 2, cleanup); uStatus = usbOpenDevice(vp, 1, 0, 0, &device, &error); CHECK_STATUS(uStatus, 3, cleanup); uStatus = usbPrintConfiguration(device, stdout, &error); CHECK_STATUS(uStatus, 4, cleanup); cleanup: if ( device ) { usbCloseDevice(device, 0); } if ( error ) { fprintf(stderr, "%s: %s\n", argv[0], error); errFree(error); } return retVal; }
// Load custom firmware (.hex) into the FX2's RAM DLLEXPORT(FLStatus) flLoadCustomFirmware( const char *curVidPid, const char *fwFile, const char **error) { FLStatus retVal = FL_SUCCESS; struct Buffer fwBuf = {0,}; BufferStatus bStatus; FX2Status fxStatus; struct USBDevice *device = NULL; USBStatus uStatus; const char *const ext = fwFile + strlen(fwFile) - 4; const bool isHex = (strcmp(".hex", ext) == 0) || (strcmp(".ihx", ext) == 0); CHECK_STATUS( !isHex, FL_FILE_ERR, cleanup, "flLoadCustomFirmware(): Filename should have .hex or .ihx extension"); uStatus = usbOpenDevice(curVidPid, 1, 0, 0, &device, error); CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flLoadCustomFirmware()"); bStatus = bufInitialise(&fwBuf, 8192, 0x00, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "flLoadCustomFirmware()"); bStatus = bufReadFromIntelHexFile(&fwBuf, NULL, fwFile, error); CHECK_STATUS(bStatus, FL_FILE_ERR, cleanup, "flLoadCustomFirmware()"); fxStatus = fx2WriteRAM(device, fwBuf.data, (uint32)fwBuf.length, error); CHECK_STATUS(fxStatus, FL_FX2_ERR, cleanup, "flLoadCustomFirmware()"); cleanup: bufDestroy(&fwBuf); if ( device ) { usbCloseDevice(device, 0); } return retVal; }
// Load the standard FPGALink firmware into the FX2 at currentVid/currentPid. DLLEXPORT(FLStatus) flLoadStandardFirmware( const char *curVidPid, const char *newVidPid, const char **error) { FLStatus flStatus, retVal = FL_SUCCESS; struct Buffer ramBuf = {0,}; BufferStatus bStatus; FX2Status fxStatus; struct USBDevice *device = NULL; USBStatus uStatus; uint16 newVid, newPid, newDid; CHECK_STATUS( !usbValidateVidPid(newVidPid), FL_USB_ERR, cleanup, "flLoadStandardFirmware(): The supplied VID:PID:DID \"%s\" is invalid; it should look like 1D50:602B or 1D50:602B:0001", newVidPid); newVid = (uint16)strtoul(newVidPid, NULL, 16); newPid = (uint16)strtoul(newVidPid+5, NULL, 16); newDid = (uint16)((strlen(newVidPid) == 14) ? strtoul(newVidPid+10, NULL, 16) : 0x0000); uStatus = usbOpenDevice(curVidPid, 1, 0, 0, &device, error); CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flLoadStandardFirmware()"); bStatus = bufInitialise(&ramBuf, 0x4000, 0x00, error); CHECK_STATUS(bStatus, FL_ALLOC_ERR, cleanup, "flLoadStandardFirmware()"); flStatus = copyFirmwareAndRewriteIDs( &ramFirmware, newVid, newPid, newDid, &ramBuf, error); CHECK_STATUS(flStatus, flStatus, cleanup, "flLoadStandardFirmware()"); fxStatus = fx2WriteRAM(device, ramBuf.data, (uint32)ramBuf.length, error); CHECK_STATUS(fxStatus, FL_FX2_ERR, cleanup, "flLoadStandardFirmware()"); cleanup: bufDestroy(&ramBuf); if ( device ) { usbCloseDevice(device, 0); } return retVal; }
// Disconnect and cleanup, if necessary. // DLLEXPORT(void) flClose(struct FLContext *handle) { if ( handle ) { usbCloseDevice(handle->device, 0); if ( handle->writeBuffer.data ) { bufDestroy(&handle->writeBuffer); } free((void*)handle); } }
// Open a connection, get device status & sanity-check it. // DLLEXPORT(FLStatus) flOpen(const char *vp, struct FLContext **handle, const char **error) { FLStatus retVal = FL_SUCCESS, fStatus; USBStatus uStatus; uint8 statusBuffer[16]; struct FLContext *newCxt = (struct FLContext *)calloc(sizeof(struct FLContext), 1); uint8 progEndpoints, commEndpoints; CHECK_STATUS(!newCxt, FL_ALLOC_ERR, cleanup, "flOpen()"); uStatus = usbOpenDevice(vp, 1, 0, 0, &newCxt->device, error); CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flOpen()"); fStatus = getStatus(newCxt, statusBuffer, error); CHECK_STATUS(fStatus, fStatus, cleanup, "flOpen()"); CHECK_STATUS( statusBuffer[0] != 'N' || statusBuffer[1] != 'E' || statusBuffer[2] != 'M' || statusBuffer[3] != 'I', FL_PROTOCOL_ERR, cleanup, "flOpen(): Device at %s not recognised", vp); CHECK_STATUS( !statusBuffer[6] && !statusBuffer[7], FL_PROTOCOL_ERR, cleanup, "flOpen(): Device at %s supports neither NeroProg nor CommFPGA", vp); progEndpoints = statusBuffer[6]; commEndpoints = statusBuffer[7]; if ( progEndpoints ) { newCxt->isNeroCapable = true; newCxt->progOutEP = (progEndpoints >> 4); newCxt->progInEP = (progEndpoints & 0x0F); } if ( commEndpoints ) { newCxt->isCommCapable = true; newCxt->commOutEP = (commEndpoints >> 4); newCxt->commInEP = (commEndpoints & 0x0F); } newCxt->firmwareID = (uint16)( (statusBuffer[8] << 8) | statusBuffer[9] ); newCxt->firmwareVersion = (uint32)( (statusBuffer[10] << 24) | (statusBuffer[11] << 16) | (statusBuffer[12] << 8) | statusBuffer[13] ); newCxt->chunkSize = 0x10000; // default maximum libusbwrap chunk size *handle = newCxt; return retVal; cleanup: if ( newCxt ) { if ( newCxt->device ) { usbCloseDevice(newCxt->device, 0); } free((void*)newCxt); } *handle = NULL; return retVal; }
// Disconnect and cleanup, if necessary. // DLLEXPORT(void) flClose(struct FLContext *handle) { if ( handle ) { USBStatus uStatus; struct CompletionReport completionReport; FLStatus fStatus = flFlushAsyncWrites(handle, NULL); size_t queueDepth = usbNumOutstandingRequests(handle->device); while ( queueDepth-- ) { uStatus = usbBulkAwaitCompletion(handle->device, &completionReport, NULL); } usbCloseDevice(handle->device, 0); free((void*)handle); (void)fStatus; (void)uStatus; } }
static int uploadData(char *dataBuffer) { usbDevice_t *dev = NULL; int err = 0, len, mask, pageSize, deviceSize, i; union{ char bytes[1]; deviceInfo_t info; deviceData_t data; } buffer; if((err = usbOpenDevice(&dev, IDENT_VENDOR_NUM, IDENT_VENDOR_STRING, IDENT_PRODUCT_NUM, IDENT_PRODUCT_STRING, 1)) != 0){ fprintf(stderr, "Error opening HIDBoot device: %s\n", usbErrorMessage(err)); goto errorOccurred; } len = sizeof(buffer); if(endAddress[addressIndex] > startAddress[0]){ // we need to upload data if((err = usbGetReport(dev, USB_HID_REPORT_TYPE_FEATURE, 1, buffer.bytes, &len)) != 0){ fprintf(stderr, "Error reading page size: %s\n", usbErrorMessage(err)); goto errorOccurred; } if(len < sizeof(buffer.info)){ fprintf(stderr, "Not enough bytes in device info report (%d instead of %d)\n", len, (int)sizeof(buffer.info)); err = -1; goto errorOccurred; } pageSize = getUsbInt(buffer.info.pageSize, 2); deviceSize = getUsbInt(buffer.info.flashSize, 4); printf("Page size = %d (0x%x)\n", pageSize, pageSize); printf("Device size = %d (0x%x); %d bytes remaining\n", deviceSize, deviceSize, deviceSize - 2048); if(endAddress[addressIndex] > deviceSize - 2048){ fprintf(stderr, "Data (%d bytes) exceeds remaining flash size!\n", endAddress[addressIndex]); err = -1; goto errorOccurred; } if(pageSize < 128){ mask = 127; }else{ mask = pageSize - 1; } for (i = 0; i <= addressIndex; i++) { startAddress[i] &= ~mask; /* round down */ endAddress[i] = (endAddress[i] + mask) & ~mask; /* round up */ printf("Uploading %d (0x%x) bytes starting at %d (0x%x)\n", endAddress[i] - startAddress[i], endAddress[i] - startAddress[i], startAddress[i], startAddress[i]); while(startAddress[i] < endAddress[i]){ buffer.data.reportId = 2; memcpy(buffer.data.data, dataBuffer + startAddress[i], 128); setUsbInt(buffer.data.address, startAddress[i], 3); printf("\r0x%05x ... 0x%05x", startAddress[i], startAddress[i] + (int)sizeof(buffer.data.data)); fflush(stdout); if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.data))) != 0){ //fprintf(stderr, "Error uploading data block: %s\n", usbErrorMessage(err)); continue; goto errorOccurred; } startAddress[i] += sizeof(buffer.data.data); } printf("\n"); } } if(leaveBootLoader){ /* and now leave boot loader: */ buffer.info.reportId = 1; usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer.bytes, sizeof(buffer.info)); /* Ignore errors here. If the device reboots before we poll the response, * this request fails. */ } errorOccurred: if(dev != NULL) usbCloseDevice(dev); return err; }
static void avrdoper_close(union filedescriptor *fdp) { usbCloseDevice(fdp); }
// Load the standard FPGALink firmware into the FX2 at currentVid/currentPid. DLLEXPORT(FLStatus) flLoadStandardFirmware( const char *curVidPid, const char *newVidPid, const char *jtagPort, const char **error) { FLStatus flStatus, returnCode; struct Buffer ramBuf = {0,}; BufferStatus bStatus; FX2Status fxStatus; struct USBDevice *device = NULL; int uStatus; uint16 newVid, newPid, newDid; uint8 port, tdoBit, tdiBit, tmsBit, tckBit; if ( !usbValidateVidPid(newVidPid) ) { errRender(error, "flLoadStandardFirmware(): The supplied VID:PID:DID \"%s\" is invalid; it should look like 1D50:602B or 1D50:602B:0001", newVidPid); FAIL(FL_USB_ERR); } newVid = (uint16)strtoul(newVidPid, NULL, 16); newPid = (uint16)strtoul(newVidPid+5, NULL, 16); newDid = (strlen(newVidPid) == 14) ? (uint16)strtoul(newVidPid+10, NULL, 16) : 0x0000; if ( strlen(jtagPort) != 5 ) { errRender(error, "flLoadStandardFirmware(): JTAG port specification must be <C|D><tdoBit><tdiBit><tmsBit><tckBit>"); FAIL(FL_FX2_ERR); } if ( (jtagPort[0] & 0xDF) == 'A' ) { port = 0; } else if ( (jtagPort[0] & 0xDF) == 'C' ) { port = 2; } else if ( (jtagPort[0] & 0xDF) == 'D' ) { port = 3; } else { errRender(error, "flLoadStandardFirmware(): JTAG port specification must be <A|C|D><tdoBit><tdiBit><tmsBit><tckBit>"); FAIL(FL_FX2_ERR); } if (jtagPort[1] < '0' || jtagPort[1] > '7' || jtagPort[2] < '0' || jtagPort[2] > '7' || jtagPort[3] < '0' || jtagPort[3] > '7' || jtagPort[4] < '0' || jtagPort[4] > '7' ) { errRender(error, "flLoadStandardFirmware(): JTAG port specification must be <A|C|D><tdoBit><tdiBit><tmsBit><tckBit>"); FAIL(FL_FX2_ERR); } tdoBit = jtagPort[1] - '0'; tdiBit = jtagPort[2] - '0'; tmsBit = jtagPort[3] - '0'; tckBit = jtagPort[4] - '0'; if ( port == 0 && (isInvalidPortABit(tdoBit) || isInvalidPortABit(tdiBit) || isInvalidPortABit(tmsBit) || isInvalidPortABit(tckBit)) ) { errRender(error, "flFlashStandardFirmware(): Only bits 0, 1, 3 & 7 are available for JTAG use on port A"); FAIL(FL_FX2_ERR); } uStatus = usbOpenDevice(curVidPid, 1, 0, 0, &device, error); CHECK_STATUS(uStatus, "flLoadStandardFirmware()", FL_USB_ERR); bStatus = bufInitialise(&ramBuf, 0x4000, 0x00, error); CHECK_STATUS(bStatus, "flLoadStandardFirmware()", FL_ALLOC_ERR); flStatus = copyFirmwareAndRewriteIDs( &ramFirmware, newVid, newPid, newDid, port, tdoBit, tdiBit, tmsBit, tckBit, &ramBuf, error); CHECK_STATUS(flStatus, "flLoadStandardFirmware()", flStatus); fxStatus = fx2WriteRAM(device, ramBuf.data, ramBuf.length, error); CHECK_STATUS(fxStatus, "flLoadStandardFirmware()", FL_FX2_ERR); returnCode = FL_SUCCESS; cleanup: bufDestroy(&ramBuf); if ( device ) { usbCloseDevice(device, 0); } return returnCode; }
int bufferRead(void) { int retVal = 0; USBStatus uStatus; struct USBDevice *deviceHandle = NULL; const char *error = NULL; uint8 *ptr; const uint8 *buf; struct CompletionReport completionReport; // Init library uStatus = usbInitialise(0, &error); CHECK_STATUS(uStatus, 1, cleanup); // Open device uStatus = usbOpenDevice("1d50:602b", 1, 0, 0, &deviceHandle, &error); CHECK_STATUS(uStatus, 2, cleanup); // Select CommFPGA conduit (FX2 slave FIFOs = 0x0001) uStatus = usbControlWrite(deviceHandle, 0x80, 0x0000, 0x0001, NULL, 0, 1000, &error); CHECK_STATUS(uStatus, 3, cleanup); // Get the next available 64KiB write buffer uStatus = usbBulkWriteAsyncPrepare(deviceHandle, &ptr, &error); // Write request command CHECK_STATUS(uStatus, 4, cleanup); buf = ptr; // Populate the buffer with a couple of FPGA write commands and one FPGA read command *ptr++ = 0x00; // write ch0 *ptr++ = (uint8)(CHUNK_SIZE >> 24); *ptr++ = (uint8)(CHUNK_SIZE >> 16); *ptr++ = (uint8)(CHUNK_SIZE >> 8); *ptr++ = (uint8)(CHUNK_SIZE & 0xFF); memcpy(ptr, randomData, CHUNK_SIZE); ptr += CHUNK_SIZE; *ptr++ = 0x00; // write ch0 *ptr++ = (uint8)(CHUNK_SIZE >> 24); *ptr++ = (uint8)(CHUNK_SIZE >> 16); *ptr++ = (uint8)(CHUNK_SIZE >> 8); *ptr++ = (uint8)(CHUNK_SIZE & 0xFF); memcpy(ptr, randomData+CHUNK_SIZE, CHUNK_SIZE); ptr += CHUNK_SIZE; *ptr++ = 0x80; // read ch0 *ptr++ = (uint8)(CHUNK_SIZE >> 24); *ptr++ = (uint8)(CHUNK_SIZE >> 16); *ptr++ = (uint8)(CHUNK_SIZE >> 8); *ptr++ = (uint8)(CHUNK_SIZE & 0xFF); // Submit the write uStatus = usbBulkWriteAsyncSubmit(deviceHandle, 2, (uint32)(ptr-buf), 1000, &error); CHECK_STATUS(uStatus, 5, cleanup); // Submit the read uStatus = usbBulkReadAsync(deviceHandle, 6, NULL, CHUNK_SIZE, 9000, &error); // Read response data CHECK_STATUS(uStatus, 6, cleanup); // Wait for them to be serviced uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 7, cleanup); printCompletionReport(&completionReport); uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 8, cleanup); printCompletionReport(&completionReport); cleanup: usbCloseDevice(deviceHandle, 0); if ( error ) { fprintf(stderr, "%s\n", error); usbFreeError(error); } return retVal; }
int multiRead(uint32 reqCount, uint32 reqSize, double *speed) { int retVal = 0; USBStatus uStatus; struct USBDevice *deviceHandle = NULL; const char *error = NULL; uint8 buf[5]; struct CompletionReport completionReport; uint32 numBytes; double totalTime; #ifdef WIN32 LARGE_INTEGER tvStart, tvEnd, freq; DWORD_PTR mask = 1; SetThreadAffinityMask(GetCurrentThread(), mask); QueryPerformanceFrequency(&freq); #else struct timeval tvStart, tvEnd; long long startTime, endTime; #endif // We can make one FPGA request message and re-use it buf[0] = 0x80; // write ch0 buf[1] = (uint8)(reqSize >> 24); buf[2] = (uint8)(reqSize >> 16); buf[3] = (uint8)(reqSize >> 8); buf[4] = (uint8)(reqSize & 0xFF); // Init library uStatus = usbInitialise(0, &error); CHECK_STATUS(uStatus, 1, cleanup); // Open device uStatus = usbOpenDevice("1d50:602b", 1, 0, 0, &deviceHandle, &error); CHECK_STATUS(uStatus, 2, cleanup); // Select CommFPGA conduit (FX2 slave FIFOs = 0x0001) uStatus = usbControlWrite(deviceHandle, 0x80, 0x0000, 0x0001, NULL, 0, 1000, &error); CHECK_STATUS(uStatus, 3, cleanup); // Record start time #ifdef WIN32 QueryPerformanceCounter(&tvStart); #else gettimeofday(&tvStart, NULL); #endif // Send a couple of read commands to the FPGA uStatus = usbBulkWriteAsync(deviceHandle, 2, buf, 5, 9000, &error); // Write request command CHECK_STATUS(uStatus, 4, cleanup); uStatus = usbBulkReadAsync(deviceHandle, 6, NULL, reqSize, 9000, &error); // Read response data CHECK_STATUS(uStatus, 5, cleanup); uStatus = usbBulkWriteAsync(deviceHandle, 2, buf, 5, 9000, &error); // Write request command CHECK_STATUS(uStatus, 6, cleanup); uStatus = usbBulkReadAsync(deviceHandle, 6, NULL, reqSize, 9000, &error); // Read response data CHECK_STATUS(uStatus, 7, cleanup); // On each iteration, await completion and send a new read command numBytes = (reqCount+2)*reqSize; while ( reqCount-- ) { uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 8, cleanup); printCompletionReport(&completionReport); uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 9, cleanup); printCompletionReport(&completionReport); uStatus = usbBulkWriteAsync(deviceHandle, 2, buf, 5, 9000, &error); // Write request command CHECK_STATUS(uStatus, 10, cleanup); uStatus = usbBulkReadAsync(deviceHandle, 6, NULL, reqSize, 9000, &error); // Read response data CHECK_STATUS(uStatus, 11, cleanup); } // Wait for the stragglers... uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 12, cleanup); printCompletionReport(&completionReport); uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 13, cleanup); printCompletionReport(&completionReport); uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 14, cleanup); printCompletionReport(&completionReport); uStatus = usbBulkAwaitCompletion(deviceHandle, &completionReport, &error); CHECK_STATUS(uStatus, 15, cleanup); printCompletionReport(&completionReport); // Record stop time #ifdef WIN32 QueryPerformanceCounter(&tvEnd); totalTime = (double)(tvEnd.QuadPart - tvStart.QuadPart); totalTime /= freq.QuadPart; *speed = (double)numBytes / (1024*1024*totalTime); #else gettimeofday(&tvEnd, NULL); startTime = tvStart.tv_sec; startTime *= 1000000; startTime += tvStart.tv_usec; endTime = tvEnd.tv_sec; endTime *= 1000000; endTime += tvEnd.tv_usec; totalTime = (double)(endTime - startTime); totalTime /= 1000000; // convert from uS to S. *speed = (double)numBytes / (1024*1024*totalTime); #endif cleanup: usbCloseDevice(deviceHandle, 0); if ( error ) { fprintf(stderr, "%s\n", error); usbFreeError(error); } return retVal; }
int main(int argc, char *argv[]) { struct arg_str *vpOpt = arg_str1("v", "vidpid", "<VID:PID>", " vendor ID and product ID (e.g 04B4:8613)"); struct arg_uint *toOpt = arg_uint0("t", "timeout", "<millis>", " timeout in milliseconds"); struct arg_int *epOpt = arg_int0("e", "endpoint", "<epNum>", " endpoint to write to"); struct arg_lit *benOpt = arg_lit0("b", "benchmark", " benchmark the operation"); struct arg_lit *chkOpt = arg_lit0("c", "checksum", " print 16-bit checksum"); struct arg_lit *helpOpt = arg_lit0("h", "help", " print this help and exit\n"); struct arg_file *fileOpt = arg_file1(NULL, NULL, "<fileName>", " the data to send"); struct arg_end *endOpt = arg_end(20); void* argTable[] = {vpOpt, toOpt, epOpt, benOpt, chkOpt, helpOpt, fileOpt, endOpt}; const char *progName = "bulk"; int numErrors; uint8 epNum = 0x06; FILE *inFile = NULL; uint8 *buffer = NULL; uint32 fileLen; struct USBDevice *deviceHandle = NULL; USBStatus uStatus; int retVal = 0; const char *error = NULL; double totalTime, speed; uint16 checksum = 0x0000; uint32 timeout = 5000; uint32 i; #ifdef WIN32 LARGE_INTEGER tvStart, tvEnd, freq; DWORD_PTR mask = 1; SetThreadAffinityMask(GetCurrentThread(), mask); QueryPerformanceFrequency(&freq); #else struct timeval tvStart, tvEnd; long long startTime, endTime; #endif if ( arg_nullcheck(argTable) != 0 ) { printf("%s: insufficient memory\n", progName); FAIL(1, cleanup); } numErrors = arg_parse(argc, argv, argTable); if ( helpOpt->count > 0 ) { printf("Bulk Write Tool Copyright (C) 2009-2011 Chris McClelland\n\nUsage: %s", progName); arg_print_syntax(stdout, argTable, "\n"); printf("\nWrite data to a bulk endpoint.\n\n"); arg_print_glossary(stdout, argTable," %-10s %s\n"); FAIL(0, cleanup); } if ( numErrors > 0 ) { arg_print_errors(stdout, endOpt, progName); printf("Try '%s --help' for more information.\n", progName); FAIL(2, cleanup); } if ( toOpt->count ) { timeout = toOpt->ival[0]; } inFile = fopen(fileOpt->filename[0], "rb"); if ( !inFile ) { fprintf(stderr, "Unable to open file %s\n", fileOpt->filename[0]); FAIL(3, cleanup); } fseek(inFile, 0, SEEK_END); fileLen = (uint32)ftell(inFile); fseek(inFile, 0, SEEK_SET); buffer = (uint8 *)malloc(fileLen); if ( !buffer ) { fprintf(stderr, "Unable to allocate memory for file %s\n", fileOpt->filename[0]); FAIL(4, cleanup); } if ( fread(buffer, 1, fileLen, inFile) != fileLen ) { fprintf(stderr, "Unable to read file %s\n", fileOpt->filename[0]); FAIL(5, cleanup); } if ( chkOpt->count ) { for ( i = 0; i < fileLen; i++ ) { checksum = (uint16)(checksum + buffer[i]); } printf("Checksum: 0x%04X\n", checksum); } if ( epOpt->count ) { epNum = (uint8)epOpt->ival[0]; } uStatus = usbInitialise(0, &error); CHECK_STATUS(uStatus, 6, cleanup); uStatus = usbOpenDevice(vpOpt->sval[0], 1, 0, 0, &deviceHandle, &error); CHECK_STATUS(uStatus, 7, cleanup); #ifdef WIN32 QueryPerformanceCounter(&tvStart); uStatus = usbBulkWrite(deviceHandle, epNum, buffer, fileLen, timeout, &error); QueryPerformanceCounter(&tvEnd); CHECK_STATUS(uStatus, 8, cleanup); totalTime = (double)(tvEnd.QuadPart - tvStart.QuadPart); totalTime /= freq.QuadPart; printf("Time: %fms\n", totalTime/1000.0); speed = (double)fileLen / (1024*1024*totalTime); #else gettimeofday(&tvStart, NULL); uStatus = usbBulkWrite(deviceHandle, epNum, buffer, fileLen, timeout, &error); gettimeofday(&tvEnd, NULL); CHECK_STATUS(uStatus, 8, cleanup); startTime = tvStart.tv_sec; startTime *= 1000000; startTime += tvStart.tv_usec; endTime = tvEnd.tv_sec; endTime *= 1000000; endTime += tvEnd.tv_usec; totalTime = (double)(endTime - startTime); totalTime /= 1000000; // convert from uS to S. speed = (double)fileLen / (1024*1024*totalTime); #endif if ( benOpt->count ) { printf("Speed: %f MB/s\n", speed); } cleanup: if ( buffer ) { free(buffer); } if ( inFile ) { fclose(inFile); } if ( deviceHandle ) { usbCloseDevice(deviceHandle, 0); } if ( error ) { fprintf(stderr, "%s\n", error); usbFreeError(error); } arg_freetable(argTable, sizeof(argTable)/sizeof(argTable[0])); return retVal; }