コード例 #1
0
// Read bytes asynchronously from the specified channel (1 <= count <= 0x10000).
//
DLLEXPORT(FLStatus) flReadChannelAsyncSubmit(
	struct FLContext *handle, uint8 chan, uint32 count, uint8 *buffer, const char **error)
{
	FLStatus retVal = FL_SUCCESS, fStatus;
	uint8 command[3];
	USBStatus uStatus;
	size_t queueDepth;
	const uint16 count16 = (count == 0x10000) ? 0x0000 : (uint16)count;
	CHECK_STATUS(
		!handle->isCommCapable, FL_PROTOCOL_ERR, cleanup,
		"flReadChannelAsyncSubmit(): This device does not support CommFPGA");
	CHECK_STATUS(
		count == 0, FL_PROTOCOL_ERR, cleanup,
		"flReadChannelAsyncSubmit(): Zero-length reads are illegal!");
	CHECK_STATUS(
		count > 0x10000, FL_PROTOCOL_ERR, cleanup,
		"flReadChannelAsyncSubmit(): Transfer length exceeds 0x10000");

	// Write command
	command[0] = chan | 0x80;
	flWriteWord(count16, command+1);
	fStatus = bufferAppend(handle, command, 3, error);
	CHECK_STATUS(fStatus, fStatus, cleanup, "flReadChannelAsyncSubmit()");

	// Flush outstanding async writes
	fStatus = flFlushAsyncWrites(handle, error);
	CHECK_STATUS(fStatus, fStatus, cleanup, "flReadChannelAsyncSubmit()");

	// Maybe do a few awaits, to keep things balanced
	queueDepth = usbNumOutstandingRequests(handle->device);
	while ( queueDepth > 2 && !handle->completionReport.flags.isRead ) {
		uStatus = usbBulkAwaitCompletion(
			handle->device, &handle->completionReport, error
		);
		CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flReadChannelAsyncSubmit()");
		queueDepth--;
	}

	// Then request the data
	uStatus = usbBulkReadAsync(
		handle->device,
		handle->commInEP,   // endpoint to read
		buffer,             // pointer to buffer, or null
		count,              // number of data bytes
		5000,             // max timeout: 49 days
		error
	);
	CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flReadChannelAsyncSubmit()");
cleanup:
	return retVal;
}
コード例 #2
0
// 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;
	}
}
コード例 #3
0
// Await a previously-submitted async read.
//
DLLEXPORT(FLStatus) flReadChannelAsyncAwait(
	struct FLContext *handle, const uint8 **data, uint32 *requestLength, uint32 *actualLength,
	const char **error)
{
	FLStatus retVal = FL_SUCCESS;
	USBStatus uStatus;
	while ( !handle->completionReport.flags.isRead ) {
		uStatus = usbBulkAwaitCompletion(
			handle->device, &handle->completionReport, error
		);
		CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flReadChannelAsyncAwait()");
	}
	*data = handle->completionReport.buffer;
	*requestLength = handle->completionReport.requestLength;
	*actualLength = handle->completionReport.actualLength;
	memset(&handle->completionReport, 0, sizeof(struct CompletionReport));
cleanup:
	return retVal;
}
コード例 #4
0
DLLEXPORT(FLStatus) flAwaitAsyncWrites(struct FLContext *handle, const char **error) {
	FLStatus retVal = FL_SUCCESS, fStatus;
	USBStatus uStatus;
	size_t queueDepth;
	fStatus = flFlushAsyncWrites(handle, error);
	CHECK_STATUS(fStatus, fStatus, cleanup, "flAwaitAsyncWrites()");
	queueDepth = usbNumOutstandingRequests(handle->device);
	while ( queueDepth && !handle->completionReport.flags.isRead ) {
		uStatus = usbBulkAwaitCompletion(
			handle->device, &handle->completionReport, error
		);
		CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flAwaitAsyncWrites()");
		queueDepth--;
	}
	CHECK_STATUS(
		queueDepth, FL_BAD_STATE, cleanup,
		"flAwaitAsyncWrites(): An asynchronous read is in flight");
cleanup:
	return retVal;
}
コード例 #5
0
static FLStatus bufferAppend(
	struct FLContext *handle, const uint8 *data, size_t count, const char **error)
{
	FLStatus retVal = FL_SUCCESS;
	size_t spaceAvailable;
	size_t queueDepth = usbNumOutstandingRequests(handle->device);
	USBStatus uStatus;
	if ( !handle->writePtr ) {
		// There is not an active write buffer
		uStatus = usbBulkWriteAsyncPrepare(handle->device, &handle->writePtr, error);
		CHECK_STATUS(uStatus, FL_ALLOC_ERR, cleanup, "bufferAppend()");
		handle->writeBuf = handle->writePtr;
	}
	spaceAvailable = handle->chunkSize - (size_t)(handle->writePtr - handle->writeBuf);
	while ( count > spaceAvailable ) {
		// Reduce the depth of the work queue a little
		while ( queueDepth > 2 && !handle->completionReport.flags.isRead ) {
			uStatus = usbBulkAwaitCompletion(
				handle->device, &handle->completionReport, error);
			CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "bufferAppend()");
			queueDepth--;
		}
		
		// Fill up this buffer
		memcpy(handle->writePtr, data, spaceAvailable);
		data += spaceAvailable;
		count -= spaceAvailable;
		
		// Submit it
		uStatus = usbBulkWriteAsyncSubmit(
			handle->device, handle->commOutEP, handle->chunkSize, U32MAX, error);
		CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "bufferAppend()");
		queueDepth++;
		
		// Get a new buffer
		uStatus = usbBulkWriteAsyncPrepare(handle->device, &handle->writePtr, error);
		CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "bufferAppend()");
		handle->writeBuf = handle->writePtr;
		spaceAvailable = handle->chunkSize;
	}
	if ( count == spaceAvailable ) {
		// Reduce the depth of the work queue a little
		while ( queueDepth > 2 && !handle->completionReport.flags.isRead ) {
			uStatus = usbBulkAwaitCompletion(
				handle->device, &handle->completionReport, error);
			CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "bufferAppend()");
			queueDepth--;
		}
		
		// Fill up this buffer
		memcpy(handle->writePtr, data, spaceAvailable);
		data += spaceAvailable;
		count -= spaceAvailable;
		
		// Submit it
		uStatus = usbBulkWriteAsyncSubmit(
			handle->device, handle->commOutEP, handle->chunkSize, U32MAX, error);
		CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "bufferAppend()");
		queueDepth++;

		// Zero the pointers
		handle->writeBuf = handle->writePtr = NULL;
	} else {
		// Count is less than spaceAvailable
		memcpy(handle->writePtr, data, count);
		handle->writePtr += count;
	}
cleanup:
	return retVal;
}
コード例 #6
0
ファイル: main.c プロジェクト: makestuff/libusbwrap
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;
}
コード例 #7
0
ファイル: main.c プロジェクト: makestuff/libusbwrap
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;
}