#include "winusbdriver.h" winUsbDriver::winUsbDriver(QWidget *parent) : QLabel(parent) { qDebug() << "Making USB Driver invisible!!"; this->hide(); //Load stack so that reset signal can be sent usbInit(0x03eb, 0xa000); setDeviceMode(deviceMode); newDig(digitalPinState); usbIsoInit(); psuTimer = new QTimer(); psuTimer->setTimerType(Qt::PreciseTimer); psuTimer->start(PSU_PERIOD); connect(psuTimer, SIGNAL(timeout()), this, SLOT(psuTick())); } unsigned char winUsbDriver::usbInit(ULONG VIDin, ULONG PIDin){ unsigned char success; //qDebug() << "usbInit() entered"; if (!LstK_Init(&deviceList, (KLST_FLAG) 0)) { qDebug("Error initializing device list"); return 0; } //else qDebug() << "Device List initialised!"; LstK_Count(deviceList, &deviceCount); if (!deviceCount) { qDebug("Device list empty"); LstK_Free(deviceList); // If LstK_Init returns TRUE, the list must be freed. return 0; } //else qDebug() << "Device Count initialised!"; //qDebug("Looking for device VID = %04X, PID = %04X\n", VIDin, PIDin); LstK_FindByVidPid(deviceList, VIDin, PIDin, &deviceInfo); LstK_Free(deviceList); if (deviceInfo){ /*qDebug("Using %04X:%04X (%s): %s - %s\n", deviceInfo->Common.Vid, deviceInfo->Common.Pid, deviceInfo->Common.InstanceID, deviceInfo->DeviceDesc, deviceInfo->Mfg); Causes exceptions in debug mode!!!!*/ } else { qDebug("Could not find device VID = %04X, PID = %04X", VIDin, PIDin); return 0; } success = UsbK_Init(&handle, deviceInfo); if (!success){ ec = GetLastError(); qDebug("UsbK_Init failed. ErrorCode: %08Xh", ec); } else qDebug("Device opened successfully!"); return success; } void winUsbDriver::usbSendControl(int RequestType, int Request, int Value, int Index, int Length, unsigned char *LDATA){ ////////////////////////////////////////////////////////////////////////////////////////// //IF YOU'RE SEEING AN ERROR, CHECK THAT REQUESTTYPE AND REQUEST ARE FORMATTED AS HEX ////////////////////////////////////////////////////////////////////////////////////////// WINUSB_SETUP_PACKET setupPacket; unsigned char controlSuccess; UINT bytesTransferred = 0; unsigned char *controlBuffer; if (handle==NULL){ qDebug("Null handle error in usbSendControl"); return; } setupPacket.RequestType = (UCHAR) RequestType; setupPacket.Request = (UCHAR) Request; setupPacket.Value = (USHORT) Value; setupPacket.Index = (USHORT) Index; setupPacket.Length = (USHORT) Length; //qDebug("RequestType = %x, Request = %x, Value = %u, Index = %u, Length = %u", setupPacket.RequestType, setupPacket.Request, setupPacket.Value, setupPacket.Index, setupPacket.Length); if (LDATA==NULL){ controlBuffer = (unsigned char *) malloc(256); } else controlBuffer = LDATA; //qDebug() << controlBuffer; //qDebug() << handle; //qDebug("SENDING CONTROL PACKET\n"); controlSuccess = UsbK_ControlTransfer(handle, setupPacket, controlBuffer, setupPacket.Length, &bytesTransferred, NULL); if (controlSuccess) { qDebug("%d BYTES TRANSFERRED", bytesTransferred); } else qDebug("usbSendControl failed"); if(LDATA == NULL){ free(controlBuffer); } } void winUsbDriver::setPsu(double voltage){ qDebug() << "New voltage =" << voltage; currentPsuVoltage = voltage; //if(deviceMode > 6) qFatal("setPsu is not configured for mode 7!!!"); double vinp = voltage/11; double vinn = 0; //double vref = 1.65; double gainPsu = 1; dutyPsu = (int) ((vinp - vinn)/vref * gainPsu * PSU_ADC_TOP); qDebug() << "Going to send value " << dutyPsu; } void winUsbDriver::setFunctionGen(int channel, functionGenControl *fGenControl){ //////////////////////////// ////NO RESIZING (YET)!!!//// //////////////////////////// ////////////////////////////////////// //// CH1 is AUX!! CH2 is "MAIN"!!//// ////////////////////////////////////// int length, maxLength, numDivides, maxDivides; double freq, amplitude, offset; unsigned char *samples; //For recalling on crash. fGenChannel = channel; if (channel == 0) fGenPtr_CH1 = fGenControl; else fGenPtr_CH2 = fGenControl; //Reading in data if (channel == 0){ length = fGenControl->length_CH1; freq = fGenControl->freq_CH1; amplitude = fGenControl->amplitude_CH1; offset = fGenControl->offset_CH1; samples = (unsigned char *) malloc(length); memcpy(samples, fGenControl->samples_CH1, (unsigned int) length); numDivides = fGenControl->divisibility_CH1; } else if(channel == 1){ length = fGenControl->length_CH2; freq = fGenControl->freq_CH2; amplitude = fGenControl->amplitude_CH2; offset = fGenControl->offset_CH2; samples = (unsigned char *) malloc(length); memcpy(samples, fGenControl->samples_CH2, (unsigned int) length); numDivides = fGenControl->divisibility_CH2; } //Triple mode if ((amplitude+offset) > FGEN_LIMIT){ amplitude = amplitude / 3; offset = offset / 3; fGenTriple |= ((unsigned char) !channel + 1); } else fGenTriple &= ((unsigned char) (254 - !channel)); //qDebug() << "fGenTriple = " << fGenTriple << "fGenControl = " << fGenControl << "length = " << length << "freq = " << freq << "amplitude = " << amplitude << "offset = " << offset << "samples = " << samples; //Waveform scaling in V double tempDouble; amplitude = (amplitude * 255) / FGEN_LIMIT; offset = (offset * 255) / FGEN_LIMIT; if (offset5) amplitude -= FGEN_OFFSET; else amplitude = 0; offset = FGEN_OFFSET; } #ifdef INVERT_TRIPLE unsigned char fGenTemp = 0; fGenTemp |= (fGenTriple & 0x01)<<1; fGenTemp |= (fGenTriple & 0x02)>>1; usbSendControl(0x40, 0xa4, fGenTemp, 0, 0, NULL); #else usbSendControl(0x40, 0xa4, fGenTriple, 0, 0, NULL); #endif //Applying amplitude and offset to all samples. for (int i=0;i DAC_SPS){ loop_entered = true; numDivides--; if (numDivides==0){ qDebug("numDivides = 0 - in T-stretching of winUsbDriver:: setFunctionGen"); } int shiftTemp = (maxDivides - numDivides); length = length >> 1; free(tempSamples); tempSamples = (unsigned char *) malloc(length); for (int i=0; iNumberOfPackets;i++){ allocBytes +=isoCtx[n]->IsoPackets[i].Length; } } } //Allocate it (why am I allocating a new buffer every time?) returnBuffer = (unsigned char *) malloc(allocBytes + 8); //Extra 8 bytes for the "header" that contains length of "packet" as unsigned int. ((unsigned int *) returnBuffer)[0] = allocBytes; //Fill the memory with the relevant samples //Note that this will return garbage if more than one isoCtx has completed. //The above condition should only ever occur if the polling rate is slower than ISO_PACKETS_PER_CTX, though. //(Or if some heinous external force stops the polling and gives it a long "temporary period"!!) for (n=0; nNumberOfPackets;i++){ dataBufferOffset = isoCtx[n]->IsoPackets[i].Offset; //memcpy(&returnBuffer[returnBufferOffset], &dataBuffer[n][dataBufferOffset], isoCtx[n]->IsoPackets[i].Length); for(int j=0;jIsoPackets[i].Length;j++){ returnBuffer[returnBufferOffset+j] = dataBuffer[n][dataBufferOffset+j]; } returnBufferOffset += isoCtx[n]->IsoPackets[i].Length; } } //Setup next transfer UINT oldStart = isoCtx[n]->StartFrame; success = IsoK_ReUse(isoCtx[n]); if(!success){ errorCode = GetLastError(); qDebug() << "IsoK_Init failed with error code" << errorCode; qDebug() << "n =" << n; return (char*) returnBuffer; } isoCtx[n]->StartFrame = oldStart + ISO_PACKETS_PER_CTX*NUM_FUTURE_CTX; //qDebug() << oldStart; //qDebug() << isoCtx[n]->StartFrame; //qDebug() << handle; success = OvlK_ReUse(ovlkHandle[n]); if(!success){ errorCode = GetLastError(); qDebug() << "OvlK_ReUse failed with error code" << errorCode; qDebug() << "n =" << n; return (char*) returnBuffer; } success = UsbK_IsoReadPipe(handle, pipeID, dataBuffer[n], sizeof(dataBuffer[n]), (LPOVERLAPPED) ovlkHandle[n], isoCtx[n]); } //qDebug("%d bytes need to be allocated", allocBytes); return (char*) returnBuffer; } winUsbDriver::~winUsbDriver(void){ qDebug() << "\n\nwinUsbDriver destructor ran!"; unsigned char success; DWORD errorCode = ERROR_SUCCESS; UsbK_Free(handle); } void winUsbDriver::setBufferPtr(bufferControl *newPtr){ bufferPtr = newPtr; } void winUsbDriver::setDeviceMode(int mode){ int oldMode = deviceMode; deviceMode = mode; usbSendControl(0x40, 0xa5, (mode == 5 ? 0 : mode), gainMask, 0, NULL); if (fGenPtr_CH1!=NULL) setFunctionGen(0, fGenPtr_CH1); if (fGenPtr_CH2!=NULL) setFunctionGen(1, fGenPtr_CH2); //switch on new deviceMode!! switch(deviceMode){ case 0: if(oldMode > 2) sendClearBuffer(1,0,0); setVisible_CH2(0); checkXY(0); break; case 1: if(oldMode > 2) sendClearBuffer(1,0,0); sendClearBuffer(0,1,0); setVisible_CH2(1); checkXY(0); break; case 2: if(oldMode > 2) sendClearBuffer(1,0,0); sendClearBuffer(0,1,0); setVisible_CH2(1); break; case 3: if(oldMode != 4) sendClearBuffer(1,0,0); sendClearBuffer(0,1,0); setVisible_CH2(0); checkXY(0); break; case 4: if(oldMode != 3) sendClearBuffer(1,0,0); sendClearBuffer(0,1,0); setVisible_CH2(1); checkXY(0); break; case 5: setVisible_CH2(0); checkXY(0); break; case 6: sendClearBuffer(0,0,1); setVisible_CH2(0); checkXY(0); break; case 7: sendClearBuffer(1,0,0); enableMMTimer(); checkXY(0); break; default: qFatal("Error in winUsbDriver::setDeviceMode. Invalid device mode."); } } void winUsbDriver::psuTick(){ if(dutyTemp == dutyPsu) return; if (dutyTemp > dutyPsu){ if((dutyTemp - dutyPsu)> PSU_STEP){ dutyTemp -= PSU_STEP; } else dutyTemp = dutyPsu; } if (dutyTemp < dutyPsu){ if((dutyPsu - dutyTemp)> PSU_STEP){ dutyTemp += PSU_STEP; } else dutyTemp = dutyPsu; } if ((dutyTemp>106) || (dutyTemp<21)){ qDebug("PSU DUTY CYCLE TOO LARGE (could underflow on SOF)!!! ABORTING!!!"); } usbSendControl(0x40, 0xa3, dutyTemp, 0, 0, NULL); } void winUsbDriver::setGain(double newGain){ if (newGain == scopeGain) return; //No update! gainBuffers(scopeGain/newGain); scopeGain = newGain; if (newGain == 0.5){ gainMask = 7<<2 | 7<<10; } else gainMask = (unsigned short)(log2(newGain))<<2 | (unsigned short)(log2(newGain))<<10; qDebug("newGain = %f", newGain); qDebug("gainMask = %d", gainMask); usbSendControl(0x40, 0xa5, deviceMode, gainMask, 0, NULL); } void winUsbDriver::avrDebug(void){ usbSendControl(0x40, 0xa0, 0, 0, 0, NULL); }