// Kick off a shift operation on the micro. This will be followed by a bunch of sends and receives. // static NeroStatus beginShift( struct NeroHandle *handle, uint32 numBits, SendType sendType, bool isLast, bool isResponseNeeded, const char **error) { NeroStatus returnCode = NERO_SUCCESS; uint16 wValue = 0x0000; int uStatus; union { uint32 u32; uint8 bytes[4]; } leNumBits; leNumBits.u32 = littleEndian32(numBits); if ( isLast ) { wValue |= (1<<IS_LAST); } if ( isResponseNeeded ) { wValue |= (1<<IS_RESPONSE_NEEDED); } wValue |= sendType << SEND_TYPE; uStatus = usbControlWrite( handle->device, CMD_JTAG_CLOCK_DATA, // bRequest wValue, // wValue 0x0000, // wIndex leNumBits.bytes, // send bit count 4, // wLength 5000, // timeout (ms) error ); CHECK_STATUS(uStatus, "beginShift()", NERO_BEGIN_SHIFT); cleanup: return returnCode; }
// Implements all the control transfers that are required by D1 of the // ACM descriptor bmCapabilities, (USBPSTN1.20 Table 4). void usbCallbackSetupHandler() { if ((usbSetupPacket.bmRequestType & 0x7F) != 0x21) // Require Type==Class and Recipient==Interface. return; if (!(usbSetupPacket.wIndex == CDC_CONTROL_INTERFACE_NUMBER || usbSetupPacket.wIndex == CDC_DATA_INTERFACE_NUMBER)) return; switch(usbSetupPacket.bRequest) { case ACM_REQUEST_SET_LINE_CODING: // SetLineCoding (USBPSTN1.20 Section 6.3.10 SetLineCoding) usbControlWrite(sizeof(usbComLineCoding), (uint8 XDATA *)&usbComLineCoding); break; case ACM_REQUEST_GET_LINE_CODING: // GetLineCoding (USBPSTN1.20 Section 6.3.11 GetLineCoding) usbControlRead(sizeof(usbComLineCoding), (uint8 XDATA *)&usbComLineCoding); break; case ACM_REQUEST_SET_CONTROL_LINE_STATE: // SetControlLineState (USBPSTN1.20 Section 6.3.12 SetControlLineState) usbComControlLineState = usbSetupPacket.wValue; usbControlAcknowledge(); if(pLineStateChangeCallback) pLineStateChangeCallback(usbComControlLineState); break; } }
static int usbSetParameters_CDC_ACM (UsbDevice *device, uint8_t request, uint16_t value, const void *data, uint16_t size) { ssize_t result = usbControlWrite(device, UsbControlRecipient_Interface, UsbControlType_Class, request, value, device->serial.data->interface->bInterfaceNumber, data, size, 1000); return result != -1; }
static ssize_t tellUsbResource ( GioHandle *handle, uint8_t recipient, uint8_t type, uint8_t request, uint16_t value, uint16_t index, const void *data, uint16_t size, int timeout ) { UsbChannel *channel = handle->channel; return usbControlWrite(channel->device, recipient, type, request, value, index, data, size, timeout); }
ssize_t usbHidSetFeature ( UsbDevice *device, unsigned char interface, unsigned char report, const void *buffer, uint16_t length, int timeout ) { return usbControlWrite(device, UsbControlRecipient_Interface, UsbControlType_Class, UsbHidRequest_SetReport, (UsbHidReportType_Feature << 8) | report, interface, buffer, length, timeout); }
// Put the device in jtag mode (i.e drive or tristate the JTAG lines) // static NeroStatus setJtagMode(struct NeroHandle *handle, bool enable, const char **error) { NeroStatus returnCode; int uStatus = usbControlWrite( handle->device, CMD_MODE_STATUS, // bRequest enable ? MODE_JTAG : 0, // wValue MODE_JTAG, // wMask NULL, // no data 0, // wLength 5000, // timeout (ms) error ); CHECK_STATUS(uStatus, "setJtagMode()", NERO_ENABLE); return NERO_SUCCESS; cleanup: return returnCode; }
// Reset the USB toggle on the device by explicitly calling SET_INTERFACE. This is a dirty hack // that appears to be necessary when running FPGALink on a Linux VM running on a Windows host. // DLLEXPORT(FLStatus) flResetToggle( struct FLContext *handle, const char **error) { FLStatus retVal = FL_SUCCESS; USBStatus uStatus = usbControlWrite( handle->device, 0x0B, // bRequest 0x0000, // wValue 0x0000, // wIndex NULL, // buffer to write 0, // wLength 1000, // timeout (ms) error ); CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flResetToggle()"); cleanup: return retVal; }
// Select the conduit that should be used to communicate with the FPGA. Each device may support one // or more different conduits to the same FPGA, or different FPGAs. // DLLEXPORT(FLStatus) flSelectConduit( struct FLContext *handle, uint8 conduit, const char **error) { FLStatus retVal = FL_SUCCESS; USBStatus uStatus = usbControlWrite( handle->device, CMD_MODE_STATUS, // bRequest 0x0000, // wValue (uint16)conduit, // wIndex NULL, // buffer to receive current state of ports 0, // wLength 1000, // timeout (ms) error ); CHECK_STATUS(uStatus, FL_USB_ERR, cleanup, "flSelectConduit()"); cleanup: return retVal; }
// Apply the supplied bit pattern to TMS, to move the TAP to a specific state. // NeroStatus neroClockFSM( struct NeroHandle *handle, uint32 bitPattern, uint8 transitionCount, const char **error) { NeroStatus returnCode = NERO_SUCCESS; int uStatus; union { uint32 u32; uint8 bytes[4]; } lePattern; lePattern.u32 = littleEndian32(bitPattern); uStatus = usbControlWrite( handle->device, CMD_JTAG_CLOCK_FSM, // bRequest (uint16)transitionCount, // wValue 0x0000, // wIndex lePattern.bytes, // bit pattern 4, // wLength 5000, // timeout (ms) error ); CHECK_STATUS(uStatus, "neroClockFSM()", NERO_CLOCKFSM); cleanup: return returnCode; }
static int usbSetAttribute_FTDI (UsbDevice *device, unsigned char request, unsigned int value, unsigned int index) { logMessage(LOG_CATEGORY(USB_IO), "FTDI request: %02X %04X %04X", request, value, index); return usbControlWrite(device, UsbControlRecipient_Device, UsbControlType_Vendor, request, value, index, NULL, 0, 1000) != -1; }
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; }
static int writeDevice (unsigned char request, const void *buffer, int length) { return usbControlWrite(usbChannel->device, MT_REQUEST_RECIPIENT, MT_REQUEST_TYPE, request, 0, 0, buffer, length, MT_REQUEST_TIMEOUT); }