Нужна версия PureBasic 5.20 и выше.
Код модуля.
DeclareModule HID ;-DeclareModule Structure HID_CAPS Usage.w UsagePage.w InputReportByteLength.w OutputReportByteLength.w FeatureReportByteLength.w Reserved.w[17] NumberLinkCollectionNodes.w NumberInputButtonCaps.w NumberInputValueCaps.w NumberInputDataIndices.w NumberOutputButtonCaps.w NumberOutputValueCaps.w NumberOutputDataIndices.w NumberFeatureButtonCaps.w NumberFeatureValueCaps.w NumberFeatureDataIndices.w EndStructure Structure HID_Sub_DeviceInfo VendorID.u ProductID.u VersionNumber.u NumInputBuffers.u InputReportByteLength.u OutputReportByteLength.u FeatureReportByteLength.u Manufacturer.s Product.s SerialNumber.s EndStructure Structure HID_DeviceInfo CountDevice.w ; Число обнаруженных HID устройств DeviceInfo.HID_Sub_DeviceInfo[258] EndStructure Structure HID_Attributes VID.u PID.u VersionNumber.u EndStructure Declare HID_Init() Declare HID_End() Declare OpenDevice(PID.u, VID.u, VersionNumber.w=-1, Index.u=0) Declare CloseDevice(hDevice) Declare TestDevice(PID.u, VID.u, VersionNumber.w=-1, Index.u=0) Declare DeviceInfo(*Info.HID_DeviceInfo) Declare ReadDevice(hDevice, *Buffer, Len) Declare WriteDevice(hDevice, *Buffer, Len) Declare GetFeature(hDevice, *Buffer, Len) Declare SetFeature(hDevice, *Buffer, Len) Declare GetInputReport(hDevice, *Buffer, Len) Declare SetOutputReport(hDevice, *Buffer, Len) Declare GetCaps(hDevice, *Capabilities.HID_CAPS) ; Узнаём по хендлу устройства, его PID, VID и номер версии. Declare GetAttributes(hDevice, *DeviceInfo.HID_Attributes) Declare GetNumInputBuffers(hDevice) Declare.s GetManufacturerString(hDevice) Declare.s GetProductString(hDevice) Declare.s GetSerialNumberString(hDevice) Declare.s GetIndexedString(hDevice, Index) EndDeclareModule Module HID Structure HIDD_ATTRIBUTES Size.l VendorID.u ProductID.u VersionNumber.w EndStructure Structure PSP_DEVICE_INTERFACE_DETAIL_DATA cbSize.l CompilerIf #PB_Compiler_Processor = #PB_Processor_x64 DevicePath.l CompilerElse DevicePath.c CompilerEndIf EndStructure CompilerIf Defined(SP_DEVICE_INTERFACE_DATA, #PB_Structure)=0 Structure SP_DEVICE_INTERFACE_DATA cbSize.l InterfaceClassGuid.GUID Flags.l Reserved.l EndStructure CompilerEndIf EnableExplicit Define.i Prototype pGetHidGuid(*HidGuid.GUID) Prototype pGetAttributes(*HidDeviceObject, *Attributes.HIDD_ATTRIBUTES) Prototype pGetPreparsedData(*HidDeviceObject, *PreparsedData) Prototype pGetCaps(*PreparsedData, *Capabilities.HID_CAPS) Prototype pFreePreparsedData(PreparsedData) Prototype pGetNumInputBuffers(HidHandle, *NumInputBuffers) Prototype pGetManufacturerString(HidHandle, *Buffer, Len) Prototype pGetProductString(HidHandle, *Buffer, Len) Prototype pGetSerialNumberString(HidHandle, *Buffer, Len) Prototype pGetIndexedString(HidHandle, Index, *Buffer, Len) Prototype pGetFeature(HidHandle, *Buffer, Len) Prototype pSetFeature(HidHandle, *Buffer, Len) Prototype pGetInputReport(HidHandle, *Buffer, Len) Prototype pSetOutputReport(HidHandle, *Buffer, Len) Prototype pSetupDiEnumDeviceInterfaces(*DeviceInfoSet, DeviceInfoData, *InterfaceClassGuid.GUID, MemberIndex, *DeviceInterfaceData.SP_DEVICE_INTERFACE_DATA) Prototype pSetupDiGetDeviceInterfaceDetail(*DeviceInfoSet, *DeviceInterfaceData.SP_DEVICE_INTERFACE_DATA, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize, *RequiredSize, *DeviceInfoData) Define hid_Lib, Setupapi_Lib, OS_Version Procedure HID_Init() Shared hid_Lib, Setupapi_Lib, OS_Version OS_Version = OSVersion() hid_Lib=LoadLibrary_("hid.dll") Setupapi_Lib=LoadLibrary_("setupapi.dll") Global fGetHidGuid.pGetHidGuid=GetProcAddress_(hid_Lib, ?GetHidGuid) Global fGetAttributes.pGetAttributes=GetProcAddress_(hid_Lib, ?GetAttributes) Global fGetPreparsedData.pGetPreparsedData=GetProcAddress_(hid_Lib, ?GetPreparsedData) Global fFreePreparsedData.pFreePreparsedData=GetProcAddress_(hid_Lib, ?FreePreparsedData) Global fGetCaps.pGetCaps=GetProcAddress_(hid_Lib, ?GetCaps) Global fGetInputReport.pGetInputReport=GetProcAddress_(hid_Lib, ?GetInputReport) Global fSetOutputReport.pSetOutputReport=GetProcAddress_(hid_Lib, ?SetOutputReport) Global fGetFeature.pGetFeature=GetProcAddress_(hid_Lib, ?GetFeature) Global fSetFeature.pSetFeature=GetProcAddress_(hid_Lib, ?SetFeature) Global fGetNumInputBuffers.pGetNumInputBuffers=GetProcAddress_(hid_Lib, ?GetNumInputBuffers) Global fGetManufacturerString.pGetManufacturerString=GetProcAddress_(hid_Lib, ?GetManufacturerString) Global fGetProductString.pGetProductString=GetProcAddress_(hid_Lib, ?GetProductString) Global fGetSerialNumberString.pGetSerialNumberString=GetProcAddress_(hid_Lib, ?GetSerialNumberString) Global fGetIndexedString.pGetIndexedString=GetProcAddress_(hid_Lib, ?GetIndexedString) Global fSetupDiEnumDeviceInterfaces.pSetupDiEnumDeviceInterfaces=GetProcAddress_(Setupapi_Lib, ?SetupDiEnumDeviceInterfaces) Global fSetupDiGetDeviceInterfaceDetail.pSetupDiGetDeviceInterfaceDetail=GetProcAddress_(Setupapi_Lib, ?Setup_InterfaceDetail) DataSection GetHidGuid: ! db "HidD_GetHidGuid", 0, 0 GetAttributes: ! db "HidD_GetAttributes", 0, 0 GetPreparsedData: ! db "HidD_GetPreparsedData", 0, 0 FreePreparsedData: ! db "HidD_FreePreparsedData", 0, 0 GetCaps: ! db "HidP_GetCaps", 0, 0 GetInputReport: ! db "HidD_GetInputReport", 0, 0 SetOutputReport: ! db "HidD_SetOutputReport", 0, 0 GetFeature: ! db "HidD_GetFeature", 0, 0 SetFeature: ! db "HidD_SetFeature", 0, 0 GetNumInputBuffers: ! db "HidD_GetNumInputBuffers", 0, 0 GetManufacturerString: ! db "HidD_GetManufacturerString", 0, 0 GetProductString: ! db "HidD_GetProductString", 0, 0 GetSerialNumberString: ! db "HidD_GetSerialNumberString", 0, 0 GetIndexedString: ! db "HidD_GetIndexedString", 0, 0 SetupDiEnumDeviceInterfaces: ! db "SetupDiEnumDeviceInterfaces", 0, 0 Setup_InterfaceDetail: CompilerIf #PB_Compiler_Unicode=0 ! db "SetupDiGetDeviceInterfaceDetailA", 0, 0 CompilerElse ! db "SetupDiGetDeviceInterfaceDetailW", 0, 0 CompilerEndIf EndDataSection EndProcedure Procedure HID_End() Shared hid_Lib, Setupapi_Lib If hid_Lib FreeLibrary_(hid_Lib) EndIf If Setupapi_Lib FreeLibrary_(Setupapi_Lib) EndIf EndProcedure Procedure FunctInfo(hDevice, *Info.HID_DeviceInfo) Protected Attributes.HIDD_ATTRIBUTES, i Protected HIDP_CAPS.HID_CAPS Attributes\Size = SizeOf(HIDD_ATTRIBUTES) If fGetAttributes(hDevice, @Attributes) i = *Info\CountDevice *Info\CountDevice+1 *Info\DeviceInfo[i]\VendorID = Attributes\VendorID *Info\DeviceInfo[i]\ProductID = Attributes\ProductID *Info\DeviceInfo[i]\VersionNumber = Attributes\VersionNumber *Info\DeviceInfo[i]\Manufacturer = GetManufacturerString(hDevice) *Info\DeviceInfo[i]\Product = GetProductString(hDevice) *Info\DeviceInfo[i]\SerialNumber = GetSerialNumberString(hDevice) *Info\DeviceInfo[i]\NumInputBuffers = GetNumInputBuffers(hDevice) GetCaps(hDevice, @HIDP_CAPS) *Info\DeviceInfo[i]\InputReportByteLength = HIDP_CAPS\InputReportByteLength *Info\DeviceInfo[i]\OutputReportByteLength = HIDP_CAPS\OutputReportByteLength *Info\DeviceInfo[i]\FeatureReportByteLength = HIDP_CAPS\FeatureReportByteLength EndIf EndProcedure ; Получение доступа к HID устройству Procedure Open_HID_Device(PID.u, VID.u, VersionNumber.w=-1, Index.u=0, *Funct=0, *Info.HID_DeviceInfo=0) Protected HidGuid.Guid Protected devInfoData.SP_DEVICE_INTERFACE_DATA Protected Attributes.HIDD_ATTRIBUTES, Security.SECURITY_ATTRIBUTES Protected *detailData.PSP_DEVICE_INTERFACE_DETAIL_DATA Protected Length.l, CurrentIndex.w, hDevInfo Protected i, Result, DevicePath.s Protected Required, hDevice If fGetHidGuid=0 Or fSetupDiEnumDeviceInterfaces=0 Or fSetupDiGetDeviceInterfaceDetail=0 Or fGetAttributes=0 ProcedureReturn 0 EndIf devInfoData\cbSize = SizeOf(SP_DEVICE_INTERFACE_DATA) Security\nLength=SizeOf(SECURITY_ATTRIBUTES) Security\bInheritHandle=1 Security\lpSecurityDescriptor = 0 fGetHidGuid(@HidGuid) hDevInfo=SetupDiGetClassDevs_(@HidGuid,0,0, #DIGCF_PRESENT|#DIGCF_DEVICEINTERFACE) If hDevInfo=0 ProcedureReturn 0 EndIf For i=0 To 255 Result=fSetupDiEnumDeviceInterfaces(hDevInfo, 0, @HidGuid, i, @devInfoData) If Result Result = fSetupDiGetDeviceInterfaceDetail(hDevInfo, @devInfoData, 0, 0,@Length, 0) *detailData=AllocateMemory(Length) *detailData\cbSize=SizeOf(PSP_DEVICE_INTERFACE_DETAIL_DATA) Result = fSetupDiGetDeviceInterfaceDetail(hDevInfo, @devInfoData, *detailData, Length+1, @Required, 0) DevicePath.s=PeekS(@*detailData\DevicePath) FreeMemory(*detailData) hDevice=CreateFile_(@DevicePath, #GENERIC_READ|#GENERIC_WRITE, #FILE_SHARE_READ|#FILE_SHARE_WRITE, @Security, #OPEN_EXISTING, 0, 0) If hDevice<>#INVALID_HANDLE_VALUE If *Funct And *Info CallFunctionFast(*Funct, hDevice, *Info) CloseHandle_(hDevice) Else Attributes\Size = SizeOf(HIDD_ATTRIBUTES) Result = fGetAttributes(hDevice, @Attributes) If Attributes\ProductID=PID And Attributes\VendorID=VID And (Attributes\VersionNumber=VersionNumber Or VersionNumber=-1 ) If CurrentIndex=Index SetupDiDestroyDeviceInfoList_(hDevInfo) ProcedureReturn hDevice Else CurrentIndex+1 CloseHandle_(hDevice) EndIf Else CloseHandle_(hDevice) EndIf EndIf EndIf Else Break EndIf Next i SetupDiDestroyDeviceInfoList_(hDevInfo) ProcedureReturn 0 EndProcedure Procedure OpenDevice(PID.u, VID.u, VersionNumber.w=-1, Index.u=0) ProcedureReturn Open_HID_Device(PID, VID, VersionNumber, Index, 0, 0) EndProcedure Procedure CloseDevice(hDevice) ; Закрытие HID устройства. If hDevice ProcedureReturn CloseHandle_(hDevice) Else ProcedureReturn 0 EndIf EndProcedure Procedure TestDevice(PID.u, VID.u, VersionNumber.w=-1, Index.u=0) Protected hHid.i, Result hHid=OpenDevice(PID, VID, VersionNumber, Index) If hHid CloseDevice(hHid) Result=#True Else Result=#False EndIf ProcedureReturn Result EndProcedure Procedure DeviceInfo(*Info.HID_DeviceInfo) If *Info ClearStructure(*Info, HID_DeviceInfo) Open_HID_Device(0, 0, 0, 0, @FunctInfo(), *Info) ProcedureReturn Bool(*Info\CountDevice>0) EndIf EndProcedure Procedure ReadDevice(hDevice, *Buffer, Len) ; Чтение данных из HID устройства Protected Written.l=0 If hDevice=0 Or *Buffer=0 Or Len<=0 ProcedureReturn 0 EndIf ReadFile_(hDevice, *Buffer, Len, @Written, 0) ProcedureReturn Written EndProcedure Procedure WriteDevice(hDevice, *Buffer, Len) ; Запись данных в HID устройство Protected Written.l=0 If hDevice=0 Or *Buffer=0 Or Len<=0 ProcedureReturn 0 EndIf WriteFile_(hDevice, *Buffer, Len, @Written, 0) ProcedureReturn Written EndProcedure Procedure GetFeature(hDevice, *Buffer, Len) If hDevice And *Buffer And Len>0 And fGetFeature ProcedureReturn fGetFeature(hDevice, *Buffer, Len) Else ProcedureReturn 0 EndIf EndProcedure Procedure SetFeature(hDevice, *Buffer, Len) If hDevice And *Buffer And Len>0 And fSetFeature ProcedureReturn fSetFeature(hDevice, *Buffer, Len) Else ProcedureReturn 0 EndIf EndProcedure ; Чтение входного репорта. ВНИМАНИЕ функция появилась только в WinXP Procedure GetInputReport(hDevice, *Buffer, Len) Shared OS_Version If hDevice And *buffer And Len>0 And OS_Version>=#PB_OS_Windows_XP And fGetInputReport ProcedureReturn fGetInputReport(hDevice, *Buffer, Len) Else ProcedureReturn 0 EndIf EndProcedure ; Запись в устройство выходного репорта. ВНИМАНИЕ функция появилась только в WinXP Procedure SetOutputReport(hDevice, *Buffer, Len) Shared OS_Version If hDevice And *buffer And Len>0 And OS_Version>=#PB_OS_Windows_XP And fSetOutputReport ProcedureReturn fSetOutputReport(hDevice, *Buffer, Len) Else ProcedureReturn 0 EndIf EndProcedure Procedure GetCaps(hDevice, *Capabilities.HID_CAPS) ; Узнаём размеры буферов и др. информацию об устройстве Protected result=0, PreparsedData If hDevice And fGetPreparsedData And fGetCaps And fFreePreparsedData If fGetPreparsedData(hDevice, @PreparsedData) fGetCaps(PreparsedData, *Capabilities) fFreePreparsedData(PreparsedData) result=1 EndIf EndIf ProcedureReturn result EndProcedure ; Узнаём по хендлу устройства, его PID, VID и номер версии. Procedure GetAttributes(hDevice, *DeviceInfo.HID_Attributes) Protected Info.HIDD_ATTRIBUTES, Result=#False If hDevice And *DeviceInfo And fGetAttributes Info\Size = SizeOf(HIDD_ATTRIBUTES) If fGetAttributes(hDevice, @Info) CopyMemory(@Info+OffsetOf(HIDD_ATTRIBUTES\VendorID), *DeviceInfo, SizeOf(HID_Attributes)) Result=#True EndIf EndIf ProcedureReturn Result EndProcedure Procedure GetNumInputBuffers(hDevice) Protected NumInputBuffers=0 If hDevice And fGetNumInputBuffers fGetNumInputBuffers(hDevice, @NumInputBuffers) EndIf ProcedureReturn NumInputBuffers EndProcedure Procedure.s GetManufacturerString(hDevice) ; Получаем идентификатор изготовителя Protected Result.s="", *mem If hDevice And fGetManufacturerString *mem=AllocateMemory(256) If *mem If fGetManufacturerString(hDevice, *mem, 252) Result=PeekS(*mem,-1,#PB_Unicode) EndIf FreeMemory(*mem) EndIf EndIf ProcedureReturn Result EndProcedure Procedure.s GetProductString(hDevice) ; Получаем идентификатор продукта Protected Result.s="", *mem If hDevice And fGetProductString *mem=AllocateMemory(256) If *mem If fGetProductString(hDevice, *mem, 252) Result=PeekS(*mem,-1,#PB_Unicode) EndIf FreeMemory(*mem) EndIf EndIf ProcedureReturn Result EndProcedure Procedure.s GetSerialNumberString(hDevice) ; Получаем серийный номер продукта Protected Result.s="", *mem If hDevice And fGetSerialNumberString *mem=AllocateMemory(256) If *mem If fGetSerialNumberString(hDevice, *mem, 252) Result=PeekS(*mem,-1,#PB_Unicode) EndIf FreeMemory(*mem) EndIf EndIf ProcedureReturn Result EndProcedure Procedure.s GetIndexedString(hDevice, Index) ; Чтение строки по её индексу из устройства Protected Result.s="", *mem If hDevice And fGetIndexedString *mem=AllocateMemory(256) If *mem If fGetIndexedString(hDevice, Index, *mem, 252) Result=PeekS(*mem,-1,#PB_Unicode) EndIf FreeMemory(*mem) EndIf EndIf ProcedureReturn Result EndProcedure EndModule
Примеры использования модуля.
Проверка наличия устройства с идентификаторами PID=1 и VID=$1234.
Код:#USB_PID=1 #USB_VID=$1234 XIncludeFile "HID_Module.pbi" Procedure Timer1() If HID::TestDevice(#USB_PID, #USB_VID)=1 SetGadgetText(1,"Устройство подключено") SetGadgetColor(1,#PB_Gadget_FrontColor,$92616D) Else SetGadgetText(1,"Устройство отсутствует") SetGadgetColor(1,#PB_Gadget_FrontColor,$0000FF) EndIf EndProcedure HID::HID_Init() OpenWindow(0,0,0,280,100,"HID_Lib_DeviceTest",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) TextGadget(0,40,10,200,16,"PID - "+Hex(#USB_PID)+"H; VID - "+Hex(#USB_VID)+"H",#PB_Text_Center ) TextGadget(1,80,40,200,16,"") Timer1() AddWindowTimer(0, 1, 500) Repeat Event=WaitWindowEvent() If Event=#PB_Event_Timer If EventTimer()=1 Timer1() EndIf EndIf Until Event = #PB_Event_CloseWindow HID::HID_End()Информация об всех HID устройствах.
Код:XIncludeFile "HID_Module.pbi" Procedure HID_DeviceInfo() ClearGadgetItems(0) Info.HID::HID_DeviceInfo If HID::DeviceInfo(@Info) If Info\CountDevice>0 For i=0 To Info\CountDevice-1 AddGadgetItem(0,i,Info\DeviceInfo[i]\Manufacturer) SetGadgetItemText(0,i,Info\DeviceInfo[i]\Product,1) SetGadgetItemText(0,i,Hex(Info\DeviceInfo[i]\ProductID,#PB_Word)+"H",2) SetGadgetItemText(0,i,Hex(Info\DeviceInfo[i]\VendorID,#PB_Word)+"H",3) SetGadgetItemText(0,i,Hex(Info\DeviceInfo[i]\VersionNumber,#PB_Word)+"H",4) SetGadgetItemText(0,i,Info\DeviceInfo[i]\SerialNumber,5) SetGadgetItemText(0,i,Str(Info\DeviceInfo[i]\NumInputBuffers),6) SetGadgetItemText(0,i,Str(Info\DeviceInfo[i]\InputReportByteLength),7) SetGadgetItemText(0,i,Str(Info\DeviceInfo[i]\OutputReportByteLength),8) SetGadgetItemText(0,i,Str(Info\DeviceInfo[i]\FeatureReportByteLength),9) Next i EndIf EndIf EndProcedure HID::HID_Init() OpenWindow(0,0,0,930,294,"Иформация о USB HID устройствах",#PB_Window_MinimizeGadget|#PB_Window_Invisible|#PB_Window_ScreenCentered) ListIconGadget(0,2,2,924,290,"Изготовитель",100,#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect) AddGadgetColumn(0,1,"Продукт",100) AddGadgetColumn(0,2,"PID",48) AddGadgetColumn(0,3,"VID",48) AddGadgetColumn(0,4,"Номер версии",90) AddGadgetColumn(0,5,"Серийный номер",104) AddGadgetColumn(0,6,"Число вх. буферов",110) AddGadgetColumn(0,7,"Размер вх. репорта",120) AddGadgetColumn(0,8,"Размер вых. репорта",124) AddGadgetColumn(0,9,"FEATURE",70) HID_DeviceInfo() HideWindow(0,0) AddWindowTimer(0, 1, 400) Repeat Event=WaitWindowEvent() If Event=#PB_Event_Timer If EventTimer()=1 HID_DeviceInfo() EndIf EndIf Until Event = #PB_Event_CloseWindow HID::HID_End()Два примера отсюда. http://pure-basic.narod.ru/article/pickit2.html
Код:#USB_PID = $33 ; Идентификаторы программатора PicKit2. #USB_VID = $4D8 #END_OF_BUFFER = $AD ; Этим заполняется пустое пространство в буфере. #PACKET_SIZE = 65 ; Размер HID репорта программатора. XIncludeFile "HID_Module.pbi" Procedure VddOn(Handle) ; Включить питание Dim OutBuffer.a(#PACKET_SIZE+2) FillMemory(@OutBuffer()+1, #PACKET_SIZE, #END_OF_BUFFER, #PB_Byte) ; Заполнение массива, данными из константы #END_OF_BUFFER OutBuffer(0)=0 OutBuffer(1)=$A6 ; EXECUTE_SCRIPT OutBuffer(2)=2 OutBuffer(3)=$FC ; _VDD_GND_OFF OutBuffer(4)=$FF ; _VDD_ON ProcedureReturn HID::WriteDevice(Handle, @OutBuffer(), #PACKET_SIZE) ; Передача данных в программатор PICkit2 EndProcedure Procedure VddOff(Handle) ; Выключить питание Dim OutBuffer.a(#PACKET_SIZE+2) FillMemory(@OutBuffer()+1, #PACKET_SIZE, #END_OF_BUFFER, #PB_Byte) ; Заполнение массива, данными из константы #END_OF_BUFFER OutBuffer(0)=0 OutBuffer(1)=$A6 ; EXECUTE_SCRIPT OutBuffer(2)=2 OutBuffer(3)=$FE ; _VDD_OFF OutBuffer(4)=$FD ; _VDD_GND_ON ProcedureReturn HID::WriteDevice(Handle, @OutBuffer(), #PACKET_SIZE) ; Передача данных в программатор PICkit2 EndProcedure HID::HID_Init() Handle=HID::OpenDevice(#USB_PID, #USB_VID) ; Установка связи с PicKit2 If Handle VddOn(Handle) ; Включить питание Delay(2000) ; Пауза 2 секунды VddOff(Handle) ; Выключить питание HID::CloseDevice(Handle) ; Разрыв связи с PicKit2 Else MessageRequester("", "Нет связи с PicKit2!", 48) EndIf HID::HID_End()Код:#USB_PID = $33 ; Идентификаторы программатора PicKit2. #USB_VID = $4D8 #END_OF_BUFFER = $AD ; Этим заполняеся пустое просторанство в буфере. #PACKET_SIZE = 65 ; Размер HID репорта программатора. #NO_Device = "Нет связи с PicKit2" XIncludeFile "HID_Module.pbi" Procedure.u Read_Status(Handle) ; Чтение состояния программатора PicKit2. ; Data[1] = Status Low ; <7> unused ; <6> 1 = PICkit 2 button pressed ; <5> 1 = VppError (Vpp < Vfault) ; <4> 1 = VddError (Vdd < Vfault) ; <3> 1 = Vpp On ; <2> 1 = Vpp GND On ; <1> 1 = Vdd On ; <0> 1 = Vdd GND On ; Data[2] = Status High ; <7> 1 = Download Buffer Overflow ; <6> 1 = Script Buffer Overflow, invalid ; Script length Or index ; <5> 1 = Run Script on Empty Script ; <4> 1 = Script abort- download empty ; <3> 1 = Script abort- upload full ; <2> 1 = ICD transfer timeout/Bus Error ; <1> 1 = UART Mode enabled ; <0> 1 = PICkit 2 reset since last ; Status Read. ; NOTE: Turns BUSY_LED off. St.u=0 ; Переменная типа Unicode (беззнаковая, 2 байта) Dim InBuffer.a(#PACKET_SIZE+2) ; Массив, использующися как буфер приёма от PICkit2. Dim OutBuffer.a(#PACKET_SIZE+2) ; Массив, использующися как буфер передачи в PICkit2. FillMemory(@OutBuffer()+1, #PACKET_SIZE, #END_OF_BUFFER, #PB_Byte) ; Заполнение массива, данными из константы #END_OF_BUFFER. OutBuffer(0)=0 OutBuffer(1)=$A2 ; READ_STATUS If HID::WriteDevice(Handle, @OutBuffer(), #PACKET_SIZE) = #PACKET_SIZE ; Передача данных в программатор PICkit2. If HID::ReadDevice(Handle, @InBuffer(), #PACKET_SIZE) = #PACKET_SIZE ; Чтение данных из программатора PICkit2. CopyMemory(@InBuffer()+1, @St, 2) ; Копирование данных из массива в переменную. EndIf EndIf ProcedureReturn St EndProcedure Procedure Timer1() ; Эта процедура вызывается по таймеру, каждые 100 мс. Shared Handle Static Old_Test Test=HID::TestDevice(#USB_PID, #USB_VID) ; Есть ли требуемое USB HID устройство? If Test<>Old_Test Old_Test=Test If Test HID::CloseDevice(Handle) Handle=HID::OpenDevice(#USB_PID, #USB_VID) ; Подключение к USB HID устройству. SetGadgetText(0,"PicKit2 подключён") Else HID::CloseDevice(Handle) ; Разрыв связи с USB HID устройством. Handle=0 SetGadgetText(0,#NO_Device) SetGadgetText(2,"НЕТ") EndIf EndIf If Test=1 ; Программатор подключён PICkit2 и нормально работает. Status.u=Read_Status(Handle) ; Получаем данные о статусе программатора If Status & %01000000 >0 ; и выделяем данные о состоянии кнопки. SetGadgetText(2,"ДА") Else SetGadgetText(2,"НЕТ") EndIf EndIf EndProcedure HID::HID_Init() ; Открываем окно OpenWindow(0,0,0,140,80,"PICkit2",#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered) TextGadget(0,2,2,140,16, #NO_Device, #PB_Text_Center) ; Здесь отображается полключён ли PicKit2. TextGadget(1,10,40,80,16,"Нажата кнопка") TextGadget(2,100,40,40,16,"НЕТ") ; Здесь отображается состояние кнопки. SetGadgetColor(2, #PB_Gadget_FrontColor, $FD0402) AddWindowTimer(0,1,100) ; Запуск таймера с периодом 100 мс. Repeat ; Начало главного цикла Event=WaitWindowEvent() If Event=#PB_Event_Timer And EventTimer()=1 ; Сработал таймер. Timer1() EndIf Until Event=#PB_Event_CloseWindow ; Событие закрытия окна - прерываем цикл. HID::HID_End()Пример отсюда. Простое USB HID устройство на ATmega8.
Код:#USB_PID=1 #USB_VID=$1234 Global W_DeviceHandle=0, R_DeviceHandle=0 XIncludeFile "HID_Module.pbi" Procedure FindDevice_Timer() Static Old_Test Test=HID::TestDevice(#USB_PID, #USB_VID) If Test<>Old_Test Old_Test=Test If Test HID::CloseDevice(W_DeviceHandle) HID::CloseDevice(R_DeviceHandle) W_DeviceHandle=HID::OpenDevice(#USB_PID, #USB_VID) R_DeviceHandle=HID::OpenDevice(#USB_PID, #USB_VID) SetGadgetText(1,"Подключено HID устройство") Else HID::CloseDevice(W_DeviceHandle) HID::CloseDevice(R_DeviceHandle) W_DeviceHandle=0 : R_DeviceHandle=0 SetGadgetText(1,"Устройство не обнаруженно ( PID — "+Hex(#USB_PID)+"H; VID — "+Hex(#USB_VID)+"H) ") SetGadgetText(5,"Нет") EndIf EndIf EndProcedure Procedure SendDevice(Command.w) If W_DeviceHandle HID::WriteDevice(W_DeviceHandle, @Command,2) Else MessageRequester("", "Нет связи с устройством!", #MB_OK|#MB_ICONWARNING) EndIf EndProcedure Procedure Thread(*xx) Dim InBuffer.b(2) Repeat If R_DeviceHandle HID::ReadDevice(R_DeviceHandle, @InBuffer(), 2) If InBuffer(1)=20 SetGadgetText(5,"Да") ElseIf InBuffer(1)=40 SetGadgetText(5,"Нет") EndIf EndIf Delay(10) ForEver EndProcedure HID::HID_Init() OpenWindow(0,0,0,320,100,"Пример работы с HID устройством",#PB_Window_MinimizeGadget|#PB_Window_Invisible|#PB_Window_ScreenCentered) TextGadget(1,10,10,300,16,"Устройство не обнаруженно ( PID — "+Hex(#USB_PID)+"H; VID — "+Hex(#USB_VID)+"H )",#PB_Text_Center) ButtonGadget(2,40,70,120,24,"Зажечь светодиод") ButtonGadget(3,170,70,120,24,"Погасить светодиод") TextGadget(4,50,40,98,16,"Кнопка нажата?") StringGadget(5,140,36,40,20,"Нет",1|#PB_String_ReadOnly) FindDevice_Timer() HideWindow(0,0) SetTimer_(WindowID(0),1,200,@FindDevice_Timer()) CreateThread(@Thread(),0) Repeat Event=WaitWindowEvent() If Event=#PB_Event_Gadget Select EventGadget() Case 2 SendDevice($AA00) Case 3 SendDevice($5500) EndSelect EndIf Until Event=#PB_Event_CloseWindow HID::HID_End()Пример отсюда. USB термометр на ATmega8 и PIC18F4550
Код:#USB_PID=$EF04 #USB_VID=$AAAA #NO_Device="Нет связи с термометром" LoadFont(2,"Arial",22,#PB_Font_Bold) XIncludeFile "HID_Module.pbi" Procedure FindDevice_Timer() ; Периодическая (каждые 400 мс.) проверка доступности термометра Shared DeviceHandle Static Old_Test Test=HID::TestDevice(#USB_PID, #USB_VID) ; Есть ли требуемое USB HID устройство? If Test<>Old_Test Old_Test=Test If Test HID::CloseDevice(DeviceHandle) DeviceHandle=HID::OpenDevice(#USB_PID, #USB_VID) ; Подключение к USB HID устройству SetGadgetText(0,"Термометр подключён") Else HID::CloseDevice(DeviceHandle) ; Разрыв связи с USB HID устройством DeviceHandle=0 SetGadgetText(0,#NO_Device) SetGadgetText(1,"OFF") EndIf EndIf EndProcedure Procedure Thread(*x) ; Эта процедура работает в отдельном потоке Shared DeviceHandle Dim In.c(4) ; Байтовый массив, используемый как бцфер приёма данных. Temp.w ; Переменная типа Word. Repeat If DeviceHandle ; Установлена ли связь с USB термометром? In(0)=0 HID::ReadDevice(DeviceHandle, @In(), 3) ; Чтение данных из USB термометра Temp=In(2) Temp<<8 ; Сдвиг влево на 8 пизиций Temp | In(1) Result.f=Temp/16 If Result<150 And Result>-58 ; Отсеиваем возможные глюки! SetGadgetText(1,StrF(Result,1)+" °C") ; Отображение температуры в окне EndIf EndIf Delay(100) ForEver EndProcedure HID::HID_Init() ; Открываем окно OpenWindow(0,0,0,170,70,"USB_Termo", #PB_Window_MinimizeGadget|#PB_Window_Invisible|#PB_Window_ScreenCentered) StickyWindow(0,1) TextGadget(0,4,4,162,16,#NO_Device,#PB_Text_Center) StringGadget(1,16,24,140,40,"OFF",#PB_Text_Center|#PB_String_ReadOnly) SetGadgetFont(1,FontID(2)) SetGadgetColor(1,#PB_Gadget_FrontColor,$DF0000) FindDevice_Timer() HideWindow(0,0) AddWindowTimer(0,1,400) ; Запуск таймера CreateThread(@Thread(),0) ; Создание отдельного потока из процедуры Thread() Repeat ; Главный цикл проги Repeat - Until Event=WaitWindowEvent() ; Идентификатор события If Event=#PB_Event_Timer If EventTimer()=1 FindDevice_Timer() ; Вызов процедуры по таймеру, каждые 400 мс. EndIf EndIf Until Event=#PB_Event_CloseWindow ; Прерывание главного цикла при закрытии окна HID::HID_End()HID_Tester.
Код:; PureBasic Visual Designer v3.95 build 1485 (PB4Code) ;- Window Constants ; Enumeration #Main_Window EndEnumeration ;- Gadget Constants ; Enumeration #Text_Device_list #ListIcon_Device #Text_Log #Button_Start #Button_Stop #Text_Selected_device #String_Selected_device #Container_Data #Option_Random #Option_SelectData #CheckBox_ReadDevice_State = #Option_SelectData + 17 #Text_Pause #String_Pause #Editor_Log #Button_UpdateDeviceList EndEnumeration XIncludeFile "HID_Module.pbi" Structure Thread_Device_IO_Info ReadDevice_State.b Pause.l DeviceInfo.HID::HID_CAPS RandomState.b Bytes.u[10] EndStructure Global PID_Device.u, VID_Device.u, VersionNumber_Device.u, DeviceHandle=0 Thread_Device_Info.Thread_Device_IO_Info Procedure HID_DeviceInfo(*x) Protected HID_Info.HID::HID_DeviceInfo Protected Hid_Count=0 If HID::DeviceInfo(@HID_Info) If HID_Info\CountDevice>0 And Hid_Count<>HID_Info\CountDevice Hid_Count=HID_Info\CountDevice ClearGadgetItems(#ListIcon_Device) For i=0 To HID_Info\CountDevice-1 AddGadgetItem(#ListIcon_Device,i,HID_Info\DeviceInfo[i]\Product) SetGadgetItemText(#ListIcon_Device,i,Hex(HID_Info\DeviceInfo[i]\ProductID,#PB_Unicode)+"H",1) SetGadgetItemText(#ListIcon_Device,i,Str(HID_Info\DeviceInfo[i]\ProductID),7) SetGadgetItemText(#ListIcon_Device,i,Hex(HID_Info\DeviceInfo[i]\VendorID,#PB_Unicode)+"H",2) SetGadgetItemText(#ListIcon_Device,i,Str(HID_Info\DeviceInfo[i]\VendorID),8) SetGadgetItemText(#ListIcon_Device,i,Hex(HID_Info\DeviceInfo[i]\VersionNumber,#PB_Unicode)+"H",3) SetGadgetItemText(#ListIcon_Device,i,Str(HID_Info\DeviceInfo[i]\VersionNumber),9) SetGadgetItemText(#ListIcon_Device,i,Str(HID_Info\DeviceInfo[i]\InputReportByteLength),4) SetGadgetItemText(#ListIcon_Device,i,Str(HID_Info\DeviceInfo[i]\OutputReportByteLength),5) SetGadgetItemText(#ListIcon_Device,i,Str(HID_Info\DeviceInfo[i]\FeatureReportByteLength),6) Next i EndIf EndIf EndProcedure Procedure Disables_Gadgets(State) DisableGadget(#Button_Start, State) DisableGadget(#Button_Stop, State!1) DisableGadget(#ListIcon_Device, State) DisableGadget(#String_Pause, State) DisableGadget(#Container_Data, State) DisableGadget(#CheckBox_ReadDevice_State, State) EndProcedure Procedure FindDevice_Timer() ; Процедура вызывается по таймеру, каджие 200 мс. Static Old_Test Shared FindDevice_Ignore Shared Thread_Device_IO_Bugs, Thread_Device_IO_ID If PID_Device<>0 And VID_Device<>0 Test=HID::TestDevice(PID_Device, VID_Device, VersionNumber_Device) ; Проверка доступности HID устройства If Test<>Old_Test Or FindDevice_Ignore=1 FindDevice_Ignore=0 Old_Test=Test If Test HID::CloseDevice(DeviceHandle) ; Освобождение хендлов, если таковые есть ; Получение идентификаторов HID устройства DeviceHandle=HID::OpenDevice(PID_Device, VID_Device, VersionNumber_Device) ; Хендл для записи If DeviceHandle SetGadgetColor(#String_Selected_device, #PB_Gadget_FrontColor, RGB(64, 140, 76)) Else SetGadgetColor(#String_Selected_device, #PB_Gadget_FrontColor, RGB(190, 0, 0)) EndIf Else HID::CloseDevice(W_DeviceHandle) ; Освобождение хендлов, если таковые есть DeviceHandle=0 SetGadgetColor(#String_Selected_device, #PB_Gadget_FrontColor, RGB(190, 0, 0)) EndIf EndIf EndIf If Thread_Device_IO_ID If Thread_Device_IO_Bugs>4 Disables_Gadgets(0) If IsThread(Thread_Device_IO_ID) KillThread(Thread_Device_IO_ID) Thread_Device_IO_ID = 0 MessageRequester("", "Thread is not responding!"+Chr(10)+"This is probably caused by bug"+Chr(10)+"connection with USB HID device!"+Chr(10)+Chr(10)+"Thread is killed!", 16) Else Thread_Device_IO_Bugs=0 EndIf Else Thread_Device_IO_Bugs+1 EndIf EndIf EndProcedure Procedure.s ByteToString(*Point, Size) Protected String.s String = "" For i=0 To Size String+RSet(Hex(PeekA(*Point+i), #PB_Ascii), 2, "0")+" " Next i ProcedureReturn String EndProcedure Procedure Thread_Device_IO(*Point) Shared Thread_Start, Thread_Device_IO_ID Shared Thread_Device_IO_Bugs, FindDevice_Ignore Protected StructInfo.Thread_Device_IO_Info CopyMemory(*Point, @StructInfo, SizeOf(Thread_Device_IO_Info)) InputReport = StructInfo\DeviceInfo\InputReportByteLength OutputReport = StructInfo\DeviceInfo\OutputReportByteLength Feature = StructInfo\DeviceInfo\FeatureReportByteLength Dim OutBuf.a(OutputReport+2) Dim InBuf.a(InputReport+2) CompareMem=InputReport If OutputReport < InputReport CompareMem = OutputReport EndIf Counter = 1 Counter_x=Counter+99;9 Repeat If DeviceHandle FillMemory(@OutBuf(), OutputReport, 0, #PB_Byte) FillMemory(@InBuf(), InputReport, 0, #PB_Byte) If StructInfo\RandomState = 1 Temp1=8 If OutputReport<8 Temp1=OutputReport EndIf For z=1 To Temp1 If StructInfo\Bytes[z] >255 Temp.a=Random(255) Else Temp.a=StructInfo\Bytes[z] EndIf OutBuf(z) = Temp Next z Else For z=1 To OutputReport Temp.a=Random(255) OutBuf(z) = Temp Next z EndIf OutCount=HID::WriteDevice(DeviceHandle, @OutBuf(),OutputReport) If OutCount = OutputReport If StructInfo\ReadDevice_State = 1 InCount=HID::ReadDevice(DeviceHandle, @InBuf(),InputReport) If InCount = InputReport If CompareMem<>0 And CompareMemory(@OutBuf(), @InBuf(), CompareMem)<>1 AddGadgetItem(#Editor_Log, -1, RSet(Str(Counter), 6, " ")+" ERROR Bug compare memory Send: "+ByteToString(@OutBuf()+1, CompareMem-2)+"; Read: "+ByteToString(@InBuf()+1, CompareMem-2)) Break EndIf Else AddGadgetItem(#Editor_Log, -1, RSet(Str(Counter), 6, " ")+" ERROR Bug read device (read "+Str(InCount)+" bytes) Send: "+ByteToString(@OutBuf()+1, OutputReport-2)+"; Read: "+ByteToString(@InBuf()+1, InputReport-2)) Break EndIf EndIf Else AddGadgetItem(#Editor_Log, -1, RSet(Str(Counter), 6, " ")+" ERROR Bug write device (send "+Str(OutCount)+" bytes). Send: "+ByteToString(@OutBuf()+1, OutputReport-2));" Break EndIf ; OutCount=HID::SetFeature(DeviceHandle, @OutBuf(),Feature) ; ; If OutCount = 1 ; If StructInfo\ReadDevice_State = 1 ; InCount=HID::GetFeature(DeviceHandle, @InBuf(),Feature) ; If InCount = 1 ; If Feature<>0 And CompareMemory(@OutBuf(), @InBuf(), Feature)<>1 ; AddGadgetItem(#Editor_Log, -1, RSet(Str(Counter), 6, " ")+" ERROR Bug compare memory Send: "+ByteToString(@OutBuf()+1, Feature-2)+"; Read: "+ByteToString(@InBuf()+1, Feature-2)) ; Break ; EndIf ; Else ; AddGadgetItem(#Editor_Log, -1, RSet(Str(Counter), 6, " ")+" ERROR Bug read device (read "+Str(InCount)+" bytes) Send: "+ByteToString(@OutBuf()+1, Feature-2)+"; Read: "+ByteToString(@InBuf()+1, Feature-2)) ; Break ; EndIf ; EndIf ; Else ; AddGadgetItem(#Editor_Log, -1, RSet(Str(Counter), 6, " ")+" ERROR Bug write device (send "+Str(OutCount)+" bytes)."); Send: "+ByteToString(@OutBuf()+1, OutputReport-2) ; Break ; EndIf If Counter_x<=Counter AddGadgetItem(#Editor_Log, -1, RSet(Str(Counter), 6, " ")+" OK Send: "+ByteToString(@OutBuf()+1, OutCount-2)) SendMessage_(GadgetID(#Editor_Log), #EM_SETSEL, -1, -1) Counter_x+100;0 EndIf EndIf If StructInfo\Pause>10 Delay(StructInfo\Pause) EndIf Thread_Device_IO_Bugs = 0 Counter + 1 Until Thread_Start<>1 Or DeviceHandle = 0 SendMessage_(GadgetID(#Editor_Log), #EM_SETSEL, -1, -1) Disables_Gadgets(0) HID::CloseDevice(DeviceHandle) FindDevice_Ignore = 1 Thread_Device_IO_ID = 0 EndProcedure Procedure Open_Main_Window() If OpenWindow(#Main_Window, 241, 107, 596, 520, "USB HID Tester", #PB_Window_MinimizeGadget | #PB_Window_Invisible | #PB_Window_TitleBar | #PB_Window_ScreenCentered ) TextGadget(#Text_Device_list, 5, 5, 280, 15, "Device list:") ButtonGadget(#Button_UpdateDeviceList, 510,2,80,18,"Update") ListIconGadget(#ListIcon_Device, 5, 20, 585, 100, "Product", 58, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_HeaderDragDrop|#PB_ListIcon_AlwaysShowSelection) AddGadgetColumn(#ListIcon_Device,1,"PID",48) AddGadgetColumn(#ListIcon_Device,2,"VID",48) AddGadgetColumn(#ListIcon_Device,3,"Version Number",94) AddGadgetColumn(#ListIcon_Device,4,"Imput report (bytes)",110) AddGadgetColumn(#ListIcon_Device,5,"Output report (bytes)",114) AddGadgetColumn(#ListIcon_Device,6,"Feature (bytes)",90) AddGadgetColumn(#ListIcon_Device,7,"",0) AddGadgetColumn(#ListIcon_Device,8,"",0) AddGadgetColumn(#ListIcon_Device,9,"",0) TextGadget(#Text_Selected_device, 5, 130, 100, 15, "Selected device:") StringGadget(#String_Selected_device, 110, 125, 480, 20, "", #PB_String_ReadOnly) ContainerGadget(#Container_Data,5,150,585,50,#PB_Container_Flat) OptionGadget(#Option_Random,4,6,90,15,"Random data") : SetGadgetState(#Option_Random,1) OptionGadget(#Option_SelectData,4,26,80,15,"Select data") Pos=100 For i=#Option_SelectData+1 To #Option_SelectData+16 Step 2 TextGadget(i, Pos, 28, 10, 15, Str((i-#Option_SelectData+2)/2)) : DisableGadget(i, 1) StringGadget(i+1, Pos+10, 24, 30, 20, "0", #PB_String_Numeric|#PB_Text_Center) : DisableGadget(i+1, 1) SetGadgetAttribute(i+1, #PB_String_MaximumLength, 3) Pos+58 Next i CloseGadgetList() TextGadget(#Text_Log, 5, 165+50, 30, 15, "Log:") : SetGadgetColor(#Text_Log, #PB_Gadget_FrontColor, RGB(0, 0, 235)) ButtonGadget(#Button_Start, 440, 155+50, 75, 25, "Start") ButtonGadget(#Button_Stop, 530, 155+50, 60, 25, "Stop") : DisableGadget(#Button_Stop, 1) EditorGadget(#Editor_Log, 5, 185+50, 585, 280, #PB_Editor_ReadOnly) SetGadgetFont(#Editor_Log, LoadFont(0, "Lucida Console", 8)) CheckBoxGadget(#CheckBox_ReadDevice_State, 50, 165+50, 135, 15, "Read data from device") TextGadget(#Text_Pause, 210, 165+50, 145, 15, "Pause between packets, ms:") StringGadget(#String_Pause, 360, 160+50, 40, 20, "0", #PB_String_Numeric) SetGadgetAttribute(#String_Pause, #PB_String_MaximumLength, 3) EndIf EndProcedure HID::HID_Init() Open_Main_Window() AddWindowTimer(#Main_Window, 1, 800) ;HID_DeviceInfo(0) Th_FindDevice=CreateThread(@HID_DeviceInfo(), 0) For i=1 To 20 WaitWindowEvent(1) Next i HideWindow(#Main_Window, #False) Repeat Event=WaitWindowEvent() If Event=#PB_Event_Timer Select EventTimer() Case 1 FindDevice_Timer() ;Case 2 EndSelect ElseIf Event=#PB_Event_Gadget Select EventGadget() Case #Button_UpdateDeviceList HID_DeviceInfo(0) Case #ListIcon_Device If EventType()=#PB_EventType_LeftDoubleClick ListPos=GetGadgetState(#ListIcon_Device) If ListPos>=0 HID::CloseDevice(W_DeviceHandle) DeviceHandle=0 PID_Device = Val(GetGadgetItemText(#ListIcon_Device, ListPos, 7)) VID_Device = Val(GetGadgetItemText(#ListIcon_Device, ListPos, 8)) VersionNumber_Device = Val(GetGadgetItemText(#ListIcon_Device, ListPos, 9)) SetGadgetColor(#String_Selected_device, #PB_Gadget_FrontColor, #PB_Default) SetGadgetText(#String_Selected_device, GetGadgetItemText(#ListIcon_Device, ListPos, 0)+"; PID: "+Hex(PID_Device,#PB_Unicode)+"H"+"; VID: "+Hex(VID_Device,#PB_Unicode)+"H"+"; S/N: "+Hex(VersionNumber_Device,#PB_Unicode)+"H") FindDevice_Ignore=1 EndIf EndIf Case #Button_Start If DeviceHandle Thread_Start=1 Thread_Device_Info\ReadDevice_State=GetGadgetState(#CheckBox_ReadDevice_State) Thread_Device_Info\Pause=Val(GetGadgetText(#String_Pause)) If Thread_Device_Info\Pause<0 Thread_Device_Info\Pause=0 ElseIf Thread_Device_Info\Pause > 1000 Thread_Device_Info\Pause = 1000 EndIf HID::GetCaps(DeviceHandle, @Thread_Device_Info\DeviceInfo) Thread_Device_Info\RandomState = GetGadgetState(#Option_Random) ! 1 If Thread_Device_Info\RandomState = 1 For i=#Option_SelectData+1 To #Option_SelectData+16 Step 2 Thread_Device_Info\Bytes[(i-#Option_SelectData+2)/2] = Val(GetGadgetText(i+1)) Next i EndIf Thread_Device_IO_Bugs=0 ClearGadgetItems(#Editor_Log) Thread_Device_IO_ID=CreateThread(@Thread_Device_IO(), @Thread_Device_Info) If Thread_Device_IO_ID Disables_Gadgets(1) Else MessageRequester("", "An error occurred when starting a thread!", 16) EndIf Else If GetGadgetText(#String_Selected_device)="" MessageRequester("", "Select a device from the list."+Chr(10)+"(Double click the left mouse button).", 48) Else MessageRequester("", "No devices found with the specified PID & VID", 48) EndIf EndIf Case #Button_Stop If Thread_Device_IO_ID<>0 Thread_Start+1 If Thread_Start>4 If IsThread(Thread_Device_IO_ID) KillThread(Thread_Device_IO_ID) EndIf Thread_Device_IO_Bugs=0 Thread_Start=0 Disables_Gadgets(0) MessageRequester("", "Thread is not responding!"+Chr(10)+"This is probably caused by an bug"+Chr(10)+"connection withUSB HID device!"+Chr(10)+Chr(10)+"Thread is killed.", 48) EndIf Else Disables_Gadgets(0) Thread_Start = 0 EndIf Case #Option_Random, #Option_SelectData State=GetGadgetState(#Option_Random) For i=#Option_SelectData+1 To #Option_SelectData+16 DisableGadget(i, State) Next i EndSelect EndIf Until Event=#PB_Event_CloseWindow If IsThread(Th_FindDevice) KillThread(Th_FindDevice) EndIf If IsThread(Thread_Device_IO_ID) KillThread(Thread_Device_IO_ID) EndIf HID::HID_End()Узнаем PID, VID и номер версии по идентификатору устройства.
Код:#USB_PID=1 #USB_VID=$1234 XIncludeFile "HID_Module.pbi" UseModule HID HID_Init() hDevice = OpenDevice(#USB_PID, #USB_VID) If hDevice Info.HID_Attributes If GetAttributes(hDevice, @Info) MessageRequester("", "PID "+Info\PID+Chr(10)+ "VID "+Info\VID+Chr(10)+ "Номер версии "+Info\VersionNumber, #MB_OK|#MB_ICONINFORMATION) Else MessageRequester("", "Ошибка функции GetAttributes", #MB_OK|#MB_ICONWARNING) EndIf CloseDevice(hDevice) Else MessageRequester("", "Устройство не найдено"+Chr(10)+ "PID "+#USB_PID+" VID "+#USB_VID, #MB_OK|#MB_ICONWARNING) EndIf HID_End()
Файлы. http://pure-basic.narod.ru/forum_files/HID_Module.zip