#include "winusbdriver.h" winUsbDriver::winUsbDriver(QWidget *parent) : genericUsbDriver(parent) { //This opens the USB connection. Nothing can continue until the board is up and running. bool connected = false; while(!connected){ QThread::msleep(32); connected = usbInit(0x03eb, 0xa000); } //Below is platform-independent constructor code. //I can't stick it in usbDriverGeneric since this needs to be run _after_ USB has initialised and calling virtuals from the superclass constructor is a bad idea! //You don't need to understand it, but it needs to go in the constructor of all platform-specific drivers! //(Actually, I think you could get away with omitting the first two lines but they don't hurt!) setDeviceMode(deviceMode); newDig(digitalPinState); usbIsoInit(); psuTimer = new QTimer(); psuTimer->setTimerType(Qt::PreciseTimer); psuTimer->start(PSU_PERIOD); connect(psuTimer, SIGNAL(timeout()), this, SLOT(psuTick())); } winUsbDriver::~winUsbDriver(void){ //Like any decent destructor, this just frees resources qDebug() << "\n\nwinUsbDriver destructor ran!"; for(int n=0;n 10)) strcpy(subString, "th"); //qDebug("\n\nThis is the %d%s Tick!", timerCount, subString); bool success; DWORD errorCode = ERROR_SUCCESS; int n, earliest = MAX_OVERLAP; unsigned int minFrame = 4294967295; unsigned int dataBufferOffset; unsigned int packetLength = 0; //Getting earliest transfer number. for (n=0; nStartFrame < minFrame){ minFrame = isoCtx[n]->StartFrame; earliest = n; } } } if (earliest == MAX_OVERLAP){ return; } //Copy the tranfer data into buffer for(int i=0;iNumberOfPackets;i++){ dataBufferOffset = isoCtx[earliest]->IsoPackets[i].Offset; memcpy(&(outBuffers[currentWriteBuffer][packetLength]), &dataBuffer[earliest][dataBufferOffset], isoCtx[earliest]->IsoPackets[i].Length); packetLength += isoCtx[earliest]->IsoPackets[i].Length; } //Get the data for isoRead() ready and swap buffers bufferLengths[currentWriteBuffer] = packetLength; currentWriteBuffer = !currentWriteBuffer; //Zero length packet means something's gone wrong. Probably a disconnect. //In the Linux version, this check is implemented as a timer that attempts a control packet every 250ms. //It doesn't matter how you do it, but it's important that there's some code that checks for device disconnects periodically and, if detected, emits the killMe() signal. if(packetLength == 0){ qDebug() << "Zero length iso packet. An hero!"; killMe(); } //Setup transfer for resubmission UINT oldStart = isoCtx[earliest]->StartFrame; success = IsoK_ReUse(isoCtx[earliest]); if(!success){ errorCode = GetLastError(); qDebug() << "IsoK_Init failed with error code" << errorCode; qDebug() << "n =" << n; return; } isoCtx[earliest]->StartFrame = oldStart + ISO_PACKETS_PER_CTX*NUM_FUTURE_CTX; success = OvlK_ReUse(ovlkHandle[earliest]); if(!success){ errorCode = GetLastError(); qDebug() << "OvlK_ReUse failed with error code" << errorCode; qDebug() << "n =" << n; return; } //Resubmit the transfer success = UsbK_IsoReadPipe(handle, pipeID, dataBuffer[earliest], sizeof(dataBuffer[earliest]), (LPOVERLAPPED) ovlkHandle[earliest], isoCtx[earliest]); //Signal to isoDriver that it can draw a new frame. upTick(); return; } char *winUsbDriver::isoRead(unsigned int *newLength){ //This will be called almost immediately after the upTick() signal is sent. Make sure bufferLengths[] abd outBuffers[] are ready! *(newLength) = bufferLengths[!currentWriteBuffer]; return (char*) outBuffers[(unsigned char) !currentWriteBuffer]; }