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; }
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; }