mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
Format source code using clang-format
This commit is contained in:
@@ -6,311 +6,360 @@
|
||||
#include "PoKeys55.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
//HIDscaner: http://forum.simflight.com/topic/68257-latest-lua-package-for-fsuipc-and-wideclient/
|
||||
// HIDscaner: http://forum.simflight.com/topic/68257-latest-lua-package-for-fsuipc-and-wideclient/
|
||||
//#define MY_DEVICE_ID "Vid_04d8&Pid_003F"
|
||||
//#define MY_DEVICE_ID "Vid_1dc3&Pid_1001&Rev_1000&MI_01"
|
||||
//HID\Vid_1dc3&Pid_1001&Rev_1000&MI_01 - MI_01 to jest interfejs komunikacyjny (00-joystick, 02-klawiatura)
|
||||
// HID\Vid_1dc3&Pid_1001&Rev_1000&MI_01 - MI_01 to jest interfejs komunikacyjny (00-joystick,
|
||||
// 02-klawiatura)
|
||||
|
||||
HANDLE WriteHandle=INVALID_HANDLE_VALUE;
|
||||
HANDLE ReadHandle =INVALID_HANDLE_VALUE;
|
||||
//GUID InterfaceClassGuid={0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30};
|
||||
HANDLE WriteHandle = INVALID_HANDLE_VALUE;
|
||||
HANDLE ReadHandle = INVALID_HANDLE_VALUE;
|
||||
// GUID InterfaceClassGuid={0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30};
|
||||
//{4d1e55b2-f16f-11cf-88cb-001111000030}
|
||||
|
||||
__fastcall TPoKeys55::TPoKeys55()
|
||||
{
|
||||
cRequest=0;
|
||||
iPWMbits=1;
|
||||
iFaza=0;
|
||||
iLastCommand=0;
|
||||
fAnalog[0]=fAnalog[1]=fAnalog[2]=fAnalog[3]=fAnalog[4]=fAnalog[5]=fAnalog[6]=-1.0;
|
||||
iPWM[0]=iPWM[1]=iPWM[2]=iPWM[3]=iPWM[4]=iPWM[5]=iPWM[6]=0;
|
||||
iPWM[7]=4096;
|
||||
iInputs[0]=0; //czy normalnie s¹ w stanie wysokim?
|
||||
iRepeats=0;
|
||||
bNoError=true;
|
||||
cRequest = 0;
|
||||
iPWMbits = 1;
|
||||
iFaza = 0;
|
||||
iLastCommand = 0;
|
||||
fAnalog[0] = fAnalog[1] = fAnalog[2] = fAnalog[3] = fAnalog[4] = fAnalog[5] = fAnalog[6] = -1.0;
|
||||
iPWM[0] = iPWM[1] = iPWM[2] = iPWM[3] = iPWM[4] = iPWM[5] = iPWM[6] = 0;
|
||||
iPWM[7] = 4096;
|
||||
iInputs[0] = 0; // czy normalnie s¹ w stanie wysokim?
|
||||
iRepeats = 0;
|
||||
bNoError = true;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
__fastcall TPoKeys55::~TPoKeys55()
|
||||
{
|
||||
Close();
|
||||
};
|
||||
__fastcall TPoKeys55::~TPoKeys55() { Close(); };
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::Close()
|
||||
{//roz³¹czenie komunikacji
|
||||
if (WriteHandle!=INVALID_HANDLE_VALUE)
|
||||
CloseHandle(WriteHandle);
|
||||
WriteHandle=INVALID_HANDLE_VALUE;
|
||||
if (ReadHandle!=INVALID_HANDLE_VALUE)
|
||||
CloseHandle(ReadHandle);
|
||||
ReadHandle=INVALID_HANDLE_VALUE;
|
||||
{ // roz³¹czenie komunikacji
|
||||
if (WriteHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(WriteHandle);
|
||||
WriteHandle = INVALID_HANDLE_VALUE;
|
||||
if (ReadHandle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(ReadHandle);
|
||||
ReadHandle = INVALID_HANDLE_VALUE;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::Connect()
|
||||
{//Ra: to jest do wyczyszcznia z niepotrzebnych zmiennych i komunikatów
|
||||
Close();
|
||||
GUID InterfaceClassGuid={0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}; //wszystkie HID tak maj¹
|
||||
HDEVINFO DeviceInfoTable;
|
||||
PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure=new SP_DEVICE_INTERFACE_DATA;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure=new SP_DEVICE_INTERFACE_DETAIL_DATA;
|
||||
SP_DEVINFO_DATA DevInfoData;
|
||||
DWORD InterfaceIndex=0;
|
||||
//DWORD StatusLastError=0;
|
||||
DWORD dwRegType;
|
||||
DWORD dwRegSize;
|
||||
DWORD StructureSize=0;
|
||||
PBYTE PropertyValueBuffer;
|
||||
bool MatchFound;
|
||||
DWORD ErrorStatus;
|
||||
HDEVINFO hDevInfo;
|
||||
String DeviceIDFromRegistry;
|
||||
String DeviceIDToFind="Vid_1dc3&Pid_1001&Rev_1000&MI_01";
|
||||
//First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID.
|
||||
DeviceInfoTable=SetupDiGetClassDevs(&InterfaceClassGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
|
||||
//Now look through the list we just populated. We are trying to see if any of them match our device.
|
||||
while (true)
|
||||
{
|
||||
InterfaceDataStructure->cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
if (SetupDiEnumDeviceInterfaces(DeviceInfoTable, NULL, &InterfaceClassGuid, InterfaceIndex, InterfaceDataStructure))
|
||||
{
|
||||
ErrorStatus=GetLastError();
|
||||
if (ERROR_NO_MORE_ITEMS==ErrorStatus) //Did we reach the end of the list of matching devices in the DeviceInfoTable?
|
||||
{//Cound not find the device. Must not have been attached.
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
//ShowMessage("Erreur: Sortie1");
|
||||
{ // Ra: to jest do wyczyszcznia z niepotrzebnych zmiennych i komunikatów
|
||||
Close();
|
||||
GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00,
|
||||
0x11, 0x11, 0x00, 0x00, 0x30}; // wszystkie HID tak maj¹
|
||||
HDEVINFO DeviceInfoTable;
|
||||
PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure =
|
||||
new SP_DEVICE_INTERFACE_DETAIL_DATA;
|
||||
SP_DEVINFO_DATA DevInfoData;
|
||||
DWORD InterfaceIndex = 0;
|
||||
// DWORD StatusLastError=0;
|
||||
DWORD dwRegType;
|
||||
DWORD dwRegSize;
|
||||
DWORD StructureSize = 0;
|
||||
PBYTE PropertyValueBuffer;
|
||||
bool MatchFound;
|
||||
DWORD ErrorStatus;
|
||||
HDEVINFO hDevInfo;
|
||||
String DeviceIDFromRegistry;
|
||||
String DeviceIDToFind = "Vid_1dc3&Pid_1001&Rev_1000&MI_01";
|
||||
// First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the
|
||||
// specified class GUID.
|
||||
DeviceInfoTable =
|
||||
SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||
// Now look through the list we just populated. We are trying to see if any of them match our
|
||||
// device.
|
||||
while (true)
|
||||
{
|
||||
InterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
if (SetupDiEnumDeviceInterfaces(DeviceInfoTable, NULL, &InterfaceClassGuid, InterfaceIndex,
|
||||
InterfaceDataStructure))
|
||||
{
|
||||
ErrorStatus = GetLastError();
|
||||
if (ERROR_NO_MORE_ITEMS == ErrorStatus) // Did we reach the end of the list of matching
|
||||
// devices in the DeviceInfoTable?
|
||||
{ // Cound not find the device. Must not have been attached.
|
||||
SetupDiDestroyDeviceInfoList(
|
||||
DeviceInfoTable); // Clean up the old structure we no longer need.
|
||||
// ShowMessage("Erreur: Sortie1");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // Else some other kind of unknown error ocurred...
|
||||
{
|
||||
ErrorStatus = GetLastError();
|
||||
SetupDiDestroyDeviceInfoList(
|
||||
DeviceInfoTable); // Clean up the old structure we no longer need.
|
||||
// ShowMessage("Erreur: Sortie2");
|
||||
return false;
|
||||
}
|
||||
// Now retrieve the hardware ID from the registry. The hardware ID contains the VID and PID,
|
||||
// which we will then
|
||||
// check to see if it is the correct device or not.
|
||||
// Initialize an appropriate SP_DEVINFO_DATA structure. We need this structure for
|
||||
// SetupDiGetDeviceRegistryProperty().
|
||||
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
||||
SetupDiEnumDeviceInfo(DeviceInfoTable, InterfaceIndex, &DevInfoData);
|
||||
// First query for the size of the hardware ID, so we can know how big a buffer to allocate
|
||||
// for the data.
|
||||
SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID,
|
||||
&dwRegType, NULL, 0, &dwRegSize);
|
||||
// Allocate a buffer for the hardware ID.
|
||||
// PropertyValueBuffer=(BYTE*)malloc(dwRegSize);
|
||||
PropertyValueBuffer = new char[dwRegSize];
|
||||
if (PropertyValueBuffer == NULL) // if null,error,couldn't allocate enough memory
|
||||
{ // Can't really recover from this situation,just exit instead.
|
||||
// ShowMessage("Allocation PropertyValueBuffer impossible");
|
||||
SetupDiDestroyDeviceInfoList(
|
||||
DeviceInfoTable); // Clean up the old structure we no longer need.
|
||||
return false;
|
||||
}
|
||||
// Retrieve the hardware IDs for the current device we are looking at. PropertyValueBuffer
|
||||
// gets filled with a
|
||||
// REG_MULTI_SZ (array of null terminated strings). To find a device,we only care about the
|
||||
// very first string in the
|
||||
// buffer,which will be the "device ID". The device ID is a string which contains the VID
|
||||
// and PID,in the example
|
||||
// format "Vid_04d8&Pid_003f".
|
||||
SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID,
|
||||
&dwRegType, PropertyValueBuffer, dwRegSize, NULL);
|
||||
// Now check if the first string in the hardware ID matches the device ID of my USB device.
|
||||
// ListBox1->Items->Add((char*)PropertyValueBuffer);
|
||||
DeviceIDFromRegistry = StrPas((char *)PropertyValueBuffer);
|
||||
// free(PropertyValueBuffer); //No longer need the PropertyValueBuffer,free the memory to
|
||||
// prevent potential memory leaks
|
||||
delete PropertyValueBuffer; // No longer need the PropertyValueBuffer,free the memory to
|
||||
// prevent potential memory leaks
|
||||
// Convert both strings to lower case. This makes the code more robust/portable accross OS
|
||||
// Versions
|
||||
DeviceIDFromRegistry = DeviceIDFromRegistry.LowerCase();
|
||||
DeviceIDToFind = DeviceIDToFind.LowerCase();
|
||||
// Now check if the hardware ID we are looking at contains the correct VID/PID
|
||||
MatchFound = (DeviceIDFromRegistry.AnsiPos(DeviceIDToFind) > 0);
|
||||
if (MatchFound == true)
|
||||
{
|
||||
// Device must have been found. Open read and write handles. In order to do this,we
|
||||
// will need the actual device path first.
|
||||
// We can get the path by calling SetupDiGetDeviceInterfaceDetail(),however,we have to
|
||||
// call this function twice: The first
|
||||
// time to get the size of the required structure/buffer to hold the detailed interface
|
||||
// data,then a second time to actually
|
||||
// get the structure (after we have allocated enough memory for the structure.)
|
||||
DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
// First call populates "StructureSize" with the correct value
|
||||
SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, InterfaceDataStructure, NULL, NULL,
|
||||
&StructureSize, NULL);
|
||||
DetailedInterfaceDataStructure =
|
||||
(PSP_DEVICE_INTERFACE_DETAIL_DATA)(malloc(StructureSize)); // Allocate enough memory
|
||||
if (DetailedInterfaceDataStructure ==
|
||||
NULL) // if null,error,couldn't allocate enough memory
|
||||
{ // Can't really recover from this situation,just exit instead.
|
||||
SetupDiDestroyDeviceInfoList(
|
||||
DeviceInfoTable); // Clean up the old structure we no longer need.
|
||||
return false;
|
||||
}
|
||||
DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
// Now call SetupDiGetDeviceInterfaceDetail() a second time to receive the goods.
|
||||
SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, InterfaceDataStructure,
|
||||
DetailedInterfaceDataStructure, StructureSize, NULL,
|
||||
NULL);
|
||||
// We now have the proper device path,and we can finally open read and write handles to
|
||||
// the device.
|
||||
// We store the handles in the global variables "WriteHandle" and "ReadHandle",which we
|
||||
// will use later to actually communicate.
|
||||
WriteHandle = CreateFile((DetailedInterfaceDataStructure->DevicePath), GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
||||
ErrorStatus = GetLastError();
|
||||
// if (ErrorStatus==ERROR_SUCCESS)
|
||||
// ToggleLedBtn->Enabled=true;//Make button no longer greyed out
|
||||
ReadHandle = CreateFile((DetailedInterfaceDataStructure->DevicePath), GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
|
||||
ErrorStatus = GetLastError();
|
||||
if (ErrorStatus == ERROR_SUCCESS)
|
||||
{
|
||||
// GetPushbuttonState->Enabled=true;//Make button no longer greyed out
|
||||
// StateLabel->Enabled=true;//Make label no longer greyed out
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(
|
||||
DeviceInfoTable); // Clean up the old structure we no longer need.
|
||||
iRepeats = 0; // nowe szanse na pod³¹czenie
|
||||
return true;
|
||||
}
|
||||
InterfaceIndex++;
|
||||
// Keep looping until we either find a device with matching VID and PID,or until we run out
|
||||
// of items.
|
||||
} // end of while(true)
|
||||
// ShowMessage("Sortie");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else //Else some other kind of unknown error ocurred...
|
||||
{
|
||||
ErrorStatus=GetLastError();
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
//ShowMessage("Erreur: Sortie2");
|
||||
return false;
|
||||
}
|
||||
//Now retrieve the hardware ID from the registry. The hardware ID contains the VID and PID, which we will then
|
||||
//check to see if it is the correct device or not.
|
||||
//Initialize an appropriate SP_DEVINFO_DATA structure. We need this structure for SetupDiGetDeviceRegistryProperty().
|
||||
DevInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
|
||||
SetupDiEnumDeviceInfo(DeviceInfoTable,InterfaceIndex,&DevInfoData);
|
||||
//First query for the size of the hardware ID, so we can know how big a buffer to allocate for the data.
|
||||
SetupDiGetDeviceRegistryProperty(DeviceInfoTable,&DevInfoData,SPDRP_HARDWAREID,&dwRegType,NULL,0,&dwRegSize);
|
||||
//Allocate a buffer for the hardware ID.
|
||||
//PropertyValueBuffer=(BYTE*)malloc(dwRegSize);
|
||||
PropertyValueBuffer=new char[dwRegSize];
|
||||
if (PropertyValueBuffer==NULL) //if null,error,couldn't allocate enough memory
|
||||
{//Can't really recover from this situation,just exit instead.
|
||||
//ShowMessage("Allocation PropertyValueBuffer impossible");
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
return false;
|
||||
}
|
||||
//Retrieve the hardware IDs for the current device we are looking at. PropertyValueBuffer gets filled with a
|
||||
//REG_MULTI_SZ (array of null terminated strings). To find a device,we only care about the very first string in the
|
||||
//buffer,which will be the "device ID". The device ID is a string which contains the VID and PID,in the example
|
||||
//format "Vid_04d8&Pid_003f".
|
||||
SetupDiGetDeviceRegistryProperty(DeviceInfoTable,&DevInfoData,SPDRP_HARDWAREID,&dwRegType,PropertyValueBuffer,dwRegSize,NULL);
|
||||
//Now check if the first string in the hardware ID matches the device ID of my USB device.
|
||||
//ListBox1->Items->Add((char*)PropertyValueBuffer);
|
||||
DeviceIDFromRegistry=StrPas((char*)PropertyValueBuffer);
|
||||
//free(PropertyValueBuffer); //No longer need the PropertyValueBuffer,free the memory to prevent potential memory leaks
|
||||
delete PropertyValueBuffer; //No longer need the PropertyValueBuffer,free the memory to prevent potential memory leaks
|
||||
//Convert both strings to lower case. This makes the code more robust/portable accross OS Versions
|
||||
DeviceIDFromRegistry=DeviceIDFromRegistry.LowerCase();
|
||||
DeviceIDToFind=DeviceIDToFind.LowerCase();
|
||||
//Now check if the hardware ID we are looking at contains the correct VID/PID
|
||||
MatchFound=(DeviceIDFromRegistry.AnsiPos(DeviceIDToFind)>0);
|
||||
if (MatchFound==true)
|
||||
{
|
||||
//Device must have been found. Open read and write handles. In order to do this,we will need the actual device path first.
|
||||
//We can get the path by calling SetupDiGetDeviceInterfaceDetail(),however,we have to call this function twice: The first
|
||||
//time to get the size of the required structure/buffer to hold the detailed interface data,then a second time to actually
|
||||
//get the structure (after we have allocated enough memory for the structure.)
|
||||
DetailedInterfaceDataStructure->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
//First call populates "StructureSize" with the correct value
|
||||
SetupDiGetDeviceInterfaceDetail(DeviceInfoTable,InterfaceDataStructure,NULL,NULL,&StructureSize,NULL);
|
||||
DetailedInterfaceDataStructure=(PSP_DEVICE_INTERFACE_DETAIL_DATA)(malloc(StructureSize)); //Allocate enough memory
|
||||
if (DetailedInterfaceDataStructure==NULL) //if null,error,couldn't allocate enough memory
|
||||
{//Can't really recover from this situation,just exit instead.
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
return false;
|
||||
}
|
||||
DetailedInterfaceDataStructure->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
//Now call SetupDiGetDeviceInterfaceDetail() a second time to receive the goods.
|
||||
SetupDiGetDeviceInterfaceDetail(DeviceInfoTable,InterfaceDataStructure,DetailedInterfaceDataStructure,StructureSize,NULL,NULL);
|
||||
//We now have the proper device path,and we can finally open read and write handles to the device.
|
||||
//We store the handles in the global variables "WriteHandle" and "ReadHandle",which we will use later to actually communicate.
|
||||
WriteHandle=CreateFile((DetailedInterfaceDataStructure->DevicePath),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0);
|
||||
ErrorStatus=GetLastError();
|
||||
//if (ErrorStatus==ERROR_SUCCESS)
|
||||
// ToggleLedBtn->Enabled=true;//Make button no longer greyed out
|
||||
ReadHandle=CreateFile((DetailedInterfaceDataStructure->DevicePath),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0);
|
||||
ErrorStatus=GetLastError();
|
||||
if (ErrorStatus==ERROR_SUCCESS)
|
||||
{
|
||||
//GetPushbuttonState->Enabled=true;//Make button no longer greyed out
|
||||
//StateLabel->Enabled=true;//Make label no longer greyed out
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
iRepeats=0; //nowe szanse na pod³¹czenie
|
||||
return true;
|
||||
}
|
||||
InterfaceIndex++;
|
||||
//Keep looping until we either find a device with matching VID and PID,or until we run out of items.
|
||||
}//end of while(true)
|
||||
//ShowMessage("Sortie");
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::Write(unsigned char c,unsigned char b3,unsigned char b4,unsigned char b5)
|
||||
bool __fastcall TPoKeys55::Write(unsigned char c, unsigned char b3, unsigned char b4,
|
||||
unsigned char b5)
|
||||
{
|
||||
DWORD BytesWritten=0;
|
||||
OutputBuffer[0]=0; //The first byte is the "Report ID" and does not get transmitted over the USB bus. Always set=0.
|
||||
OutputBuffer[1]=0xBB; //0xBB - bajt rozpoznawczy dla PoKeys55
|
||||
OutputBuffer[2]=iLastCommand=c; //operacja: 0x31: blokowy odczyt wejϾ
|
||||
OutputBuffer[3]=b3; //np. numer pinu (o 1 mniej ni¿ numer na p³ytce)
|
||||
OutputBuffer[4]=b4;
|
||||
OutputBuffer[5]=b5;
|
||||
OutputBuffer[6]=0;
|
||||
OutputBuffer[7]=++cRequest; //numer ¿¹dania
|
||||
OutputBuffer[8]=0;
|
||||
for (int i=0;i<8;++i)
|
||||
OutputBuffer[8]+=OutputBuffer[i]; //czy sumowaæ te¿ od 9 do 64?
|
||||
//The basic Windows I/O functions WriteFile() and ReadFile() can be used to read and write to HID class USB devices
|
||||
//(once we have the read and write handles to the device, which are obtained with CreateFile()).
|
||||
//The following call to WriteFile() sends 64 bytes of data to the USB device.
|
||||
WriteFile(WriteHandle,&OutputBuffer,65,&BytesWritten,0); //Blocking function, unless an "overlapped" structure is used
|
||||
return (BytesWritten==65);
|
||||
//Read(); //odczyt trzeba zrobiæ inaczej - w tym miejscu bêdzie za szybko i nic siê nie odczyta
|
||||
DWORD BytesWritten = 0;
|
||||
OutputBuffer[0] = 0; // The first byte is the "Report ID" and does not get transmitted over the
|
||||
// USB bus. Always set=0.
|
||||
OutputBuffer[1] = 0xBB; // 0xBB - bajt rozpoznawczy dla PoKeys55
|
||||
OutputBuffer[2] = iLastCommand = c; // operacja: 0x31: blokowy odczyt wejϾ
|
||||
OutputBuffer[3] = b3; // np. numer pinu (o 1 mniej ni¿ numer na p³ytce)
|
||||
OutputBuffer[4] = b4;
|
||||
OutputBuffer[5] = b5;
|
||||
OutputBuffer[6] = 0;
|
||||
OutputBuffer[7] = ++cRequest; // numer ¿¹dania
|
||||
OutputBuffer[8] = 0;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
OutputBuffer[8] += OutputBuffer[i]; // czy sumowaæ te¿ od 9 do 64?
|
||||
// The basic Windows I/O functions WriteFile() and ReadFile() can be used to read and write to
|
||||
// HID class USB devices
|
||||
//(once we have the read and write handles to the device, which are obtained with CreateFile()).
|
||||
// The following call to WriteFile() sends 64 bytes of data to the USB device.
|
||||
WriteFile(WriteHandle, &OutputBuffer, 65, &BytesWritten,
|
||||
0); // Blocking function, unless an "overlapped" structure is used
|
||||
return (BytesWritten == 65);
|
||||
// Read(); //odczyt trzeba zrobiæ inaczej - w tym miejscu bêdzie za szybko i nic siê nie odczyta
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool __fastcall TPoKeys55::Read()
|
||||
{
|
||||
DWORD BytesRead=0;
|
||||
InputBuffer[0]=0; //The first byte is the "Report ID" and does not get transmitted over the USB bus. Always set=0.
|
||||
//Now get the response packet from the firmware.
|
||||
//The following call to ReadFIle() retrieves 64 bytes of data from the USB device.
|
||||
ReadFile(ReadHandle,&InputBuffer,65,&BytesRead,0); //Blocking function,unless an "overlapped" structure is used
|
||||
//InputPacketBuffer[0] is the report ID, which we don't care about.
|
||||
//InputPacketBuffer[1] is an echo back of the command.
|
||||
//InputPacketBuffer[2] contains the I/O port pin value for the pushbutton.
|
||||
return (BytesRead==65)?InputBuffer[7]==cRequest:false;
|
||||
DWORD BytesRead = 0;
|
||||
InputBuffer[0] = 0; // The first byte is the "Report ID" and does not get transmitted over the
|
||||
// USB bus. Always set=0.
|
||||
// Now get the response packet from the firmware.
|
||||
// The following call to ReadFIle() retrieves 64 bytes of data from the USB device.
|
||||
ReadFile(ReadHandle, &InputBuffer, 65, &BytesRead,
|
||||
0); // Blocking function,unless an "overlapped" structure is used
|
||||
// InputPacketBuffer[0] is the report ID, which we don't care about.
|
||||
// InputPacketBuffer[1] is an echo back of the command.
|
||||
// InputPacketBuffer[2] contains the I/O port pin value for the pushbutton.
|
||||
return (BytesRead == 65) ? InputBuffer[7] == cRequest : false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::ReadLoop(int i)
|
||||
{//próbuje odczytaæ (i) razy
|
||||
do
|
||||
{if (Read()) return true;
|
||||
Sleep(1); //trochê poczekaæ, a¿ odpowie
|
||||
}
|
||||
while (--i);
|
||||
return false;
|
||||
{ // próbuje odczytaæ (i) razy
|
||||
do
|
||||
{
|
||||
if (Read())
|
||||
return true;
|
||||
Sleep(1); // trochê poczekaæ, a¿ odpowie
|
||||
} while (--i);
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
AnsiString __fastcall TPoKeys55::Version()
|
||||
{//zwraca numer wersji, funkcja nieoptymalna czasowo (czeka na odpowiedŸ)
|
||||
if (!WriteHandle) return "";
|
||||
Write(0x00,0); //0x00 - Read serial number, version
|
||||
if (ReadLoop(10))
|
||||
{//3: serial MSB; 4: serial LSB; 5: software version (v(1+[4-7]).([0-3])); 6: revision number
|
||||
AnsiString s="PoKeys55 #"+AnsiString((InputBuffer[3]<<8)+InputBuffer[4]);
|
||||
s+=" v"+AnsiString(1+(InputBuffer[5]>>4))+"."+AnsiString(InputBuffer[5]&15)+"."+AnsiString(InputBuffer[6]);
|
||||
/* //Ra: pozyskiwanie daty mo¿na sobie darowaæ, jest poniek¹d bez sensu
|
||||
Write(0x04,0); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
{//2: 0x04; 3-6: char 1-4, 5-8, 9-11; (83-65-112-32-32-49-32-50-48-49-49-0=="Sep 1 2011")
|
||||
s+=" ("+AnsiString((char*)InputBuffer+3,4);
|
||||
Write(0x04,1); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
{s+=AnsiString((char*)InputBuffer+3,4);
|
||||
Write(0x04,2); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
s+=AnsiString((char*)InputBuffer+3,3);
|
||||
}
|
||||
s+=")";
|
||||
}
|
||||
*/
|
||||
return s;
|
||||
}
|
||||
return "";
|
||||
{ // zwraca numer wersji, funkcja nieoptymalna czasowo (czeka na odpowiedŸ)
|
||||
if (!WriteHandle)
|
||||
return "";
|
||||
Write(0x00, 0); // 0x00 - Read serial number, version
|
||||
if (ReadLoop(10))
|
||||
{ // 3: serial MSB; 4: serial LSB; 5: software version (v(1+[4-7]).([0-3])); 6: revision number
|
||||
AnsiString s = "PoKeys55 #" + AnsiString((InputBuffer[3] << 8) + InputBuffer[4]);
|
||||
s += " v" + AnsiString(1 + (InputBuffer[5] >> 4)) + "." + AnsiString(InputBuffer[5] & 15) +
|
||||
"." + AnsiString(InputBuffer[6]);
|
||||
/* //Ra: pozyskiwanie daty mo¿na sobie darowaæ, jest poniek¹d bez sensu
|
||||
Write(0x04,0); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c
|
||||
kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
{//2: 0x04; 3-6: char 1-4, 5-8, 9-11; (83-65-112-32-32-49-32-50-48-49-49-0=="Sep 1 2011")
|
||||
s+=" ("+AnsiString((char*)InputBuffer+3,4);
|
||||
Write(0x04,1); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c
|
||||
kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
{s+=AnsiString((char*)InputBuffer+3,4);
|
||||
Write(0x04,2); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c
|
||||
kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
s+=AnsiString((char*)InputBuffer+3,3);
|
||||
}
|
||||
s+=")";
|
||||
}
|
||||
*/
|
||||
return s;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
bool __fastcall TPoKeys55::PWM(int x,float y)
|
||||
{//ustawienie wskazanego PWM (@12Mhz: 12000=1ms=1000Hz)
|
||||
//iPWM[7]=1024; //1024==85333.3333333333ns=11718.75Hz
|
||||
iPWM[x]=int(0.5f+0x0FFF*y)&0x0FFF; //0x0FFF=4095
|
||||
return true;
|
||||
bool __fastcall TPoKeys55::PWM(int x, float y)
|
||||
{ // ustawienie wskazanego PWM (@12Mhz: 12000=1ms=1000Hz)
|
||||
// iPWM[7]=1024; //1024==85333.3333333333ns=11718.75Hz
|
||||
iPWM[x] = int(0.5f + 0x0FFF * y) & 0x0FFF; // 0x0FFF=4095
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __fastcall TPoKeys55::Update(bool pause)
|
||||
{//funkcja powinna byæ wywo³ywana regularnie, np. raz w ka¿dej ramce ekranowej
|
||||
if (pause)
|
||||
{//specjalna procedura, jeœli utracone po³¹czenie spowodowa³o pauzê
|
||||
iLastCommand=0; //po³¹czenie zosta³o na nowo otwarte
|
||||
//iFaza=0; //jeden b³¹d i podtrzymanie pauzy jest kontynuowane
|
||||
}
|
||||
switch (iFaza)
|
||||
{case 0: //uaktualnienie PWM raz na jakiœ czas
|
||||
OutputBuffer[9]=0x3F; //maska u¿ytych PWM
|
||||
*((int*)(OutputBuffer+10))=iPWM[0]; //PWM1 (pin 22)
|
||||
*((int*)(OutputBuffer+14))=iPWM[1]; //PWM2 (pin 21)
|
||||
*((int*)(OutputBuffer+18))=iPWM[2]; //PWM3 (pin 20)
|
||||
*((int*)(OutputBuffer+22))=iPWM[3]; //PWM4 (pin 19)
|
||||
*((int*)(OutputBuffer+26))=iPWM[4]; //PWM5 (pin 18)
|
||||
*((int*)(OutputBuffer+30))=iPWM[5]; //PWM6 (pin 17)
|
||||
*((int*)(OutputBuffer+34))=iPWM[7]; //PWM period
|
||||
if (Write(0xCB,1)) //wys³anie ustawieñ (1-ustaw, 0-odczyt)
|
||||
iRepeats=0; //informacja, ¿e posz³o dobrze
|
||||
++iFaza; //ta faza zosta³a zakoñczona
|
||||
//iRepeats=0;
|
||||
break;
|
||||
case 1: //odczyt wejϾ analogowych - komenda i przetwarzanie
|
||||
if (iLastCommand!=0x3A) //asynchroniczne ustawienie kontrolki mo¿e namieszaæ
|
||||
Write(0x3A,0); //0x3A - Analog inputs reading – all analog inputs in one command
|
||||
else if (Read())
|
||||
{//jest odebrana ramka i zgodnoœæ numeru ¿¹dania
|
||||
fAnalog[0]=((InputBuffer[21]<<8)+InputBuffer[22])/4095.0f; //pin 47
|
||||
fAnalog[1]=((InputBuffer[19]<<8)+InputBuffer[20])/4095.0f; //pin 46
|
||||
fAnalog[2]=((InputBuffer[17]<<8)+InputBuffer[18])/4095.0f; //pin 45
|
||||
fAnalog[3]=((InputBuffer[15]<<8)+InputBuffer[16])/4095.0f; //pin 44
|
||||
fAnalog[4]=((InputBuffer[13]<<8)+InputBuffer[14])/4095.0f; //pin 43
|
||||
fAnalog[5]=((InputBuffer[11]<<8)+InputBuffer[12])/4095.0f; //pin 42
|
||||
fAnalog[6]=((InputBuffer[ 9]<<8)+InputBuffer[10])/4095.0f; //pin 41
|
||||
++iFaza; //skoro odczytano, mo¿na przejœæ do kolejnej fazy
|
||||
iRepeats=0; //zerowanie licznika prób
|
||||
}
|
||||
else ++iRepeats; //licznik nieudanych prób
|
||||
break;
|
||||
case 2: //odczyt wejϾ cyfrowych - komenda i przetwarzanie
|
||||
if (iLastCommand!=0x31) //asynchroniczne ustawienie kontrolki mo¿e namieszaæ
|
||||
Write(0x31,0); //0x31: blokowy odczyt wejϾ
|
||||
else if (Read())
|
||||
{//jest odebrana ramka i zgodnoœæ numeru ¿¹dania
|
||||
iInputs[0]=*((int*)(InputBuffer+3)); //odczyt 32 bitów
|
||||
iFaza=3; //skoro odczytano, mo¿na kolejny cykl
|
||||
iRepeats=0; //zerowanie licznika prób
|
||||
}
|
||||
else ++iRepeats; //licznik nieudanych prób
|
||||
break;
|
||||
case 3: //ustawienie wyjœæ analogowych, 0..4095 mapowaæ na 0..65520 (<<4)
|
||||
if (Write(0x41,43-1,(iPWM[6]>>4),(iPWM[6]<<4))) //wys³anie ustawieñ
|
||||
iRepeats=0; //informacja, ¿e posz³o dobrze
|
||||
iFaza=0; //++iFaza; //ta faza zosta³a zakoñczona
|
||||
//powinno jeszcze przyjϾ potwierdzenie o kodzie 0x41
|
||||
break;
|
||||
default:
|
||||
iFaza=0; //na wypadek, gdyby zb³¹dzi³o po jakichœ zmianach w kodzie
|
||||
//iRepeats=0;
|
||||
}
|
||||
if (!iRepeats)
|
||||
bNoError=true; //jest OK
|
||||
else if (iRepeats>=10) //youBy 2014-07: przy 5 powtórzeniach sieje mi pauz¹ po 2 razy na sekundê, a przy 10 jest ok
|
||||
{//przekroczenie liczby prób wymusza kolejn¹ fazê
|
||||
++iFaza;
|
||||
iRepeats=1; //w nowej fazie nowe szanse, ale nie od 0!
|
||||
bNoError=false; //zg³osiæ b³¹d
|
||||
}
|
||||
return (bNoError); //true oznacza prawid³owe dzia³anie
|
||||
//czy w przypadku b³êdu komunikacji z PoKeys w³¹czaæ pauzê?
|
||||
//dopiero poprawne pod³¹czenie zeruje licznik prób
|
||||
{ // funkcja powinna byæ wywo³ywana regularnie, np. raz w ka¿dej ramce ekranowej
|
||||
if (pause)
|
||||
{ // specjalna procedura, jeœli utracone po³¹czenie spowodowa³o pauzê
|
||||
iLastCommand = 0; // po³¹czenie zosta³o na nowo otwarte
|
||||
// iFaza=0; //jeden b³¹d i podtrzymanie pauzy jest kontynuowane
|
||||
}
|
||||
switch (iFaza)
|
||||
{
|
||||
case 0: // uaktualnienie PWM raz na jakiœ czas
|
||||
OutputBuffer[9] = 0x3F; // maska u¿ytych PWM
|
||||
*((int *)(OutputBuffer + 10)) = iPWM[0]; // PWM1 (pin 22)
|
||||
*((int *)(OutputBuffer + 14)) = iPWM[1]; // PWM2 (pin 21)
|
||||
*((int *)(OutputBuffer + 18)) = iPWM[2]; // PWM3 (pin 20)
|
||||
*((int *)(OutputBuffer + 22)) = iPWM[3]; // PWM4 (pin 19)
|
||||
*((int *)(OutputBuffer + 26)) = iPWM[4]; // PWM5 (pin 18)
|
||||
*((int *)(OutputBuffer + 30)) = iPWM[5]; // PWM6 (pin 17)
|
||||
*((int *)(OutputBuffer + 34)) = iPWM[7]; // PWM period
|
||||
if (Write(0xCB, 1)) // wys³anie ustawieñ (1-ustaw, 0-odczyt)
|
||||
iRepeats = 0; // informacja, ¿e posz³o dobrze
|
||||
++iFaza; // ta faza zosta³a zakoñczona
|
||||
// iRepeats=0;
|
||||
break;
|
||||
case 1: // odczyt wejϾ analogowych - komenda i przetwarzanie
|
||||
if (iLastCommand != 0x3A) // asynchroniczne ustawienie kontrolki mo¿e namieszaæ
|
||||
Write(0x3A, 0); // 0x3A - Analog inputs reading – all analog inputs in one command
|
||||
else if (Read())
|
||||
{ // jest odebrana ramka i zgodnoœæ numeru ¿¹dania
|
||||
fAnalog[0] = ((InputBuffer[21] << 8) + InputBuffer[22]) / 4095.0f; // pin 47
|
||||
fAnalog[1] = ((InputBuffer[19] << 8) + InputBuffer[20]) / 4095.0f; // pin 46
|
||||
fAnalog[2] = ((InputBuffer[17] << 8) + InputBuffer[18]) / 4095.0f; // pin 45
|
||||
fAnalog[3] = ((InputBuffer[15] << 8) + InputBuffer[16]) / 4095.0f; // pin 44
|
||||
fAnalog[4] = ((InputBuffer[13] << 8) + InputBuffer[14]) / 4095.0f; // pin 43
|
||||
fAnalog[5] = ((InputBuffer[11] << 8) + InputBuffer[12]) / 4095.0f; // pin 42
|
||||
fAnalog[6] = ((InputBuffer[9] << 8) + InputBuffer[10]) / 4095.0f; // pin 41
|
||||
++iFaza; // skoro odczytano, mo¿na przejœæ do kolejnej fazy
|
||||
iRepeats = 0; // zerowanie licznika prób
|
||||
}
|
||||
else
|
||||
++iRepeats; // licznik nieudanych prób
|
||||
break;
|
||||
case 2: // odczyt wejϾ cyfrowych - komenda i przetwarzanie
|
||||
if (iLastCommand != 0x31) // asynchroniczne ustawienie kontrolki mo¿e namieszaæ
|
||||
Write(0x31, 0); // 0x31: blokowy odczyt wejϾ
|
||||
else if (Read())
|
||||
{ // jest odebrana ramka i zgodnoœæ numeru ¿¹dania
|
||||
iInputs[0] = *((int *)(InputBuffer + 3)); // odczyt 32 bitów
|
||||
iFaza = 3; // skoro odczytano, mo¿na kolejny cykl
|
||||
iRepeats = 0; // zerowanie licznika prób
|
||||
}
|
||||
else
|
||||
++iRepeats; // licznik nieudanych prób
|
||||
break;
|
||||
case 3: // ustawienie wyjœæ analogowych, 0..4095 mapowaæ na 0..65520 (<<4)
|
||||
if (Write(0x41, 43 - 1, (iPWM[6] >> 4), (iPWM[6] << 4))) // wys³anie ustawieñ
|
||||
iRepeats = 0; // informacja, ¿e posz³o dobrze
|
||||
iFaza = 0; //++iFaza; //ta faza zosta³a zakoñczona
|
||||
// powinno jeszcze przyjϾ potwierdzenie o kodzie 0x41
|
||||
break;
|
||||
default:
|
||||
iFaza = 0; // na wypadek, gdyby zb³¹dzi³o po jakichœ zmianach w kodzie
|
||||
// iRepeats=0;
|
||||
}
|
||||
if (!iRepeats)
|
||||
bNoError = true; // jest OK
|
||||
else if (iRepeats >= 10) // youBy 2014-07: przy 5 powtórzeniach sieje mi pauz¹ po 2 razy na
|
||||
// sekundê, a przy 10 jest ok
|
||||
{ // przekroczenie liczby prób wymusza kolejn¹ fazê
|
||||
++iFaza;
|
||||
iRepeats = 1; // w nowej fazie nowe szanse, ale nie od 0!
|
||||
bNoError = false; // zg³osiæ b³¹d
|
||||
}
|
||||
return (bNoError); // true oznacza prawid³owe dzia³anie
|
||||
// czy w przypadku b³êdu komunikacji z PoKeys w³¹czaæ pauzê?
|
||||
// dopiero poprawne pod³¹czenie zeruje licznik prób
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user