#include "stdafx.h" #include ".\ADMCA\DPP\USB\DppUSB.h" #include #include #include #ifdef _DEBUG #define USB_DEBUG_MODE 1 #else #define USB_DEBUG_MODE 0 #endif CDppUSB::CDppUSB(void) { USB_Device_Handle = INVALID_HANDLE_VALUE; PipeHandle_config = INVALID_HANDLE_VALUE; PipeHandle_configOut = INVALID_HANDLE_VALUE; PipeHandle_statusA = INVALID_HANDLE_VALUE; PipeHandle_dataA = INVALID_HANDLE_VALUE; PipeHandle_statusB = INVALID_HANDLE_VALUE; PipeHandle_dataB = INVALID_HANDLE_VALUE; PipeHandle_Scope = INVALID_HANDLE_VALUE; NumUSBDevices = 0; CurrentDevice = 1; DriverOpen = false; PipesOpen = false; isSendingPacket = false; usb_busy = false; isDPP5 = false; cstrDppUsbDeviceType = ""; HaveDeviceStatus = false; } CDppUSB::~CDppUSB(void) { CloseUSB(); } // Monitor Conditions // ------------------ // Driver Not Connected or Closed (!DriverOpen) // Connect to driver (in OpenUSB) // Scan for devices (in OpenUSB) // Open Device if devices > 0 (in OpenUSB) // DriverOpen (DriverOpen) // Check for device status: // Device Not Open ((DriverOpen && !PipesOpen) && (NumUSBDevices > 0)) // open pipes, check success, return number of devices // Device Open, PipesOpen ((DriverOpen && PipesOpen) && (NumUSBDevices > 0)) // return number of devices // Device Removed ((DriverOpen && PipesOpen) && (NumUSBDevices == 0)) // close pipes, rescan for devices, return number of devices // No Devices ((DriverOpen && !PipesOpen) && (NumUSBDevices == 0)) // return number of devices int CDppUSB::MonitorUSBDevices() { while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // check for devices once, to start usb_busy = false; if (DriverOpen == false) { // cannot detect devices if the driver is not open NumUSBDevices = OpenUSB(); // open the driver and try to detect any devices } else if ((DriverOpen && !PipesOpen) && (NumUSBDevices > 0)) { // Device Not Open // open pipes, check success, return number of devices NumUSBDevices = OpenUSBPipes(); // open the pipes } else if ((DriverOpen && PipesOpen) && (NumUSBDevices > 0)) { // Device Open, PipesOpen // return number of devices from initial check } else if ((DriverOpen && PipesOpen) && (NumUSBDevices == 0)) { // Device Removed // close pipes, rescan for devices, return number of devices from initial check CloseUSBPipes(); } else if ((DriverOpen && !PipesOpen) && (NumUSBDevices == 0)) { // No Devices // return number of devices from initial check } return NumUSBDevices; } // convert a 4 byte long word to a double // lwStart - starting index of longword // buffer - byte buffer double CDppUSB::LongWordToDouble(int lwStart, UCHAR buffer[]) { double dblVal; int j; double ByteMask; dblVal = 0; for(j=0;j<4;j++) { // build 4 bytes (lwStart-lwStart+3) into double ByteMask = pow(2.0,(8.0 * (double)j)); dblVal = dblVal + (buffer[(lwStart + j)] * ByteMask); } return dblVal; } // returns true if successful, false otherwise // the results are stored in dppusbSerialNumber, dppusbDeviceType bool CDppUSB::GetUSBDeviceInfo() { UCHAR Status[USB_BUFFER_SIZE]; dppusbDeviceType = 0; dppusbSerialNumber = 0; while(usb_busy); usb_busy = true; int iNumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; isDPP5 = false; // DPP5 20070927 intialize DPP5 indicator if (NumUSBDevices <= 0) { return false; } // no devices GetDPPStatus(true,Status); //get the device type and serial number dppusbFPGA = UCHARVersionToDouble(Status[8]); // DPP5 20070907 // FPGA version (8 bits) dppusbFirmware = UCHARVersionToDouble(Status[13]); // DPP5 20070907 // embedded code version if (dppusbFirmware >= 5.0) { // DPP5 20070907 // device is DPP5 if firmware >= 5.0 isDPP5 = true; } else { isDPP5 = false; } dppusbDeviceType = ((((Status[23] & 0x80) >> 7) + 1) + ((int)isDPP5 * 2)); // device indicator from status dppusbSerialNumber = (ULONG)LongWordToDouble(14, Status); // SerialNumber bytes 0-3 cstrDppUsbDeviceType = GetDeviceNameFromVal(dppusbDeviceType); //AfxMessageBox(cstrDppUsbDeviceType); //CETest return true; } CString CDppUSB::GetDeviceNameFromVal(int DeviceTypeVal) { CString cstrDeviceType; switch(DeviceTypeVal) { case 1: cstrDeviceType = "DP4"; break; case 2: cstrDeviceType = "PX4"; break; case 3: cstrDeviceType = "DP4EMUL"; break; case 4: cstrDeviceType = "DP5"; break; default: // unknown cstrDeviceType = ""; break; } return cstrDeviceType; } // calculate major.minor version from UCHAR, convert/save to double double CDppUSB::UCHARVersionToDouble(UCHAR Version) { double dblVersion; CString strTemp; strTemp.Format(_T("%d.%02d"),((Version & 240) / 16),(Version & 15)); //AfxMessageBox(strTemp); //CETest //dblVersion = atof(strTemp); dblVersion = wcstod(strTemp,NULL); return dblVersion; } // monitors usb for attached devices int CDppUSB::USBTimer() { return MonitorUSBDevices(); } UINT CDppUSB::OpenUSBPipes() { UINT Device; UINT Flags; // DPP5 20070912 Device Test --------------------- UCHAR Status[USB_BUFFER_SIZE]; UCHAR Firmware; // DPP5 20070912 --------------------------------- if (!DriverOpen) return 0; // cannot open pipes or count devices if driver not open CloseUSBPipes(); // close the pipes if open NumUSBDevices = 0; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices >= 1) { Device = CurrentDevice; // default to first device Flags = FILE_FLAG_OVERLAPPED; while(usb_busy); usb_busy = true; PipeHandle_config = USBDRVD_PipeOpen(Device, 0, Flags, &GUID_CLASS); // Pipe 0 PipeHandle_statusA = USBDRVD_PipeOpen(Device, 1, Flags, &GUID_CLASS); // Pipe 1 PipeHandle_dataA = USBDRVD_PipeOpen(Device, 2, Flags, &GUID_CLASS); // Pipe 2 usb_busy = false; // DPP5 20070912/20071126 Read and test status for DPP5 device type HaveDeviceStatus = false; GetDPP_PipeOpen_Status(true,Status); //get devicetype and sernum,no ready check if (HaveDeviceStatus) { Firmware = Status[13]; // embedded code version if (Firmware >= 80) { isDPP5 = true; } else { isDPP5 = false; } } else { isDPP5 = false; // try the device as a DP4/PX4 } while(usb_busy); usb_busy = true; if (isDPP5) PipeHandle_configOut = USBDRVD_PipeOpen(Device, 3, Flags, &GUID_CLASS); // DPP5 20070907 // Pipe 3 if (! isDPP5) PipeHandle_statusB = USBDRVD_PipeOpen(Device, 3, Flags, &GUID_CLASS); // DPP5 20070907 no DPP5 statusB pipe if (! isDPP5) PipeHandle_dataB = USBDRVD_PipeOpen(Device, 4, Flags, &GUID_CLASS); // DPP5 20070907 no DPP5 dataB pipe if (! isDPP5) PipeHandle_configOut = USBDRVD_PipeOpen(Device, 5, Flags, &GUID_CLASS); // DPP5 20070907 configOut pipe will be pipe 3 for DPP5 if (! isDPP5) PipeHandle_Scope = USBDRVD_PipeOpen(Device, 6, Flags, &GUID_CLASS); // DPP5 20070907 Scope pipe disabled until implemented usb_busy = false; PipesOpen = true; } return NumUSBDevices; } UINT CDppUSB::OpenUSB() { UINT Device; UINT Flags; NumUSBDevices = 0; if (DriverOpen == false) { Device = CurrentDevice; // default to first device Flags = FILE_FLAG_OVERLAPPED; while(usb_busy); usb_busy = true; USB_Device_Handle = USBDRVD_OpenDevice(Device, 0, &GUID_CLASS); usb_busy = false; // check if the driver is open if ((USB_Device_Handle != INVALID_HANDLE_VALUE) && (USB_Device_Handle != NULL)){ DriverOpen = true; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (PipesOpen) { // must reopen pipes for the current device CloseUSBPipes(); } if (NumUSBDevices > 0) { // if a device is present open the device OpenUSBPipes(); } } else { // driver error, attempt to close driver NumUSBDevices = 0; CloseUSB(); } } else { while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; } return NumUSBDevices; } UINT CDppUSB::OpenUSBEx(UINT Device) { //CurrentDevice = Device; // jungo only open default device OpenUSB(); return NumUSBDevices; } void CDppUSB::CloseUSBPipes() { if (PipesOpen) { while(usb_busy); usb_busy = true; USBDRVD_PipeClose (PipeHandle_config); if (PipeHandle_configOut != INVALID_HANDLE_VALUE) USBDRVD_PipeClose (PipeHandle_configOut); // DPP5 200709011 disable configOut pipe close if not valid USBDRVD_PipeClose (PipeHandle_statusA); USBDRVD_PipeClose (PipeHandle_dataA); if ((! isDPP5) && (PipeHandle_statusB != INVALID_HANDLE_VALUE)) USBDRVD_PipeClose (PipeHandle_statusB); // DPP5 20070911 no DPP5 statusB pipe if ((! isDPP5) && (PipeHandle_dataB != INVALID_HANDLE_VALUE)) USBDRVD_PipeClose (PipeHandle_dataB); // DPP5 20070907 no DPP5 dataB pipe if ((! isDPP5) && (PipeHandle_Scope != INVALID_HANDLE_VALUE)) USBDRVD_PipeClose (PipeHandle_Scope); // DPP5 20070907 DPP5 Scope pipe disabled until implemented usb_busy = false; PipeHandle_config = INVALID_HANDLE_VALUE; PipeHandle_configOut = INVALID_HANDLE_VALUE; PipeHandle_statusA = INVALID_HANDLE_VALUE; PipeHandle_dataA = INVALID_HANDLE_VALUE; PipeHandle_statusB = INVALID_HANDLE_VALUE; PipeHandle_dataB = INVALID_HANDLE_VALUE; PipeHandle_Scope = INVALID_HANDLE_VALUE; PipesOpen = false; } NumUSBDevices = 0; } void CDppUSB::CloseUSB() { if (DriverOpen) { CloseUSBPipes(); while(usb_busy); usb_busy = true; USBDRVD_CloseDevice (USB_Device_Handle); usb_busy = false; USB_Device_Handle = INVALID_HANDLE_VALUE; DriverOpen = false; } NumUSBDevices = 0; } //----------------------------------------------------------------------------------- //82H Enable MCA/MCS //83H Disable MCA/MCS //----------------------------------------------------------------------------------- UINT CDppUSB::PauseMCAUSB(BOOLEAN boolPauseMCA) { ULONG ret; UCHAR buffer[64]; //UCHAR buffer[USB_BUFFER_SIZE]; if (! USBDeviceReady()) { return 0; } ClearBufferArray(buffer); while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { // only send if USB DP4 detected if (boolPauseMCA) { // Req type=2 (Vendor), Dest=3 (other), Request=0x83 (disable MCA), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x83, 0, 0, buffer, 0); usb_busy = false; } else { // Req type=2 (Vendor), Dest=3 (other), Request=0x82 (enable MCA), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x82, 0, 0, buffer, 0); usb_busy = false; } } return NumUSBDevices; } void CDppUSB::SendUSBPacket(UCHAR buffer[]) { UINT Count; DWORD nBytes; DWORD Timeout; ULONG ret; int retries; int CurTry; if (! USBDeviceReady()) { return; } CString cstrBufMsg; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { // only send config packet if USB DP4 detected Count = 64; // 64-byte USB packet Timeout = 100; // .1 second timeout retries = 5; // 5 chances to send config CurTry = 0; // holds the current number of tries do { ret = 0; nBytes = 0; while(usb_busy); usb_busy = true; ret = USBDRVD_PipeWriteTimeout(PipeHandle_config, buffer, Count, &nBytes, Timeout); usb_busy = false; CurTry++; } while(((nBytes != Count) || (ret == FALSE)) && (CurTry < retries)); } } //----------------------------------------------------------------------------------- //80H Clear buffer A //81H Clear buffer B (doesn't do anything on DP5) //----------------------------------------------------------------------------------- void CDppUSB::ClearBuffer(BOOLEAN isBufferA) { ULONG ret; UCHAR buffer[64]; if (! USBDeviceReady()) { return; } ClearBufferArray(buffer); if (isBufferA) { // Req type=2 (Vendor), Dest=3 (other), Request=0x80 (clear buffer A), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x80, 0, 0, buffer, 0); usb_busy = false; } else { // Req type=2 (Vendor), Dest=3 (other), Request=0x81 (clear buffer B), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x81, 0, 0, buffer, 0); usb_busy = false; } //CString cstrRetVal; //cstrRetVal.Format("ClearBuffer ret: %d", ret); //::MessageBox(NULL,cstrRetVal,"USBDRVD_VendorOrClassRequestOut",MB_ICONINFORMATION); } BOOLEAN CDppUSB::USBDeviceReady() { if (!DriverOpen) return FALSE; if (!PipesOpen) return FALSE; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { return TRUE; } else { return FALSE; } } // returns 0 if fails, return same codes as ReadFile() ULONG CDppUSB::GetDPPConfig(UCHAR ConfigIn[], bool isScopeData) { UINT Count; DWORD nBytes; DWORD Timeout; ULONG ret; int retries; int CurTry; //CString cstrCETest; //CETest //cstrCETest.Format(_T("%d"),PipeHandle_configOut); //CETest //AfxMessageBox(cstrCETest); //CETest if (isScopeData && (! isDPP5)) { return 0; } if ((PipeHandle_configOut == INVALID_HANDLE_VALUE)) { return 0; } // DPP5 20070907 disabled until DPP5 cfg read fully implemented if (! USBDeviceReady()) { return 0; } Count = 64; // status packet=64 bytes if (isScopeData) { Count = 512; } Timeout = 100; // .1 second timeout retries = 5; // 5 chances to send config CurTry = 0; // holds the current number of tries do { ret = 0; nBytes = 0; while(usb_busy); usb_busy = true; //!!!!! update count for count ret = USBDRVD_PipeReadTimeout(PipeHandle_configOut, ConfigIn, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; CurTry++; } while(((nBytes != Count) || (ret == FALSE)) && (CurTry < retries)); return nBytes; } void CDppUSB::GetDPPStatus(BOOLEAN isBufferA, UCHAR Status[]) { UINT Count; DWORD nBytes; DWORD Timeout; ULONG ret; int retries; int CurTry; if (! USBDeviceReady()) { return; } Count = 64; // status packet=64 bytes Timeout = 100; // .1 second timeout retries = 5; // 5 chances to send config CurTry = 0; // holds the current number of tries do { ret = 0; nBytes = 0; if (isBufferA) { while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_statusA, Status, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; } else if (! isDPP5) { // DPP5 20070907 DPP5 devices do not have a BufferB while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_statusB, Status, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; } CurTry++; } while(((nBytes != Count) || (ret == FALSE)) && (CurTry < retries)); // test for device status needed to open pipes HaveDeviceStatus = (isBufferA && (nBytes == Count) && (ret != FALSE) && (CurTry < retries)); } void CDppUSB::GetDPP_PipeOpen_Status(BOOLEAN isBufferA, UCHAR Status[]) { UINT Count; DWORD nBytes; DWORD Timeout; ULONG ret; int retries; int CurTry; //if (! USBDeviceReady()) { return; } // ALL PIPES ARE NOT OPEN CANNOT CHECK AT THIS POINT Count = 64; // status packet=64 bytes Timeout = 100; // .1 second timeout retries = 5; // 5 chances to send config CurTry = 0; // holds the current number of tries do { ret = 0; nBytes = 0; if (isBufferA) { while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_statusA, Status, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; } else if (! isDPP5) { // DPP5 20070907 DPP5 devices do not have a BufferB while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_statusB, Status, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; } CurTry++; } while(((nBytes != Count) || (ret == FALSE)) && (CurTry < retries)); // test for device status needed to open pipes HaveDeviceStatus = (isBufferA && (nBytes == Count) && (ret != FALSE) && (CurTry < retries)); } // reads data and returns actual number of bytes read DWORD CDppUSB::GetDPPData(BOOLEAN isBufferA, UCHAR buffer[], UINT ExpectedCount) { UINT Count; DWORD nBytes; DWORD Timeout; ULONG ret; int retries; int CurTry; if (! USBDeviceReady()) { return 0; } Count = ExpectedCount; // status packet=64 bytes Timeout = 100; // .1 second timeout retries = 5; // 5 chances to send config CurTry = 0; // holds the current number of tries do { ret = 0; nBytes = 0; if (isBufferA) { while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_dataA, buffer, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; } else { if (isDPP5) { return 0; } // DPP5 20070907 DPP5 devices do not have a BufferB if ((PipeHandle_dataB == INVALID_HANDLE_VALUE)) { return 0; } // DPP5 20070907 exit on bad bufferB pipe while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_dataB, buffer, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; } CurTry++; } while(((nBytes != Count) || (ret == FALSE)) && (CurTry < retries)); return nBytes; } // loads buffer with config data and sends as usb packet void CDppUSB::SendDPPConfigUSB(UCHAR Config[], UINT Preset) { int i; UCHAR buffer[USB_BUFFER_SIZE]; UCHAR buffer2[USB_CFG_IN_SIZE]; for(i=0; i<=10; i++) { // assign config bytes 0-10 to buffer buffer[i] = Config[i+2]; } buffer[11] = (BYTE)(Preset % 256); // !!! preset is set in config cmdbtn fn buffer[12] = (BYTE)((Preset / 256) % 256); buffer[13] = (BYTE)((Preset / 65536) % 256); for(i=14; i<=29; i++) { // assign config bytes 14-29 to buffer buffer[i] = Config[i-1]; } //CString cstrMCS; //cstrMCS.Format("%d",buffer[29] & 0x0F); //AfxMessageBox(cstrMCS); buffer[30] = 0; // these bytes are not assigned buffer[31] = 0; for(i=32; i<=63; i++) { // assign config bytes 32-63 to buffer buffer[i] = Config[i]; } SendUSBPacket(buffer); //CString strBufferData; //strBufferData = DisplayBufferArray(buffer); //SaveStringDataToFile(strBufferData); GetDPPConfig(buffer2,false); bool isSame; isSame = CompareBufferArrays(buffer,buffer2); if (!isSame) { SendUSBPacket(buffer); GetDPPConfig(buffer2,false); isSame = CompareBufferArrays(buffer,buffer2); } } void CDppUSB::SaveStringDataToFile(CString strData) { FILE *out; CString strFilename; CString strError; strFilename = "CfgHex.txt"; if ( (out = _tfopen(strFilename,_T("w"))) == (FILE *) NULL) strError.Format(_T("Couldn't open %s for writing.\n"), strFilename); else { fprintf(out,"%s\n",strData); } fclose(out); } bool CDppUSB::CompareBufferArrays(UCHAR buffer[], UCHAR buffer2[]) { int i; int arrsize; bool isSame; isSame = true; arrsize = (sizeof buffer) / (sizeof buffer[0]); for(i=0;i 0) { // Req type=2 (Vendor), Dest=3 (other), Request=0x84 (arm scope trigger), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x84, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //85H Autoset input offset (fine steps) (DPP5 not implemented yet) //----------------------------------------------------------------------------------- void CDppUSB::InputOffsetFineStep() { ULONG ret; UCHAR buffer[64]; //if (isDPP5) return; // DPP5 20070910 disable InputOffsetFineStep for DPP5 while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { // Req type=2 (Vendor), Dest=3 (other), Request=0x85 (InputOffsetFineStep), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x85, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //86H Autoset input offset (coarse steps) (DPP5 not implemented yet) //----------------------------------------------------------------------------------- void CDppUSB::InputOffsetCoarseStep() { ULONG ret; UCHAR buffer[64]; //if (isDPP5) return; // DPP5 20070910 disable InputOffsetCoarseStep for DPP5 while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { // Req type=2 (Vendor), Dest=3 (other), Request=0x86 (InputOffsetCoarseStep), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x86, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //87H Autoset fast threshold (DPP5 not implemented yet) //----------------------------------------------------------------------------------- void CDppUSB::DPPCalcFastThresh() { ULONG ret; UCHAR buffer[64]; //if (isDPP5) return; // DPP5 20070910 disable DPPCalcFastThresh for DPP5 while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { // Req type=2 (Vendor), Dest=3 (other), Request=0x87 (DPPCalcFastThresh), Val=0, Index=0, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x87, 0, 0, buffer, 0); usb_busy = false; } } DWORD CDppUSB::GetScopeData(UCHAR Scope[]) { UINT Count; DWORD nBytes; DWORD Timeout; ULONG ret; int retries; int CurTry; if (isDPP5) { return 0; } // DPP5 20071210 disabled dpp5 scope uses PipeHandle_configOut pipe if ((PipeHandle_Scope == INVALID_HANDLE_VALUE)) { return 0; } // DPP5 20070907 exit on bad scope pipe if (! USBDeviceReady()) { return 0; } Count = 512; // scope packet=512 bytes Timeout = 100; // .1 second timeout retries = 5; // 5 chances to send config CurTry = 0; // holds the current number of tries do { ret = 0; nBytes = 0; if (usb_busy) return 0; while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_Scope, Scope, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; CurTry++; } while(((nBytes != Count) || (ret == FALSE)) && (CurTry < retries)); return nBytes; } double CDppUSB::GetDriverVersion() { UINT ret; ULONG USB_Major; ULONG USB_Minor; double dblVersion; CString strVersion; if (! USBDeviceReady()) { return 0; } if (usb_busy) return 0; while(usb_busy); usb_busy = true; ret = USBDRVD_GetDriverVersion(USB_Device_Handle, &USB_Major, &USB_Minor); usb_busy = false; //Driver Version strVersion.Format(_T("%d.%03d"),USB_Major,USB_Minor); //dblVersion = atof(strVersion); dblVersion = wcstod(strVersion,NULL); return dblVersion; } //read a 64-character logical name from the PX4 EEPROM. //return the name via a USB Get_Descriptor request. //The PX4 name is USB String Descriptor 3. //3 is the string number, ask for 65 bytes to get 64 CString CDppUSB::GetPX4DeviceText() { CHAR buffer[USB_BUFFER_SIZE]; UINT ret; CString strText; if (! USBDeviceReady()) { return (_T("")); } if (usb_busy) return (_T("")); while(usb_busy); usb_busy = true; ret = USBDRVD_GetStringDescriptor(USB_Device_Handle, 0x0409, 3, 65, buffer); usb_busy = false; buffer[64] = '\0'; strText = buffer; strText.Trim(); return strText; } //sends a 64-character logical name to the PX4. It will save it in EEPROM, //and return the name via a USB 'Get_Descriptor request. The PX4 name is USB String Descriptor #3. //Writing is a series of Vendor Requests, each of which writes 2 characters. // The 'Request' is 0x7F, the 'value' LSB is one character and the MSB is the subsequent one, // the 'index' is the string offset, i.e. 0, 2, 4...62. An index of 62 triggers // the firmware to copy the string into the EEPROM. void CDppUSB::SendPX4DeviceText(CString strText) { UCHAR Setting = 0x00; // no setting used UINT ret; USHORT ChOut; char ch1; char ch2; CString strTextOut; CString strSpaces(' ',65); strTextOut = strText + strSpaces; // if (! USBDeviceReady()) { return ; } if (usb_busy) return ; for(USHORT i=0; i<32 ; i++) { // 32 Requests to send 64 bytes ch1 = (char)strTextOut[i * 2]; ch2 = (char)strTextOut[(i * 2) + 1]; ChOut = (ch2 << 8) + ch1; // Req type=2 (Vendor), Dest=3 (Other), Request=&H7F (Write PX4 Name), Val=char1+char2, Index=string byte position, Len=0 while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x7F, ChOut, (USHORT)(i * 2), &Setting, 0); usb_busy = false; } return ; } void CDppUSB::SendDP5DeviceText(CString strText) { BYTE Buffer[512]; int idxCnt; long lStrLen; UINT ret; if (! USBDeviceReady()) { return ; } if (usb_busy) return ; lStrLen = strText.GetLength(); for(idxCnt=0; idxCnt<512 ; idxCnt++) { if (idxCnt < lStrLen) { Buffer[idxCnt] = (BYTE)strText[idxCnt]; } else { Buffer[idxCnt] = 0; } } for(idxCnt=0; idxCnt<16 ; idxCnt++) { //Req type=2 (Vendor), Dest=3 (Other), Request=&H7F (Write PX4 Name), Val=0, Index=0..15, Len=32 ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x7F, 0, idxCnt, &Buffer[idxCnt * 32], 32); } } CString CDppUSB::GetDP5DeviceText() { UCHAR buffer[1024]; CString strText; UINT Count; DWORD nBytes; DWORD Timeout; ULONG ret; int retries; int CurTry; for(int idxCnt=0; idxCnt<1024 ; idxCnt++) { buffer[idxCnt] = '\0'; } if (! USBDeviceReady()) { return (_T("")); } if (usb_busy) return (_T("")); //if ((PipeHandle_config == INVALID_HANDLE_VALUE)) { return (""); } // exit on bad cfg pipe ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x98, 1, 0, buffer, 0); Sleep(2); Count = 512; // dp5 text packet=512 bytes Timeout = 100; // .1 second timeout retries = 5; // 5 chances to send config CurTry = 0; // holds the current number of tries do { //Req type=2 (Vendor), Dest=3 (other), Request=&H98, Val=1 (Request text block via Pipe 3), Index=0, Len=0 ret = 0; nBytes = 0; if (usb_busy) return (_T("")); while(usb_busy); usb_busy = true; ret = USBDRVD_PipeReadTimeout(PipeHandle_configOut, buffer, (Count + COUNT_OFFSET), &nBytes, Timeout); usb_busy = false; CurTry++; //Sleep(5); } while(((nBytes != Count) || (ret == FALSE)) && (CurTry < retries)); usb_busy = false; //buffer[512] = '\0'; strText = buffer; strText.Trim(); return strText; } //USBDRVD_API ULONG _stdcall USBDRVD_VendorOrClassRequestOut(HANDLE hDevice, // UCHAR Type, // 1=class, 2 = vendor // UCHAR Destination, // 0=device, 1=interface, // // 2=endpoint, 3=other // // see the USB Specification for an explanation of the following // UCHAR Request, // request // USHORT Value, // value // USHORT Index, // index // PUCHAR pData, // data buffer // ULONG Length); // length of data //----------------------------------------------------------------------------------- //Dpp Vendor Request + 16-bit value //----------------------------------------------------------------------------------- void CDppUSB::SendGenericDppVendorRequest(UCHAR Request, USHORT Value) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, Request, Value, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //88H Clear PA0/IO0 //----------------------------------------------------------------------------------- void CDppUSB::ClearPA0IO0() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x88, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //89H Set PA0/IO0 //----------------------------------------------------------------------------------- void CDppUSB::SetPA0IO0() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x89, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //8AH Clear PA1/IO1 //----------------------------------------------------------------------------------- void CDppUSB::ClearPA1IO1() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x8A, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //8BH Set PA1/IO1 //----------------------------------------------------------------------------------- void CDppUSB::SetPA1IO1() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x8B, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //8CH Clear PA2/IO2 //----------------------------------------------------------------------------------- void CDppUSB::ClearPA2IO2() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x8C, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //8DH Set PA2/IO2 //----------------------------------------------------------------------------------- void CDppUSB::SetPA2IO2() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x8D, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //8EH Clear PA3/IO3 //----------------------------------------------------------------------------------- void CDppUSB::ClearPA3IO3() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x8E, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //8FH Set PA3/IO3 //----------------------------------------------------------------------------------- void CDppUSB::SetPA3IO3() { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x8F, 0, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //90H + 16-bit value Set Diode cal //----------------------------------------------------------------------------------- void CDppUSB::SendDiodeCal(USHORT DCalValue) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x90, DCalValue, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //91H + 16-bit value Set TEC current limit (not used on DP5) //----------------------------------------------------------------------------------- void CDppUSB::SetTECCurrentLimit(USHORT CurrentLimit) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x91, CurrentLimit, 0, buffer, 0); usb_busy = false; } } //=================================================================================== //These are new for the DP5: //----------------------------------------------------------------------------------- //92H + 16-bit value Set DP5 boot options* //----------------------------------------------------------------------------------- //*Boot options: //LSB of 16-bit value field: //D7 0 = PX4 mode (use PX4 power supply configuration bytes, report 'PX4' in status) // 1 = DP5 mode (use nonvolatile settings for HV, temp, etc; report 'DP4' in status) //D6 0 = boot in unconfigured state // 1 = use nonvolatile configuration, report 'power button config' in status //D5 0 = 57,600 baud for RS232 // 1 = 115,200 baud //D4 0 = 20MHz FPGA clock // 1 = 80MHz FPGA clock //D3 0 = positive HV PC5 required // 1 = negative HV PC5 required //D2 0 = ADC non-inverting [DP5 mode only; use 'invert' bit in PX4 mode] // 1 = ADC inverting [" "] //D1 0 = // 1 = //D0 0 = // 1 = //The MSB of the boot options is undefined so far. void CDppUSB::SetDP5BootOptions(USHORT BootOptions) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x92, BootOptions, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //93H + 16-bit value Set PC5 HV //----------------------------------------------------------------------------------- void CDppUSB::SetPC5HV(USHORT HV) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x93, HV, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //94H + 16-bit value Set PC5 TEC temperature //----------------------------------------------------------------------------------- void CDppUSB::SetPC5TECTemp(USHORT Temperature) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x94, Temperature, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //95H + 16-bit value Set DP5 input offset //----------------------------------------------------------------------------------- void CDppUSB::SetDP5InputOffset(USHORT InputOffset) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x95, InputOffset, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //96H + 16-bit value Set DP5 microcontroller ADC/Temperature calibration (TBD) //----------------------------------------------------------------------------------- void CDppUSB::SetDP5MicroAdcTempCal(USHORT MicroAdcTempCal) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x96, MicroAdcTempCal, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //97H + 16-bit value Set DP5 spectrum offset //----------------------------------------------------------------------------------- void CDppUSB::SetDP5SpectrumOffset(USHORT SpectrumOffset) { ULONG ret; UCHAR buffer[64]; while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x97, SpectrumOffset, 0, buffer, 0); usb_busy = false; } } //----------------------------------------------------------------------------------- //98H Request Digital Scope Data 20071210 //----------------------------------------------------------------------------------- void CDppUSB::RequestDigitalScopeData() { ULONG ret; UCHAR buffer[64]; if (! isDPP5) return; // Request Digital Scope Data needed for DP5 USB scope only while(usb_busy); usb_busy = true; NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); usb_busy = false; if (NumUSBDevices > 0) { while(usb_busy); usb_busy = true; ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x98, 0, 0, buffer, 0); usb_busy = false; } } ////----------------------------------------------------------------------------------- ////99H + 16-bit value TBD ////----------------------------------------------------------------------------------- //void CDppUSB::Set TBD(USHORT TBDOptions) //{ // ULONG ret; // UCHAR buffer[64]; // while(usb_busy); // usb_busy = true; // NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // usb_busy = false; // if (NumUSBDevices > 0) { // while(usb_busy); // usb_busy = true; // ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x99, TBDOptions, 0, buffer, 0); // usb_busy = false; // } //} ////----------------------------------------------------------------------------------- ////9AH + 16-bit value TBD ////----------------------------------------------------------------------------------- //void CDppUSB::Set TBD(USHORT TBDOptions) //{ // ULONG ret; // UCHAR buffer[64]; // while(usb_busy); // usb_busy = true; // NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // usb_busy = false; // if (NumUSBDevices > 0) { // while(usb_busy); // usb_busy = true; // ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x9A, TBDOptions, 0, buffer, 0); // usb_busy = false; // } //} ////----------------------------------------------------------------------------------- ////9BH + 16-bit value TBD ////----------------------------------------------------------------------------------- //void CDppUSB::Set TBD(USHORT TBDOptions) //{ // ULONG ret; // UCHAR buffer[64]; // while(usb_busy); // usb_busy = true; // NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // usb_busy = false; // if (NumUSBDevices > 0) { // while(usb_busy); // usb_busy = true; // ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x9B, TBDOptions, 0, buffer, 0); // usb_busy = false; // } //} ////----------------------------------------------------------------------------------- ////9CH + 16-bit value TBD ////----------------------------------------------------------------------------------- //void CDppUSB::Set TBD(USHORT TBDOptions) //{ // ULONG ret; // UCHAR buffer[64]; // while(usb_busy); // usb_busy = true; // NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // usb_busy = false; // if (NumUSBDevices > 0) { // while(usb_busy); // usb_busy = true; // ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x9C, TBDOptions, 0, buffer, 0); // usb_busy = false; // } //} ////----------------------------------------------------------------------------------- ////9DH + 16-bit value TBD ////----------------------------------------------------------------------------------- //void CDppUSB::Set TBD(USHORT TBDOptions) //{ // ULONG ret; // UCHAR buffer[64]; // while(usb_busy); // usb_busy = true; // NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // usb_busy = false; // if (NumUSBDevices > 0) { // while(usb_busy); // usb_busy = true; // ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x9D, TBDOptions, 0, buffer, 0); // usb_busy = false; // } //} ////----------------------------------------------------------------------------------- ////9EH + 16-bit value TBD ////----------------------------------------------------------------------------------- //void CDppUSB::Set TBD(USHORT TBDOptions) //{ // ULONG ret; // UCHAR buffer[64]; // while(usb_busy); // usb_busy = true; // NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // usb_busy = false; // if (NumUSBDevices > 0) { // while(usb_busy); // usb_busy = true; // ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x9E, TBDOptions, 0, buffer, 0); // usb_busy = false; // } //} ////----------------------------------------------------------------------------------- ////9FH + 16-bit value Save current configuration to flash memory (may or may not be necessary) ////----------------------------------------------------------------------------------- //void CDppUSB::Set SaveCfgToFlash(USHORT ConfigOptions) //{ // ULONG ret; // UCHAR buffer[64]; // while(usb_busy); // usb_busy = true; // NumUSBDevices = USBDRVD_GetDevCount(&GUID_CLASS); // usb_busy = false; // if (NumUSBDevices > 0) { // while(usb_busy); // usb_busy = true; // ret = USBDRVD_VendorOrClassRequestOut(USB_Device_Handle, 2, 3, 0x9F, ConfigOptions, 0, buffer, 0); // usb_busy = false; // } //} ////===================================================================================