// 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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}