int libusb_submit_transfer(struct libusb_transfer* transfer) { transfer_wrapper* wrapper = GetWrapper(transfer); void*& context = wrapper->usb; if (NULL == context) { int ret (LIBUSB_ERROR_OTHER); switch(transfer->type) { case LIBUSB_TRANSFER_TYPE_CONTROL : fprintf(stderr, "ERROR: libusb_submit_transfer() with LIBUSB_TRANSFER_TYPE_CONTROL; use libusb_control_transfer() instead.\n"); return(LIBUSB_ERROR_INVALID_PARAM); case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS : ret = usb_isochronous_setup_async(translate(transfer->dev_handle), &context, transfer->endpoint, transfer->iso_packet_desc[0].length); break; case LIBUSB_TRANSFER_TYPE_BULK : ret = usb_bulk_setup_async(translate(transfer->dev_handle), &context, transfer->endpoint); break; case LIBUSB_TRANSFER_TYPE_INTERRUPT : ret = usb_interrupt_setup_async(translate(transfer->dev_handle), &context, transfer->endpoint); break; default : return(LIBUSB_ERROR_INVALID_PARAM); } if (ret < 0) { // TODO: better error handling... // what do the functions usb_***_setup_async() actually return on error? return(ret); } TMapIsocTransfers::iterator it = mIsocTransfers.find(transfer->endpoint); if (it == mIsocTransfers.end()) mIsocTransfers.insert(std::make_pair(transfer->endpoint, new TListTransfers())); } mIsocTransfers[transfer->endpoint]->Append(wrapper); transfer->status = LIBUSB_TRANSFER_COMPLETED; int ret = usb_submit_async(context, (char*)transfer->buffer, transfer->length); if (ret < 0) { // TODO: better error handling... // what does usb_submit_async() actually returns on error? // LIBUSB_ERROR_NO_DEVICE if the device has been disconnected // LIBUSB_ERROR_BUSY if the transfer has already been submitted. // another LIBUSB_ERROR code on other failure return(ret); } // 0 on success return(0); }
int TransferAsync(struct BENCHMARK_TRANSFER_PARAM* transferParam, struct BENCHMARK_TRANSFER_HANDLE** handleRef) { int ret; struct BENCHMARK_TRANSFER_HANDLE* handle; *handleRef = NULL; // Submit transfers until the maximum number of outstanding transfer(s) is reached. while (transferParam->OutstandingTransferCount < transferParam->Test->BufferCount) { // Get the next available benchmark transfer handle. *handleRef = handle = &transferParam->TransferHandles[transferParam->TransferHandleNextIndex]; // If a libusb-win32 transfer context hasn't been setup for this benchmark transfer // handle, do it now. // if (!handle->Context) { // Data buffer(s) are located at the end of the transfer param. handle->Data = transferParam->Buffer + (transferParam->TransferHandleNextIndex * transferParam->Test->BufferSize); handle->DataMaxLength = transferParam->Test->BufferSize; switch (ENDPOINT_TYPE(transferParam)) { case USB_ENDPOINT_TYPE_ISOCHRONOUS: ret = usb_isochronous_setup_async(transferParam->Test->DeviceHandle, &handle->Context, transferParam->Ep.bEndpointAddress, transferParam->IsoPacketSize ? transferParam->IsoPacketSize : transferParam->Ep.wMaxPacketSize); break; case USB_ENDPOINT_TYPE_BULK: ret = usb_bulk_setup_async(transferParam->Test->DeviceHandle, &handle->Context, transferParam->Ep.bEndpointAddress); break; case USB_ENDPOINT_TYPE_INTERRUPT: ret = usb_interrupt_setup_async(transferParam->Test->DeviceHandle, &handle->Context, transferParam->Ep.bEndpointAddress); break; default: ret = -1; break; } if (ret < 0) { CONERR("failed creating transfer context ret=%d\n",ret); goto Done; } } // Submit this transfer now. handle->ReturnCode = ret = usb_submit_async(handle->Context, handle->Data, handle->DataMaxLength); if (ret < 0) goto Done; // Mark this handle has InUse. handle->InUse = TRUE; // When transfers ir successfully submitted, OutstandingTransferCount goes up; when // they are completed it goes down. // transferParam->OutstandingTransferCount++; // Move TransferHandleNextIndex to the next available transfer. INC_ROLL(transferParam->TransferHandleNextIndex, transferParam->Test->BufferCount); } // If the number of outstanding transfers has reached the limit, wait for the // oldest outstanding transfer to complete. // if (transferParam->OutstandingTransferCount == transferParam->Test->BufferCount) { // TransferHandleWaitIndex is the index of the oldest outstanding transfer. *handleRef = handle = &transferParam->TransferHandles[transferParam->TransferHandleWaitIndex]; // Only wait, cancelling & freeing is handled by the caller. handle->ReturnCode = ret = usb_reap_async_nocancel(handle->Context, transferParam->Test->Timeout); if (ret < 0) goto Done; // Mark this handle has no longer InUse. handle->InUse = FALSE; // When transfers ir successfully submitted, OutstandingTransferCount goes up; when // they are completed it goes down. // transferParam->OutstandingTransferCount--; // Move TransferHandleWaitIndex to the oldest outstanding transfer. INC_ROLL(transferParam->TransferHandleWaitIndex, transferParam->Test->BufferCount); } Done: return ret; }
//***************************************************** //* Name: pindmdInit //* Purpose: initialize ftdi driver //* In: //* Out: //***************************************************** void pinddrvInit(void) { UINT8 deviceId; #ifdef PINDMD2 int ret = 0; enabled = 1; do16 = 1; //f = fopen("debug.txt","w"); //init usb library usb_init(); //find busses usb_find_busses(); //find devices usb_find_devices(); //try to open our device if( !( device = open_dev() ) ) { //if not successfull, print error message MessageBox(NULL, "PinDMD not found", "Error", MB_ICONERROR); enabled = 0; return; } //set configuration if( usb_set_configuration( device, MY_CONFIG ) < 0 ) { MessageBox(NULL, "PinDMD cannot configure", "Error", MB_ICONERROR); enabled = 0; usb_close( device ); return; } //try to claim interface for use if( usb_claim_interface( device, MY_INTF ) < 0 ) { MessageBox(NULL, "PinDMD cannot claim interface", "Error", MB_ICONERROR); enabled = 0; usb_close( device ); return; } // SETUP async ret = usb_bulk_setup_async( device, &asyncWriteContext, EP_OUT ); if( ret < 0 ) { MessageBox(NULL, "PinDMD cannot setup async", "Error", MB_ICONERROR); enabled = 0; //relese interface usb_release_interface( device, MY_INTF ); //close device and exit usb_close( device ); return; } //if(f) // fprintf(f,"all ok:%d \n",enabled); #else FT_DEVICE_LIST_INFO_NODE *devInfo; DWORD numDevs; UINT8 i; UINT8 BitMode; deviceId = 0; sendFrameCount=0; // create the device information list ftStatus = FT_CreateDeviceInfoList(&numDevs); enabled = 0; // ftdi devices found if (numDevs > 0) { // allocate storage for list based on numDevs devInfo = (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs); // get the device information list ftStatus = FT_GetDeviceInfoList(devInfo,&numDevs); // info request successful if (ftStatus == FT_OK) { for (i = 0; i < numDevs; i++) { // search for pindmd board serial number if((strcmp(devInfo[i].SerialNumber,"DMD1000")==0) || (strcmp(devInfo[i].SerialNumber,"DMD1001")==0) || (strcmp(devInfo[i].SerialNumber,"DMD2000A")==0)){ // assign divice id (incase other ftdi devices are connected) deviceId=i; enabled = 1; } // pinDMD 2 //if(strcmp(devInfo[i].SerialNumber,"DMD2000A")==0) // pinDMD_Version = 2; // slow usb if(strcmp(devInfo[i].SerialNumber,"DMD1001")==0) slowUSB = 1; } } } else { enabled=0; return; } // get handle on device ftStatus = FT_Open(deviceId, &ftHandle); if(ftStatus != FT_OK){ // FT_Open failed return; enabled=0; return; } // check pinDMD firmware to see if its 16 colour (bit4=true) FT_SetBitMode(ftHandle, 0x0, 0x20); ftStatus = FT_GetBitMode(ftHandle, &BitMode); if (ftStatus == FT_OK) { // BitMode contains current value do16 = ((BitMode&0x08)==0x08); doOther = ((BitMode&0x04)==0x04); } // original pinDMD //if(pinDMD_Version==1){ // set Asynchronous Bit Bang Mode FT_SetBitMode(ftHandle, 0xff, 0x1); // set Baud FT_SetBaudRate(ftHandle, slowUSB?11000:12000); // Actually 10400 * 16 // new pinDMD 2 FPGA /*} else { do16 = 1; FT_SetBitMode(ftHandle, 0xff, 0); Sleep(10); FT_SetBitMode(ftHandle, 0xff, 0x40); FT_SetLatencyTimer(ftHandle, 16); FT_SetUSBParameters(ftHandle,0x10000, 0x10000); FT_SetFlowControl(ftHandle, FT_FLOW_RTS_CTS, 0x0, 0x0); FT_Purge(ftHandle, FT_PURGE_RX); Sleep(10); }*/ #endif }