LibUSB in Purebasic

Just starting out? Need help? Post your questions and find answers here.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

LibUSB in Purebasic

Post by matalog »

I have put the files from this link http://purebasic.mybb.ru/viewtopic.php?id=389 in a folder with the 2012 version of LibUSB, which they, in 2017 were probably using. https://www.dropbox.com/scl/fi/531o7yoo ... 6zbb1&dl=0

Can anyone have a look at them and see if they can understand the couple of errors appearing (I assume due to changes in PB) and maybe test it and see if it works?
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

You files were 'corupted' and also wrong defined.


I used now the latest available libusb for windows:

Not tested: (maybe more aligns are needed, maybe PrototypeC is needed)

Code: Select all

;
; https://github.com/mcuee/libusb-win32
;
; Version 1.4.0.0
;

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


#LIBUSB_PATH_MAX = 512


;
; Device And/Or Interface Class codes
;
#USB_CLASS_PER_INTERFACE  = 0
#USB_CLASS_AUDIO          = 1
#USB_CLASS_COMM           = 2
#USB_CLASS_HID            = 3
#USB_CLASS_PRINTER        = 7
#USB_CLASS_MASS_STORAGE   = 8
#USB_CLASS_HUB            = 9
#USB_CLASS_DATA           = 10
#USB_CLASS_VENDOR_SPEC    = $ff


;
; Descriptor types
;
#USB_DT_DEVICE    = $01
#USB_DT_CONFIG    = $02
#USB_DT_STRING    = $03
#USB_DT_INTERFACE = $04
#USB_DT_ENDPOINT  = $05

#USB_DT_HID       = $21
#USB_DT_REPORT    = $22
#USB_DT_PHYSICAL  = $23
#USB_DT_HUB       = $29


;
; Descriptor sizes per descriptor type
;
#USB_DT_DEVICE_SIZE         = 18
#USB_DT_CONFIG_SIZE         = 9
#USB_DT_INTERFACE_SIZE      = 9
#USB_DT_ENDPOINT_SIZE       = 7
#USB_DT_ENDPOINT_AUDIO_SIZE = 9
#USB_DT_HUB_NONVAR_SIZE     = 7




; All standard descriptors have these 2 fields in common
Structure usb_descriptor_header
  bLength.a
  bDescriptorType.a
EndStructure


; String descriptor
Structure usb_string_descriptor
  bLength.a
  bDescriptorType.a
  wData.u[1]
EndStructure


; HID descriptor
Structure usb_hid_descriptor
  bLength.a
  bDescriptorType.a
  bcdHID.u
  bCountryCode.a
  bNumDescriptors.a
EndStructure


; Endpoint descriptor
#USB_MAXENDPOINTS = 32
Structure usb_endpoint_descriptor
  bLength.a
  bDescriptorType.a
  bEndpointAddress.a
  bmAttributes.a
  wMaxPacketSize.u
  bInterval.a
  bRefresh.a
  bSynchAddress.a
  
  *extra  ; Extra descriptors
  extralen.i
EndStructure


#USB_ENDPOINT_ADDRESS_MASK      = $0f   ; in bEndpointAddress
#USB_ENDPOINT_DIR_MASK          = $80

#USB_ENDPOINT_TYPE_MASK         = $03   ; in bmAttributes
#USB_ENDPOINT_TYPE_CONTROL      = 0
#USB_ENDPOINT_TYPE_ISOCHRONOUS  = 1
#USB_ENDPOINT_TYPE_BULK         = 2
#USB_ENDPOINT_TYPE_INTERRUPT    = 3


; Interface descriptor
#USB_MAXINTERFACES  = 32
Structure usb_interface_descriptor
  bLength.a
  bDescriptorType.a
  bInterfaceNumber.a
  bAlternateSetting.a
  bNumEndpoints.a
  bInterfaceClass.a
  bInterfaceSubClass.a
  bInterfaceProtocol.a
  iInterface.a
  
  *endpoint.usb_endpoint_descriptor
  
  *extra  ;	Extra descriptors
  extralen.i
EndStructure


#USB_MAXALTSETTING  = 128   ; Hard limit

Structure usb_interface
  *altsetting.usb_interface_descriptor
  
  num_altsetting.i
EndStructure


; Configuration descriptor information..
#USB_MAXCONFIG  = 8
Structure usb_config_descriptor
  bLength.a
  bDescriptorType.a
  wTotalLength.u
  bNumInterfaces.a
  bConfigurationValue.a
  iConfiguration.a
  bmAttributes.a
  MaxPower.a
  
  *Interface.usb_interface
  
  *extra  ; Extra descriptors
  extralen.i
EndStructure


; Device descriptor
Structure usb_device_descriptor
  bLength.a
  bDescriptorType.a
  bcdUSB.u
  bDeviceClass.a
  bDeviceSubClass.a
  bDeviceProtocol.a
  bMaxPacketSize0.a
  idVendor.u
  idProduct.u
  bcdDevice.u
  iManufacturer.a
  iProduct.a
  iSerialNumber.a
  bNumConfigurations.a
EndStructure


Structure usb_ctrl_setup
  bRequestType.a
  bRequest.a
  wValue.u
  wIndex.u
  wLength.u
EndStructure


;
; Standard requests
;
#USB_REQ_GET_STATUS         = $00
#USB_REQ_CLEAR_FEATURE      = $01
; = $02 is reserved
#USB_REQ_SET_FEATURE        = $03
; = $04 is reserved
#USB_REQ_SET_ADDRESS        = $05
#USB_REQ_GET_DESCRIPTOR     = $06
#USB_REQ_SET_DESCRIPTOR     = $07
#USB_REQ_GET_CONFIGURATION  = $08
#USB_REQ_SET_CONFIGURATION  = $09
#USB_REQ_GET_INTERFACE      = $0A
#USB_REQ_SET_INTERFACE      = $0B
#USB_REQ_SYNCH_FRAME        = $0C

#USB_TYPE_STANDARD          = ($00 << 5)
#USB_TYPE_CLASS             = ($01 << 5)
#USB_TYPE_VENDOR            = ($02 << 5)
#USB_TYPE_RESERVED          = ($03 << 5)

#USB_RECIP_DEVICE           = $00
#USB_RECIP_INTERFACE        = $01
#USB_RECIP_ENDPOINT         = $02
#USB_RECIP_OTHER            = $03


;
; Various libusb API related stuff
;

#USB_ENDPOINT_IN  = $80
#USB_ENDPOINT_OUT = $00

; Error codes
#USB_ERROR_BEGIN  = 500000

;
; This is supposed To look weird. This file is generated from autoconf
; And I didn't want to make this too complicated.
;
Macro USB_LE16_TO_CPU(x)
EndMacro


;
; Device reset types For usb_reset_ex.
; http://msdn.microsoft.com/en-us/library/ff537269%28VS.85%29.aspx
; http://msdn.microsoft.com/en-us/library/ff537243%28v=vs.85%29.aspx
;
#USB_RESET_TYPE_RESET_PORT = (1 << 0)
#USB_RESET_TYPE_CYCLE_PORT = (1 << 1)
#USB_RESET_TYPE_FULL_RESET = (#USB_RESET_TYPE_CYCLE_PORT | #USB_RESET_TYPE_RESET_PORT)


; Data types
; struct usb_device
; struct usb_bus

Structure usb_device Align #PB_Structure_AlignC
  *next.usb_device
  *prev.usb_device
  
  filename.a[#LIBUSB_PATH_MAX]
  
  *bus.usb_bus
  
  descriptor.usb_device_descriptor
  *config.usb_config_descriptor
  
  *dev  ; Darwin support

  devnum.a
  
  num_children.a
  *children
EndStructure


Structure usb_bus Align #PB_Structure_AlignC
  *next.usb_bus
  *prev.usb_bus
  
  dirname.a[#LIBUSB_PATH_MAX]
  
  *devices.usb_device
  location.l
  
  *root_dev.usb_device
EndStructure


; Version information, Windows specific
Structure usb_version_fields
  major.l
  minor.l
  micro.l
  nano.l
EndStructure

Structure usb_version
  dll.usb_version_fields
  driver.usb_version_fields
EndStructure


Structure usb_dev_handle
EndStructure

; Function prototypes

; usb.c
Prototype.i Prototype_usb_open(*dev.usb_device)
Prototype.i Prototype_usb_close(*dev.usb_dev_handle)
Prototype.i Prototype_usb_get_string(*dev.usb_dev_handle, index.i, langid.i, *buf, buflen.i)
Prototype.i Prototype_usb_get_string_simple(*dev.usb_dev_handle, index.i, *buf, buflen.i)

; descriptors.c
Prototype.i Prototype_usb_get_descriptor_by_endpoint(*udev.usb_dev_handle, ep.i, type.a, index.a, *buf, size.i)
Prototype.i Prototype_usb_get_descriptor(*udev.usb_dev_handle, type.a, index.a, *buf, size.i)


; <arch>.c
Prototype.i Prototype_usb_bulk_write(*dev.usb_dev_handle, ep.i, *bytes, size.i, timeout.i)
Prototype.i Prototype_usb_bulk_read(*dev.usb_dev_handle, ep.i, *bytes, size.i, timeout.i)
Prototype.i Prototype_usb_interrupt_write(*dev.usb_dev_handle, ep.i, *bytes, size.i, timeout.i)
Prototype.i Prototype_usb_interrupt_read(*dev.usb_dev_handle, ep.i, *bytes, size.i, timeout.i)
Prototype.i Prototype_usb_control_msg(*dev.usb_dev_handle, requesttype.i, request.i, value.i, index.i, *bytes, size.i, timeout.i)
Prototype.i Prototype_usb_set_configuration(*dev.usb_dev_handle, configuration.i)
Prototype.i Prototype_usb_claim_interface(*dev.usb_dev_handle, _Interface.i)
Prototype.i Prototype_usb_release_interface(*dev.usb_dev_handle, _Interface.i)
Prototype.i Prototype_usb_set_altinterface(*devusb_dev_handle, alternate.i)
Prototype.i Prototype_usb_resetep(*dev.usb_dev_handle, ep.i)
Prototype.i Prototype_usb_clear_halt(*dev.usb_dev_handle, ep.i)
Prototype.i Prototype_usb_reset(*dev.usb_dev_handle)
Prototype.i Prototype_usb_reset_ex(*dev.usb_dev_handle, reset_type.i)

Prototype.i Prototype_usb_strerror()

Prototype Prototype_usb_init()
Prototype Prototype_usb_set_debug(level.i)
Prototype.i Prototype_usb_find_busses()
Prototype.i Prototype_usb_find_devices()
Prototype.i Prototype_usb_device(*dev.usb_dev_handle)
Prototype.i Prototype_usb_get_busses()


; Windows specific functions

#LIBUSB_HAS_INSTALL_SERVICE_NP = 1
Prototype.i Prototype_usb_install_service_np()
Prototype Prototype_usb_install_service_np_rundll(wnd.i, instance.i, cmd_line.p-Ascii, cmd_show.i)

#LIBUSB_HAS_UNINSTALL_SERVICE_NP = 1
Prototype.i Prototype_usb_uninstall_service_np()
Prototype Prototype_usb_uninstall_service_np_rundll(wnd.i, instance.i, cmd_line.p-Ascii, cmd_show.i)

#LIBUSB_HAS_INSTALL_DRIVER_NP = 1
Prototype.i Prototype_usb_install_driver_np(inf_file.p-Ascii)
Prototype Prototype_usb_install_driver_np_rundll(wnd.i, instance.i, cmd_line.p-Ascii, cmd_show.i)

#LIBUSB_HAS_TOUCH_INF_FILE_NP = 1
Prototype.i Prototype_usb_touch_inf_file_np(inf_file.p-Ascii)
Prototype Prototype_usb_touch_inf_file_np_rundll(wnd.i, instance.i, cmd_line.p-Ascii, cmd_show.i)

#LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP = 1
Prototype.i Prototype_usb_install_needs_restart_np()

#LIBUSB_HAS_INSTALL_NP = 1
Prototype.i Prototype_usb_install_npW(hwnd.i, instance.i, cmd_line.s, starg_arg.i)
Prototype.i Prototype_usb_install_npA(hwnd.i, instance.i, cmd_line.p-Ascii, starg_arg.i)
Macro usb_install_np
  usb_install_npA
EndMacro
Prototype Prototype_usb_install_np_rundll(wnd.i, instance.i, cmd_line.p-Ascii, cmd_show.i)

Prototype.i Prototype_usb_get_version()

Prototype.i Prototype_usb_isochronous_setup_async(*dev.usb_dev_handle, *context, ep.a, pktsize.i)
Prototype.i Prototype_usb_bulk_setup_async(*dev.usb_dev_handle, *context, ep.a)
Prototype.i Prototype_usb_interrupt_setup_async(*dev.usb_dev_handle, *context, ep.a)

Prototype.i Prototype_usb_submit_async(*context, *bytes, size.i)
Prototype.i Prototype_usb_reap_async(*context, timeout.i)
Prototype.i Prototype_usb_reap_async_nocancel(*context, timeout.i)
Prototype.i Prototype_usb_cancel_async(*context)
Prototype.i Prototype_usb_free_async(*context)



Global libusb_lib.i

Global.i usb_open.Prototype_usb_open
Global.i usb_close.Prototype_usb_close
Global.i usb_get_string.Prototype_usb_get_string
Global.i usb_get_string_simple.Prototype_usb_get_string_simple

; descriptors.c
Global.i usb_get_descriptor_by_endpoint.Prototype_usb_get_descriptor_by_endpoint
Global.i usb_get_descriptor.Prototype_usb_get_descriptor


; <arch>.c
Global.i usb_bulk_write.Prototype_usb_bulk_write
Global.i usb_bulk_read.Prototype_usb_bulk_read
Global.i usb_interrupt_write.Prototype_usb_interrupt_write
Global.i usb_interrupt_read.Prototype_usb_interrupt_read
Global.i usb_control_msg.Prototype_usb_control_msg
Global.i usb_set_configuration.Prototype_usb_set_configuration
Global.i usb_claim_interface.Prototype_usb_claim_interface
Global.i usb_release_interface.Prototype_usb_release_interface
Global.i usb_set_altinterface.Prototype_usb_set_altinterface
Global.i usb_resetep.Prototype_usb_resetep
Global.i usb_clear_halt.Prototype_usb_clear_halt
Global.i usb_reset.Prototype_usb_reset
Global.i usb_reset_ex.Prototype_usb_reset_ex

Global.i usb_strerror.Prototype_usb_strerror

Global usb_init.Prototype_usb_init
Global usb_set_debug.Prototype_usb_set_debug
Global.i usb_find_busses.Prototype_usb_find_busses
Global.i usb_find_devices.Prototype_usb_find_devices
Global.i usb_device.Prototype_usb_device
Global.i usb_get_busses.Prototype_usb_get_busses


; Windows specific functions


Global.i usb_install_service_np.Prototype_usb_install_service_np
Global.i usb_uninstall_service_np.Prototype_usb_uninstall_service_np
Global.i usb_install_driver_np.Prototype_usb_install_driver_np
Global.i usb_touch_inf_file_np.Prototype_usb_touch_inf_file_np
Global.i usb_install_needs_restart_np.Prototype_usb_install_needs_restart_np
Global.i usb_install_npW.Prototype_usb_install_npW
Global.i usb_install_npA.Prototype_usb_install_npA
Global.i usb_get_version.Prototype_usb_get_version

Global.i usb_isochronous_setup_async.Prototype_usb_isochronous_setup_async
Global.i usb_bulk_setup_async.Prototype_usb_bulk_setup_async
Global.i usb_interrupt_setup_async.Prototype_usb_interrupt_setup_async

Global.i usb_submit_async.Prototype_usb_submit_async
Global.i usb_reap_async.Prototype_usb_reap_async
Global.i usb_reap_async_nocancel.Prototype_usb_reap_async_nocancel
Global.i usb_cancel_async.Prototype_usb_cancel_async
Global.i usb_free_async.Prototype_usb_free_async


Procedure.i libusb_init()
  
  If Not IsLibrary(libusb_lib)
    
    CompilerSelect #PB_Compiler_OS
      CompilerCase #PB_OS_Windows
        CompilerIf #PB_Compiler_32Bit
          libusb_lib = OpenLibrary(#PB_Any, "libusb0_x86.dll")
        CompilerElse
          libusb_lib = OpenLibrary(#PB_Any, "libusb0.dll")
        CompilerEndIf
        
      CompilerCase #PB_OS_Linux
        
      CompilerCase #PB_OS_MacOS
        
    CompilerEndSelect
    
    If libusb_lib
      usb_open = GetFunction(libusb_lib, "usb_open")
      usb_close = GetFunction(libusb_lib, "usb_close")
      usb_get_string = GetFunction(libusb_lib, "usb_get_string")
      usb_get_string_simple = GetFunction(libusb_lib, "usb_get_string_simple")
      
      usb_get_descriptor_by_endpoint = GetFunction(libusb_lib, "usb_get_descriptor_by_endpoint")
      usb_get_descriptor = GetFunction(libusb_lib, "usb_get_descriptor")
      
      usb_bulk_write = GetFunction(libusb_lib, "usb_bulk_write")
      usb_bulk_read = GetFunction(libusb_lib, "usb_bulk_read")
      usb_interrupt_write = GetFunction(libusb_lib, "usb_interrupt_write")
      usb_interrupt_read = GetFunction(libusb_lib, "usb_interrupt_read")
      usb_control_msg = GetFunction(libusb_lib, "usb_control_msg")
      usb_set_configuration = GetFunction(libusb_lib, "usb_set_configuration")
      usb_claim_interface = GetFunction(libusb_lib, "usb_claim_interface")
      usb_release_interface = GetFunction(libusb_lib, "usb_release_interface")
      usb_set_altinterface = GetFunction(libusb_lib, "usb_set_altinterface")
      usb_resetep = GetFunction(libusb_lib, "usb_resetep")
      usb_clear_halt = GetFunction(libusb_lib, "usb_clear_halt")
      usb_reset = GetFunction(libusb_lib, "usb_reset")
      usb_reset_ex = GetFunction(libusb_lib, "usb_reset_ex")
      
      usb_strerror = GetFunction(libusb_lib, "usb_strerror")
      
      usb_init = GetFunction(libusb_lib, "usb_init")
      usb_set_debug = GetFunction(libusb_lib, "usb_set_debug")
      usb_find_busses = GetFunction(libusb_lib, "usb_find_busses")
      usb_find_devices = GetFunction(libusb_lib, "usb_find_devices")
      usb_device = GetFunction(libusb_lib, "usb_device")
      usb_get_busses = GetFunction(libusb_lib, "usb_get_busses")
      
      usb_install_service_np = GetFunction(libusb_lib, "usb_install_service_np")
      usb_uninstall_service_np = GetFunction(libusb_lib, "usb_uninstall_service_np")
      usb_install_driver_np = GetFunction(libusb_lib, "usb_install_driver_np")
      usb_touch_inf_file_np = GetFunction(libusb_lib, "usb_touch_inf_file_np")
      usb_install_needs_restart_np = GetFunction(libusb_lib, "usb_install_needs_restart_np")
      usb_install_npW = GetFunction(libusb_lib, "usb_install_npW")
      usb_install_npA = GetFunction(libusb_lib, "usb_install_npA")
      usb_get_version = GetFunction(libusb_lib, "usb_get_version")
      
      usb_isochronous_setup_async = GetFunction(libusb_lib, "usb_isochronous_setup_async")
      usb_bulk_setup_async = GetFunction(libusb_lib, "usb_bulk_setup_async")
      usb_interrupt_setup_async = GetFunction(libusb_lib, "usb_interrupt_setup_async")
      
      usb_submit_async = GetFunction(libusb_lib, "usb_submit_async")
      usb_reap_async = GetFunction(libusb_lib, "usb_reap_async")
      usb_reap_async_nocancel = GetFunction(libusb_lib, "usb_reap_async_nocancel")
      usb_cancel_async = GetFunction(libusb_lib, "usb_cancel_async")
      usb_free_async = GetFunction(libusb_lib, "usb_free_async")
    EndIf
  EndIf
  
  ProcedureReturn libusb_lib
  
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  
  Procedure.i open_dev(VId.u, PId.u)
  
    Protected *bus.usb_bus
    Protected *dev.usb_device
    
    *bus = usb_get_busses()
    While *bus
      Debug "Bus: " + PeekS(@*bus\dirname[0], -1, #PB_Ascii)
      *dev = *bus\devices
      Debug *dev
      While *dev
        Debug *dev
        If *dev\descriptor\idVendor = VId And *dev\descriptor\idProduct = PId
          ProcedureReturn usb_open(*dev)
        EndIf
        *dev = *dev\Next
      Wend
      
      *bus = *bus\Next
    Wend
    
    ProcedureReturn #Null
    
  EndProcedure

  
  
  Define *usb_version.usb_version
  Define *usb_dev_handle
  
  If libusb_init()
    
    *usb_version = usb_get_version()
    Debug "Version DLL   : " + Str(*usb_version\dll\major) + "." + Str(*usb_version\dll\minor) + "." + Str(*usb_version\dll\micro) + "." +Str(*usb_version\dll\nano)
    Debug "Version Driver: " + Str(*usb_version\driver\major) + "." + Str(*usb_version\driver\minor) + "." + Str(*usb_version\driver\micro) + "." +Str(*usb_version\driver\nano)
    
    usb_init()  ; initialize the library
    Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    Debug usb_find_busses() ; find all busses
    Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    Debug usb_find_devices()  ; find all connected devices
    Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    
    *usb_dev_handle = open_dev($0666, $0001)
    If *usb_dev_handle
      Debug "Ok"
      usb_close(*usb_dev_handle)
    Else
      Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    EndIf
    
  EndIf
  
CompilerEndIf
And the driver needs to be installed. :wink:
Last edited by infratec on Fri Jan 17, 2025 11:46 am, edited 2 times in total.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

Re: LibUSB in Purebasic

Post by matalog »

infratec wrote: Mon Jan 13, 2025 12:17 pm You files were 'corupted' and also wrong defined.


I used now the latest available libusb for windows:

Not tested: (maybe more aligns are needed, maybe PrototypeC is needed)

And the driver needs to be installed. :wink:
Well, it doesn't report any problems. It runs and stops. Thanks for fixing the problems.

I really do not know anything about using this, can it be adapted to list connected devices, or just a DEBUG to prove it is working.
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

:?: :?: :?:

As you can read in the code, all function of libusb are 'imported', so you can do all stuff with usb what is possible.
firace
Addict
Addict
Posts: 947
Joined: Wed Nov 09, 2011 8:58 am

Re: LibUSB in Purebasic

Post by firace »

matalog wrote: Thu Jan 16, 2025 6:08 pm
infratec wrote: Mon Jan 13, 2025 12:17 pm You files were 'corupted' and also wrong defined.


I used now the latest available libusb for windows:

Not tested: (maybe more aligns are needed, maybe PrototypeC is needed)

And the driver needs to be installed. :wink:
Well, it doesn't report any problems. It runs and stops. Thanks for fixing the problems.

I really do not know anything about using this, can it be adapted to list connected devices, or just a DEBUG to prove it is working.
As a quick test you can try to call Prototype_usb_get_version() or Prototype_usb_find_devices()
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

Re: LibUSB in Purebasic

Post by matalog »

Actually, I just noticed the last part of the program:

Code: Select all

  If libusb_init()
    
    *usb_version = usb_get_version()
    Debug "Version DLL   : " + Str(*usb_version\dll\major) + "." + Str(*usb_version\dll\minor) + "." + Str(*usb_version\dll\micro) + "." +Str(*usb_version\dll\nano)
    Debug "Version Driver: " + Str(*usb_version\driver\major) + "." + Str(*usb_version\driver\minor) + "." + Str(*usb_version\driver\micro) + "." +Str(*usb_version\driver\nano)
    
    usb_init()  ; initialize the library
    Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    Debug usb_find_busses() ; find all busses
    Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    Debug usb_find_devices()  ; find all connected devices
    Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    
    *usb_dev_handle = open_dev($0666, $0001)
    If *usb_dev_handle
      Debug "Ok"
      usb_close(*usb_dev_handle)
    Else
      Debug PeekS(usb_strerror(), -1, #PB_Ascii)
    EndIf
    
  EndIf
When I run the program it doesn't debug anything, so libusb is not initialised. I'll have to have another look through installing it.
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

I added the dll selection for x86 and x64.
You need to place the dll beside the executable.
Check 'Create temp exe in source directory'
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

I switched to an 'other' libusb

https://github.com/libusb/libusb/releases

download the 7z package wich include the dlls for windows

This lib is also used in linux (maybe also macOS)

libusb.pbi:

Code: Select all

;
; https://libusb.info/
;
; https://github.com/libusb/libusb/releases
;

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


Structure libusb_cpu_to_le16_Structure
  StructureUnion
		b8.a[2]
		b16.u
	EndStructureUnion
EndStructure

Procedure.u libusb_cpu_to_le16(x.u)
  
  Protected _tmp.libusb_cpu_to_le16_Structure
  
  
	_tmp\b8[1] = (x >> 8)
	_tmp\b8[0] = (x & $ff)
	
	ProcedureReturn _tmp\b16
	
EndProcedure

Macro libusb_le16_to_cpu
  libusb_cpu_to_le16
EndMacro


#LIBUSB_FLEXIBLE_ARRAY = 0

; Device And/Or Interface Class codes
Enumeration libusb_class_code
  #LIBUSB_CLASS_PER_INTERFACE       = $00
  #LIBUSB_CLASS_AUDIO               = $01 ; Audio class
  #LIBUSB_CLASS_COMM                = $02 ; Communications class
  #LIBUSB_CLASS_HID                 = $03 ; Human Interface Device class
  #LIBUSB_CLASS_PHYSICAL            = $05 ; Physical
  #LIBUSB_CLASS_IMAGE               = $06 ; Image class
  #LIBUSB_CLASS_PTP                 = $06 ; legacy name from libusb-0.1 usb.h
  #LIBUSB_CLASS_PRINTER             = $07 ; Printer class
  #LIBUSB_CLASS_MASS_STORAGE        = $08 ; Mass storage class
  #LIBUSB_CLASS_HUB                 = $09 ; Hub class
  #LIBUSB_CLASS_DATA                = $0a ; Data class
  #LIBUSB_CLASS_SMART_CARD          = $0b ; Smart Card
  #LIBUSB_CLASS_CONTENT_SECURITY    = $0d ; Content Security
  #LIBUSB_CLASS_VIDEO               = $0e ; Video
  #LIBUSB_CLASS_PERSONAL_HEALTHCARE = $0f ; Personal Healthcare
  #LIBUSB_CLASS_DIAGNOSTIC_DEVICE   = $dc ; Diagnostic Device
  #LIBUSB_CLASS_WIRELESS            = $e0 ; Wireless class
  #LIBUSB_CLASS_MISCELLANEOUS       = $ef ; Miscellaneous class
  #LIBUSB_CLASS_APPLICATION         = $fe ; Application class
  #LIBUSB_CLASS_VENDOR_SPEC         = $ff ; Class is vendor-specific
EndEnumeration


Enumeration libusb_descriptor_type
  #LIBUSB_DT_DEVICE                 = $01 ; Device descriptor. See libusb_device_descriptor.
  #LIBUSB_DT_CONFIG                 = $02 ; Configuration descriptor. See libusb_config_descriptor.
  #LIBUSB_DT_STRING                 = $03 ; String descriptor
  #LIBUSB_DT_INTERFACE              = $04 ; Interface descriptor. See libusb_interface_descriptor.
  #LIBUSB_DT_ENDPOINT               = $05 ; Endpoint descriptor. See libusb_endpoint_descriptor.
  #LIBUSB_DT_INTERFACE_ASSOCIATION  = $0b ; Interface Association Descriptor.
  #LIBUSB_DT_BOS                    = $0f ; BOS descriptor
  #LIBUSB_DT_DEVICE_CAPABILITY      = $10 ; Device Capability descriptor
  #LIBUSB_DT_HID                    = $21 ; HID descriptor
  #LIBUSB_DT_REPORT                 = $22 ; HID report descriptor
  #LIBUSB_DT_PHYSICAL               = $23 ; Physical descriptor
  #LIBUSB_DT_HUB                    = $29 ; Hub descriptor
  #LIBUSB_DT_SUPERSPEED_HUB         = $2a ; SuperSpeed Hub descriptor
  #LIBUSB_DT_SS_ENDPOINT_COMPANION  = $30 ; SuperSpeed Endpoint Companion descriptor
EndEnumeration


Enumeration libusb_descriptor_type
  #LIBUSB_DT_DEVICE                 = $01 ; Device descriptor. See libusb_device_descriptor.
  #LIBUSB_DT_CONFIG                 = $02 ; Configuration descriptor. See libusb_config_descriptor.
  #LIBUSB_DT_STRING                 = $03 ; String descriptor
  #LIBUSB_DT_INTERFACE              = $04 ; Interface descriptor. See libusb_interface_descriptor.
  #LIBUSB_DT_ENDPOINT               = $05 ; Endpoint descriptor. See libusb_endpoint_descriptor.
  #LIBUSB_DT_INTERFACE_ASSOCIATION  = $0b ; Interface Association Descriptor.
  #LIBUSB_DT_BOS                    = $0f ; BOS descriptor
  #LIBUSB_DT_DEVICE_CAPABILITY      = $10 ; Device Capability descriptor
  #LIBUSB_DT_HID                    = $21 ; HID descriptor
  #LIBUSB_DT_REPORT                 = $22 ; HID report descriptor
  #LIBUSB_DT_PHYSICAL               = $23 ; Physical descriptor
  #LIBUSB_DT_HUB                    = $29 ; Hub descriptor
  #LIBUSB_DT_SUPERSPEED_HUB         = $2a ; SuperSpeed Hub descriptor
  #LIBUSB_DT_SS_ENDPOINT_COMPANION  = $30 ; SuperSpeed Endpoint Companion descriptor
EndEnumeration


; Descriptor sizes per descriptor type
#LIBUSB_DT_DEVICE_SIZE = 18
#LIBUSB_DT_CONFIG_SIZE = 9
#LIBUSB_DT_INTERFACE_SIZE = 9
#LIBUSB_DT_ENDPOINT_SIZE = 7
#LIBUSB_DT_ENDPOINT_AUDIO_SIZE = 9  ; Audio extension
#LIBUSB_DT_HUB_NONVAR_SIZE = 7
#LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE = 6
#LIBUSB_DT_BOS_SIZE = 5
#LIBUSB_DT_DEVICE_CAPABILITY_SIZE = 3

; BOS descriptor sizes
#LIBUSB_BT_USB_2_0_EXTENSION_SIZE = 7
#LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE = 10
#LIBUSB_BT_CONTAINER_ID_SIZE = 20
#LIBUSB_BT_PLATFORM_DESCRIPTOR_MIN_SIZE = 20

; We unwrap the BOS => Define its max size
#LIBUSB_DT_BOS_MAX_SIZE = (#LIBUSB_DT_BOS_SIZE + #LIBUSB_BT_USB_2_0_EXTENSION_SIZE +	#LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE + #LIBUSB_BT_CONTAINER_ID_SIZE)

#LIBUSB_ENDPOINT_ADDRESS_MASK = $0f	; in bEndpointAddress
#LIBUSB_ENDPOINT_DIR_MASK = $80


Enumeration libusb_endpoint_direction
  #LIBUSB_ENDPOINT_OUT  = $00 ; Out: host-To-device
  #LIBUSB_ENDPOINT_IN   = $80 ; In: device-To-host
EndEnumeration

#LIBUSB_TRANSFER_TYPE_MASK = $03  ; in bmAttributes


Enumeration libusb_endpoint_transfer_type
  #LIBUSB_ENDPOINT_TRANSFER_TYPE_CONTROL      = $0  ; Control endpoint
  #LIBUSB_ENDPOINT_TRANSFER_TYPE_ISOCHRONOUS  = $1  ; Isochronous endpoint
  #LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK         = $2  ; Bulk endpoint
  #LIBUSB_ENDPOINT_TRANSFER_TYPE_INTERRUPT    = $3  ; Interrupt endpoint
EndEnumeration


Enumeration libusb_standard_request
  #LIBUSB_REQUEST_GET_STATUS        = $00 ; Request status of the specific recipient.
  #LIBUSB_REQUEST_CLEAR_FEATURE     = $01 ; Clear Or disable a specific feature.
  #LIBUSB_REQUEST_SET_FEATURE       = $03 ; Set Or enable a specific feature.
  #LIBUSB_REQUEST_SET_ADDRESS       = $05 ; Set device address For all future accesses.
  #LIBUSB_REQUEST_GET_DESCRIPTOR    = $06 ; Get the specified descriptor.
  #LIBUSB_REQUEST_SET_DESCRIPTOR    = $07 ; Used To update existing descriptors Or add new descriptors.
  #LIBUSB_REQUEST_GET_CONFIGURATION = $08 ; Get the current device configuration value.
  #LIBUSB_REQUEST_SET_CONFIGURATION = $09 ; Set device configuration.
  #LIBUSB_REQUEST_GET_INTERFACE     = $0A ; Return the selected alternate setting For the specified Interface.
  #LIBUSB_REQUEST_SET_INTERFACE     = $0B ; Select an alternate Interface For the specified Interface.
  #LIBUSB_REQUEST_SYNCH_FRAME       = $0C ; Set then report an endpoint's synchronization frame.
  #LIBUSB_REQUEST_SET_SEL           = $30 ; Sets both the U1 And U2 Exit Latency.
  #LIBUSB_SET_ISOCH_DELAY           = $31 ; Delay from the time a host transmits a packet To the time it is received by the device.
EndEnumeration


Enumeration libusb_request_type
  #LIBUSB_REQUEST_TYPE_STANDARD = ($00 << 5) ; Standard.
  #LIBUSB_REQUEST_TYPE_CLASS    = ($01 << 5) ; Class.
  #LIBUSB_REQUEST_TYPE_VENDOR   = ($02 << 5) ; Vendor.
  #LIBUSB_REQUEST_TYPE_RESERVED = ($03 << 5) ; Reserved. 
EndEnumeration


Enumeration libusb_request_recipient
  #LIBUSB_RECIPIENT_DEVICE    = $00 ; Device.
  #LIBUSB_RECIPIENT_INTERFACE = $01 ; Interface.
  #LIBUSB_RECIPIENT_ENDPOINT  = $02 ; Endpoint.
  #LIBUSB_RECIPIENT_OTHER     = $03 ; Other.
EndEnumeration


#LIBUSB_ISO_SYNC_TYPE_MASK = $0c

Enumeration libusb_iso_sync_type
  #LIBUSB_ISO_SYNC_TYPE_NONE      = $0  ; No synchronization
  #LIBUSB_ISO_SYNC_TYPE_ASYNC     = $1  ; Asynchronous
  #LIBUSB_ISO_SYNC_TYPE_ADAPTIVE  = $2  ; Adaptive
  #LIBUSB_ISO_SYNC_TYPE_SYNC      = $3  ; Synchronous
EndEnumeration


#LIBUSB_ISO_USAGE_TYPE_MASK = $30

Enumeration libusb_iso_usage_type
  #LIBUSB_ISO_USAGE_TYPE_DATA     = $0  ; Data endpoint
  #LIBUSB_ISO_USAGE_TYPE_FEEDBACK = $1  ; Feedback endpoint
  #LIBUSB_ISO_USAGE_TYPE_IMPLICIT = $2  ; Implicit feedback Data endpoint
EndEnumeration


Enumeration libusb_supported_speed
  #LIBUSB_LOW_SPEED_OPERATION   = (1 << 0)  ; Low speed operation supported (1.5MBit/s).
  #LIBUSB_FULL_SPEED_OPERATION  = (1 << 1)  ; Full speed operation supported (12MBit/s).
  #LIBUSB_HIGH_SPEED_OPERATION  = (1 << 2)  ; High speed operation supported (480MBit/s).
  #LIBUSB_SUPER_SPEED_OPERATION = (1 << 3)  ; Superspeed operation supported (5000MBit/s).
EndEnumeration


Enumeration libusb_usb_2_0_extension_attributes
  #LIBUSB_BM_LPM_SUPPORT  = (1 << 1)  ; Supports Link Power Management (LPM)
EndEnumeration


Enumeration libusb_ss_usb_device_capability_attributes
  #LIBUSB_BM_LTM_SUPPORT  = (1 << 1)  ; Supports Latency Tolerance Messages (LTM)
EndEnumeration


Enumeration libusb_bos_type
  #LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = $01 ; Wireless USB device capability
  #LIBUSB_BT_USB_2_0_EXTENSION              = $02 ; USB 2.0 extensions
  #LIBUSB_BT_SS_USB_DEVICE_CAPABILITY       = $03 ; SuperSpeed USB device capability
  #LIBUSB_BT_CONTAINER_ID                   = $04 ; Container ID type
  #LIBUSB_BT_PLATFORM_DESCRIPTOR            = $05 ; Platform descriptor
EndEnumeration


Macro uint8_t
  a
EndMacro

Macro uint16_t
  u
EndMacro

Macro uint32_t
  l
EndMacro

Macro short
  w
EndMacro

Macro size_t
  l
EndMacro




CompilerIf Not Defined(timeval, #PB_Structure)
  Structure timeval
    tv_sec.l
    tv_usec.l
  EndStructure
CompilerEndIf

; PB
Structure AsciiArray
  a.a[0]
EndStructure


Structure libusb_device_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t             ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t     ; Descriptor type. More...
  bcdUSB.uint16_t             ; USB specification release number in binary-coded decimal. More...
  bDeviceClass.uint8_t        ; USB-If class code For the device. More...
  bDeviceSubClass.uint8_t     ; USB-If subclass code For the device, qualified by the bDeviceClass value.
  bDeviceProtocol.uint8_t     ; USB-If protocol code For the device, qualified by the bDeviceClass And bDeviceSubClass values.
  bMaxPacketSize0.uint8_t     ; Maximum packet size For endpoint 0.
  idVendor.uint16_t           ; USB-If vendor ID.
  idProduct.uint16_t          ; USB-If product ID.
  bcdDevice.uint16_t          ; Device release number in binary-coded decimal.
  iManufacturer.uint8_t       ; Index of string descriptor describing manufacturer.
  iProduct.uint8_t            ; Index of string descriptor describing product.
  iSerialNumber.uint8_t       ; Index of string descriptor containing device serial number.
  bNumConfigurations.uint8_t  ; Number of possible configurations.
EndStructure


Structure libusb_endpoint_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t           ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t   ; Descriptor type. More...
  bEndpointAddress.uint8_t  ; The address of the endpoint described by this descriptor. More...
  bmAttributes.uint8_t      ; Attributes which apply To the endpoint when it is configured using the bConfigurationValue. More...
  wMaxPacketSize.uint16_t   ; Maximum packet size this endpoint is capable of sending/receiving.
  bInterval.uint8_t         ; Interval For polling endpoint For Data transfers.
  bRefresh.uint8_t          ; For audio devices only: the rate at which synchronization feedback is provided.
  bSynchAddress.uint8_t     ; For audio devices only: the address If the synch endpoint.
  *extra.AsciiArray         ; Extra descriptors. More...
  extra_length.l            ; Length of the extra descriptors, in bytes. More...
EndStructure


Structure libusb_interface_association_descriptor Align #PB_Structure_AlignC 
	bLength.uint8_t ; Size of this descriptor (in bytes)
  
	; Descriptor type. Will have value
	; \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE_ASSOCIATION
	; LIBUSB_DT_INTERFACE_ASSOCIATION in this context.
	bDescriptorType.uint8_t
  
	bFirstInterface.uint8_t ; Interface number of the first Interface that is associated with this function
	bInterfaceCount.uint8_t ; Number of contiguous interfaces that are associated with this function
  
	; USB-If class code For this function.
	; A value of zero is Not allowed in this descriptor.
	; If this field is 0xff, the function class is vendor-specific.
	; All other values are reserved For assignment by the USB-If.
	bFunctionClass.uint8_t
  
	; USB-If subclass code For this function.
	; If this field is Not set To 0xff, all values are reserved
	; For assignment by the USB-If
	bFunctionSubClass.uint8_t
  
	; USB-If protocol code For this function.
	; These codes are qualified by the values of the bFunctionClass
	; And bFunctionSubClass fields.
	bFunctionProtocol.uint8_t
  
	iFunction.uint8_t ; Index of string descriptor describing this function
EndStructure


Structure libusb_interface_association_descriptor_array Align #PB_Structure_AlignC 
	; Array of Interface association descriptors. The size of this Array
	; is determined by the length field.
	*iad.libusb_interface_association_descriptor
	length.l  ; Number of Interface association descriptors contained. Read-only.
EndStructure


Structure libusb_endpoint_descriptor_Array
  led.libusb_endpoint_descriptor[0]
EndStructure

Structure libusb_interface_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t             ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t     ;	Descriptor type. More...
  bInterfaceNumber.uint8_t    ; Number of this Interface.
  bAlternateSetting.uint8_t   ;	Value used To Select this alternate setting For this Interface.
  bNumEndpoints.uint8_t       ; Number of endpoints used by this Interface (excluding the control endpoint).
  bInterfaceClass.uint8_t     ; USB-If class code For this Interface. More...
  bInterfaceSubClass.uint8_t  ; USB-If subclass code For this Interface, qualified by the bInterfaceClass value.
  bInterfaceProtocol.uint8_t  ; USB-If protocol code For this Interface, qualified by the bInterfaceClass And bInterfaceSubClass values.
  iInterface.uint8_t          ; Index of string descriptor describing this Interface.
  *endpoint.libusb_endpoint_descriptor_Array  ; Array of endpoint descriptors. More...
  *extra.AsciiArray                     ; Extra descriptors. More...
  extra_length.l                        ; Length of the extra descriptors, in bytes. More...
EndStructure


Structure libusb_interface_descriptor_Array
  lid.libusb_interface_descriptor[0]
EndStructure


Structure libusb_interface Align #PB_Structure_AlignC 
  *altsetting.libusb_interface_descriptor_Array ; Array of Interface descriptors. More...
  num_altsetting.l                        ; The number of alternate settings that belong To this Interface. More...
EndStructure


Structure libusb_interface_Array  
   int.libusb_interface[0]
EndStructure

Structure libusb_config_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t             ; Size of this descriptor (in bytes) 
  bDescriptorType.uint8_t     ; Descriptor type. More...
  wTotalLength.uint16_t       ;	Total length of Data returned For this configuration.
  bNumInterfaces.uint8_t      ; Number of interfaces supported by this configuration.
  bConfigurationValue.uint8_t ; Identifier value For this configuration.
  iConfiguration.uint8_t      ; Index of string descriptor describing this configuration.
  bmAttributes.uint8_t        ; Configuration characteristics.
  MaxPower.uint8_t            ; Maximum power consumption of the USB device from this bus in this configuration when the device is fully operation. More...
  *Interface.libusb_interface_Array;_Array ; Array of interfaces supported by this configuration. More...
  *extra                      ; Extra descriptors. More...
  extra_length.l              ; Length of the extra descriptors, in bytes. More...
EndStructure


Structure libusb_ss_endpoint_companion_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t             ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t     ; Descriptor type. More...
  bMaxBurst.uint8_t           ; The maximum number of packets the endpoint can send Or receive As part of a burst
  bmAttributes.uint8_t        ; In bulk EP: bits 4:0 represents the maximum number of streams the EP supports. More...
  wBytesPerInterval.uint16_t  ; The total number of bytes this EP will transfer every service interval. More...
EndStructure


Structure libusb_bos_dev_capability_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t                                 ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t                         ; Descriptor type. More...
  bDevCapabilityType.uint8_t                      ; Device Capability type. 
  dev_capability_data.uint8_t[#LIBUSB_FLEXIBLE_ARRAY]  ; Device Capability Data (bLength - 3 bytes) 
EndStructure


Structure libusb_bos_descriptor Align #PB_Structure_AlignC 
  bLength.a         ; Size of this descriptor (in bytes)
  bDescriptorType.a ; Descriptor type. More...
  wTotalLength.w    ; Length of this descriptor And all of its sub descriptors.
  bNumDeviceCaps.a  ; The number of separate device capability descriptors in the BOS.
  *dev_capability.libusb_bos_dev_capability_descriptor[#LIBUSB_FLEXIBLE_ARRAY] ; bNumDeviceCap Device Capability Descriptors 
EndStructure


Structure libusb_usb_2_0_extension_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t             ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t     ; Descriptor type. More...
  bDevCapabilityType.uint8_t  ; Capability type. More...
  bmAttributes.uint32_t       ; Bitmap encoding of supported device level features. More...
EndStructure


Structure libusb_ss_usb_device_capability_descriptor Align #PB_Structure_AlignC 
  bLength.uint8_t               ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t       ; Descriptor type. More...
  bDevCapabilityType.uint8_t    ; Capability type. More...
  bmAttributes.uint8_t          ; Bitmap encoding of supported device level features. More...
  wSpeedSupported.uint16_t      ; Bitmap encoding of the speed supported by this device when operating in SuperSpeed mode. More...
  bFunctionalitySupport.uint8_t ; The lowest speed at which all the functionality supported by the device is available To the user. More...
  bU1DevExitLat.uint8_t         ; U1 Device Exit Latency.
  bU2DevExitLat.uint16_t        ; U2 Device Exit Latency. 
EndStructure


Structure libusb_container_id_descriptor Align #PB_Structure_AlignC
  bLength.uint8_t             ; Size of this descriptor (in bytes)
  bDescriptorType.uint8_t     ; Descriptor type. More...
  bDevCapabilityType.uint8_t  ; Capability type. More...
  bReserved.uint8_t           ; Reserved field.
  ContainerID.uint8_t[16]     ; 128 bit UUID
EndStructure


Structure libusb_platform_descriptor Align #PB_Structure_AlignC
	bLength.uint8_t ; Size of this descriptor (in bytes)
  
	; Descriptor type. Will have value
	; \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY
	; LIBUSB_DT_DEVICE_CAPABILITY in this context.
	bDescriptorType.uint8_t
  
	; Capability type. Will have value
	; \ref libusb_capability_type::LIBUSB_BT_PLATFORM_DESCRIPTOR
	; LIBUSB_BT_CONTAINER_ID in this context.
	bDevCapabilityType.uint8_t
	
	bReserved.uint8_t ; Reserved field
	PlatformCapabilityUUID.uint8_t[16]  ; 128 bit UUID
	CapabilityData.uint8_t[#LIBUSB_FLEXIBLE_ARRAY]  ; Capability Data (bLength - 20)
EndStructure


Structure libusb_control_setup Align #PB_Structure_AlignC 
  bmRequestType.uint8_t ; Request type. More...
  bRequest.uint8_t      ; Request. More...
  wValue.uint16_t       ; Value. More...
  wIndex.uint16_t       ; Index. More...
  wLength.uint16_t      ; Number of bytes To transfer. 
EndStructure

#LIBUSB_CONTROL_SETUP_SIZE = (SizeOf(libusb_control_setup))


; libusb

Structure libusb_context
EndStructure


Structure libusb_device
EndStructure

; PB
Structure libusb_device_array
  dev.i[0]
EndStructure


Structure libusb_device_handle
EndStructure


Structure libusb_version Align #PB_Structure_AlignC 
  major.u   ;	Library major version.
  minor.u   ; Library minor version.
  micro.u   ; Library micro version.
  nano.u    ; Library nano version.
  *rc       ; Library release candidate suffix string, e.g. More...
  *describe ; For ABI compatibility only. 
EndStructure


Enumeration libusb_speed
  #LIBUSB_SPEED_UNKNOWN = 0    ; The OS doesn't report or know the device speed.
  #LIBUSB_SPEED_LOW = 1        ; The device is operating at low speed (1.5MBit/s).
  #LIBUSB_SPEED_FULL = 2       ; The device is operating at full speed (12MBit/s).
  #LIBUSB_SPEED_HIGH = 3       ; The device is operating at high speed (480MBit/s).
  #LIBUSB_SPEED_SUPER = 4      ; The device is operating at super speed (5000MBit/s).
  #LIBUSB_SPEED_SUPER_PLUS = 5 ; The device is operating at super speed plus (10000MBit/s). 
EndEnumeration


Enumeration libusb_error
  #LIBUSB_SUCCESS 	          = 0   ; Success (no error)
  #LIBUSB_ERROR_IO            = -1  ; Input/output error.
  #LIBUSB_ERROR_INVALID_PARAM = -2  ; Invalid parameter.
  #LIBUSB_ERROR_ACCESS        = -3  ; Access denied (insufficient permissions)
  #LIBUSB_ERROR_NO_DEVICE     = -4  ; No such device (it may have been disconnected)
  #LIBUSB_ERROR_NOT_FOUND     = -5  ; Entity Not found.
  #LIBUSB_ERROR_BUSY          = -6  ; Resource busy.
  #LIBUSB_ERROR_TIMEOUT       = -7  ; Operation timed out.
  #LIBUSB_ERROR_OVERFLOW      = -8  ; Overflow.
  #LIBUSB_ERROR_PIPE          = -9  ; Pipe error.
  #LIBUSB_ERROR_INTERRUPTED   = -10 ; System call interrupted (perhaps due To signal)
  #LIBUSB_ERROR_NO_MEM        = -11 ; Insufficient memory.
  #LIBUSB_ERROR_NOT_SUPPORTED = -12 ; Operation Not supported Or unimplemented on this platform.
  #LIBUSB_ERROR_OTHER         = -99 ; Other error.
EndEnumeration

#LIBUSB_ERROR_COUNT = 14


Enumeration libusb_transfer_type
  #LIBUSB_TRANSFER_TYPE_CONTROL = 0     ; Control transfer.
  #LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1 ; Isochronous transfer.
  #LIBUSB_TRANSFER_TYPE_BULK = 2        ; Bulk transfer.
  #LIBUSB_TRANSFER_TYPE_INTERRUPT = 3   ; Interrupt transfer.
  #LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4 ; Bulk stream transfer. 
EndEnumeration


Enumeration libusb_transfer_status
  #LIBUSB_TRANSFER_COMPLETED  ; Transfer completed without error.
  #LIBUSB_TRANSFER_ERROR      ; Transfer failed.
  #LIBUSB_TRANSFER_TIMED_OUT  ; Transfer timed out.
  #LIBUSB_TRANSFER_CANCELLED  ; Transfer was cancelled.
  #LIBUSB_TRANSFER_STALL      ; For bulk/interrupt endpoints: halt condition detected (endpoint stalled).
  #LIBUSB_TRANSFER_NO_DEVICE  ; Device was disconnected.
  #LIBUSB_TRANSFER_OVERFLOW   ; Device sent more Data than requested. 
EndEnumeration


Enumeration libusb_transfer_flags
  #LIBUSB_TRANSFER_SHORT_NOT_OK = (1 << 0)    ; Report short frames As errors.
  #LIBUSB_TRANSFER_FREE_BUFFER = (1 << 1)     ; Automatically free() transfer buffer during libusb_free_transfer().
  #LIBUSB_TRANSFER_FREE_TRANSFER = (1 << 2)   ; Automatically call libusb_free_transfer() after callback returns.
  #LIBUSB_TRANSFER_ADD_ZERO_PACKET = (1 << 3) ; Terminate transfers that are a multiple of the endpoint's wMaxPacketSize with an extra zero length packet
EndEnumeration


Structure libusb_iso_packet_descriptor Align #PB_Structure_AlignC 
  length.l          ; Length of Data To request in this packet.
  actual_length.l   ; Amount of Data that was actually transferred.
  status.l          ; Status code For this packet. 
EndStructure


Prototype Prototype_libusb_transfer_cb_fn(*transfer)

Structure libusb_transfer Align #PB_Structure_AlignC 
  *dev_handle     ; Handle of the device that this transfer will be submitted To.
  flags.uint8_t   ; A bitwise Or combination of libusb_transfer_flags.
  endpoint.a      ; Address of the endpoint where this transfer will be sent.
  type.a          ; Type of the transfer from libusb_transfer_type.
  timeout.l       ; Timeout For this transfer in milliseconds. More...
  status.l        ; The status of the transfer. More...
  length.l        ; Length of the Data buffer. More...
  actual_length.l ; Actual length of Data that was transferred. More...
  callback.Prototype_libusb_transfer_cb_fn  ; Callback function. More...
  *user_data                                ; User context Data. More...
  *buffer                                   ; Data buffer.
  num_iso_packets.l                         ; Number of isochronous packets. More...
  iso_packet_desc.libusb_iso_packet_descriptor[#LIBUSB_FLEXIBLE_ARRAY] ; Isochronous packet descriptors, For isochronous transfers only. 
EndStructure


Enumeration libusb_capability
  #LIBUSB_CAP_HAS_CAPABILITY                = $0000 ; The libusb_has_capability() API is available.
  #LIBUSB_CAP_HAS_HOTPLUG                   = $0001 ; Hotplug support is available on this platform.
  #LIBUSB_CAP_HAS_HID_ACCESS                = $0100 ; The library can access HID devices without requiring user intervention.
  #LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = $0101 ; The library supports detaching of the Default USB driver, using libusb_detach_kernel_driver(), If one is set by the OS kernel.
EndEnumeration


Enumeration libusb_log_level
  #LIBUSB_LOG_LEVEL_NONE = 0   ; No messages ever emitted by the library (Default)
  #LIBUSB_LOG_LEVEL_ERROR = 1  ; Error messages are emitted
  #LIBUSB_LOG_LEVEL_WARNING = 2; Warning And error messages are emitted
  #LIBUSB_LOG_LEVEL_INFO = 3   ; Informational, warning And error messages are emitted
  #LIBUSB_LOG_LEVEL_DEBUG = 4  ; All messages are emitted
EndEnumeration


Enumeration libusb_log_cb_mode
  #LIBUSB_LOG_CB_GLOBAL = (1 << 0)   ; Callback function handling all log messages.
  #LIBUSB_LOG_CB_CONTEXT = (1 << 1)  ; Callback function handling context related log messages.
EndEnumeration


Enumeration libusb_option
  #LIBUSB_OPTION_LOG_LEVEL = 0  ; Set the log message verbosity.
  #LIBUSB_OPTION_USE_USBDK = 1  ; Use the UsbDk backend For a specific context, If available.
  #LIBUSB_OPTION_NO_DEVICE_DISCOVERY = 2 ; Do Not scan For devices. 
  #LIBUSB_OPTION_WEAK_AUTHORITY = #LIBUSB_OPTION_NO_DEVICE_DISCOVERY
  #LIBUSB_OPTION_LOG_CB = 3
  #LIBUSB_OPTION_MAX = 4
EndEnumeration


Prototype Prototype_libusb_log_cb(*ctx, level.l, str.p-Ascii)

Structure libusb_init_option_value
  StructureUnion
    ival.i
    log_cbval.Prototype_libusb_log_cb
  EndStructureUnion
EndStructure

Structure libusb_init_option
  ; Which option To set
  option.i 
  ; An integer value used by the option (If applicable).
  value.libusb_init_option_value
EndStructure



Prototype Prototype_libusb_init(*ctx)
Global _libusb_init.Prototype_libusb_init
Prototype.l Prototype_libusb_init_context(*ctx, *options.libusb_init_option, num_options.l)
Global _libusb_init_context.Prototype_libusb_init_context
Prototype Prototype_libusb_exit(*ctx)
Global libusb_exit.Prototype_libusb_exit
Prototype.l Prototype_libusb_set_debug(*ctx, level.l)
Global libusb_set_debug.Prototype_libusb_set_debug
Prototype Prototype_libusb_set_log_cb(*ctx, *cb.Prototype_libusb_log_cb, mode.l)
Global libusb_set_log_cb.Prototype_libusb_set_log_cb
Prototype.i Prototype_libusb_get_version()
Global libusb_get_version.Prototype_libusb_get_version
Prototype.l Prototype_libusb_has_capability(capability.uint32_t)
Global libusb_has_capability.Prototype_libusb_has_capability
Prototype.i Prototype_libusb_error_name(error_code.l)
Global _libusb_error_name.Prototype_libusb_error_name
Prototype.l Prototype_libusb_setlocale(locale.p-Ascii)
Global libusb_setlocale.Prototype_libusb_setlocale
Prototype.i Prototype_libusb_strerror(errcode.l)
Global _libusb_strerror.Prototype_libusb_strerror

Prototype.l Prototype_libusb_get_device_list(*ctx, *List)
Global libusb_get_device_list.Prototype_libusb_get_device_list
Prototype Prototype_libusb_free_device_list(*List, unref_devices.l)
Global libusb_free_device_list.Prototype_libusb_free_device_list
Prototype.i Prototype_libusb_ref_device(*dev)
Global libusb_ref_device.Prototype_libusb_ref_device
Prototype Prototype_libusb_unref_device(*dev)
Global libusb_unref_device.Prototype_libusb_unref_device

Prototype.l Prototype_libusb_get_configuration(*dev_handle, *config)
Global libusb_get_configuration.Prototype_libusb_get_configuration
Prototype.l Prototype_libusb_get_device_descriptor(*dev, *desc.libusb_device_descriptor)
Global libusb_get_device_descriptor.Prototype_libusb_get_device_descriptor
Prototype.l Prototype_libusb_get_active_config_descriptor(*dev, *pconfig)
Global libusb_get_active_config_descriptor.Prototype_libusb_get_active_config_descriptor
Prototype.l Prototype_libusb_get_config_descriptor(*dev, config_index.uint8_t, *pconfig)
Global libusb_get_config_descriptor.Prototype_libusb_get_config_descriptor
Prototype.l Prototype_libusb_get_config_descriptor_by_value(*dev, bConfigurationValue.uint8_t, *pconfig)
Global libusb_get_config_descriptor_by_value.Prototype_libusb_get_config_descriptor_by_value
Prototype Prototype_libusb_free_config_descriptor(*config.libusb_config_descriptor)
Global libusb_free_config_descriptor.Prototype_libusb_free_config_descriptor
Prototype.l Prototype_libusb_get_ss_endpoint_companion_descriptor(*ctx, *endpoint.libusb_endpoint_descriptor, *ep_comp)
Global libusb_get_ss_endpoint_companion_descriptor.Prototype_libusb_get_ss_endpoint_companion_descriptor
Prototype Prototype_libusb_free_ss_endpoint_companion_descriptor(*ep_comp.libusb_ss_endpoint_companion_descriptor)
Global libusb_free_ss_endpoint_companion_descriptor.Prototype_libusb_free_ss_endpoint_companion_descriptor
Prototype.l Prototype_libusb_get_bos_descriptor(*dev_handle, *bos)
Global libusb_get_bos_descriptor.Prototype_libusb_get_bos_descriptor
Prototype Prototype_libusb_free_bos_descriptor(*bos.libusb_bos_descriptor)
Global libusb_free_bos_descriptor.Prototype_libusb_free_bos_descriptor
Prototype.l Prototype_libusb_get_usb_2_0_extension_descriptor(*ctx, *dev_cap.libusb_bos_dev_capability_descriptor, *usb_2_0_extension)
Global libusb_get_usb_2_0_extension_descriptor.Prototype_libusb_get_usb_2_0_extension_descriptor
Prototype Prototype_libusb_free_usb_2_0_extension_descriptor(*usb_2_0_extension.libusb_usb_2_0_extension_descriptor)
Global libusb_free_usb_2_0_extension_descriptor.Prototype_libusb_free_usb_2_0_extension_descriptor
Prototype.l Prototype_libusb_get_ss_usb_device_capability_descriptor(*ctx, *dev_cap.libusb_bos_dev_capability_descriptor, *ss_usb_device_cap)
Global libusb_get_ss_usb_device_capability_descriptor.Prototype_libusb_get_ss_usb_device_capability_descriptor
Prototype Prototype_libusb_free_ss_usb_device_capability_descriptor(*ss_usb_device_cap.libusb_ss_usb_device_capability_descriptor)
Global libusb_free_ss_usb_device_capability_descriptor.Prototype_libusb_free_ss_usb_device_capability_descriptor
Prototype.l Prototype_libusb_get_container_id_descriptor(*ctx, *dev_cap.libusb_bos_dev_capability_descriptor, *container_id)
Global libusb_get_container_id_descriptor.Prototype_libusb_get_container_id_descriptor
Prototype Prototype_libusb_free_container_id_descriptor(*container_id.libusb_container_id_descriptor)
Global libusb_free_container_id_descriptor.Prototype_libusb_free_container_id_descriptor
Prototype.l Prototype_libusb_get_platform_descriptor(*ctx, *dev_cap.libusb_bos_dev_capability_descriptor, *platform_descriptor)
Global libusb_get_platform_descriptor.Prototype_libusb_get_platform_descriptor
Prototype Prototype_libusb_free_platform_descriptor(*platform_descriptor.libusb_platform_descriptor)
Global libusb_free_platform_descriptor.Prototype_libusb_free_platform_descriptor
Prototype.uint8_t Prototype_libusb_get_bus_number(*dev)
Global libusb_get_bus_number.Prototype_libusb_get_bus_number
Prototype.uint8_t Prototype_libusb_get_port_number(*dev)
Global libusb_get_port_number.Prototype_libusb_get_port_number
Prototype.l Prototype_libusb_get_port_numbers(*dev, *port_numbers, port_numbers_len.l)
Global libusb_get_port_numbers.Prototype_libusb_get_port_numbers
Prototype.l Prototype_libusb_get_port_path(*ctx, *dev, *port_numbers, port_numbers_len.uint8_t)  ; deprecated: use libusb_get_port_numbers()
Global libusb_get_port_path.Prototype_libusb_get_port_path
Prototype.i Prototype_libusb_get_parent(*dev)
Global libusb_get_parent.Prototype_libusb_get_parent
Prototype.uint8_t Prototype_libusb_get_device_address(*dev)
Global libusb_get_device_address.Prototype_libusb_get_device_address
Prototype.l Prototype_libusb_get_device_speed(*dev)
Global libusb_get_device_speed.Prototype_libusb_get_device_speed
Prototype.l Prototype_libusb_get_max_packet_size(*dev, endpoint.a	)
Global libusb_get_max_packet_size.Prototype_libusb_get_max_packet_size
Prototype.l Prototype_libusb_get_max_iso_packet_size(*dev, endpoint.a)
Global libusb_get_max_iso_packet_size.Prototype_libusb_get_max_iso_packet_size
Prototype.l Prototype_libusb_get_max_alt_packet_size(*dev, interface_number.l, alternate_setting.l, endpoint.a)
Global libusb_get_max_alt_packet_size.Prototype_libusb_get_max_alt_packet_size

Prototype.l Prototype_libusb_get_interface_association_descriptors(*dev, config_index.uint8_t, *iad_array)
Global libusb_get_interface_association_descriptors.Prototype_libusb_get_interface_association_descriptors
Prototype.l Prototype_libusb_get_active_interface_association_descriptors(*dev, *iad_array)
Global libusb_get_active_interface_association_descriptors.Prototype_libusb_get_active_interface_association_descriptors
Prototype Prototype_libusb_free_interface_association_descriptors(*iad_array.libusb_interface_association_descriptor_array)
Global libusb_free_interface_association_descriptors.Prototype_libusb_free_interface_association_descriptors

Prototype.l Prototype_libusb_wrap_sys_device(*ctx, sys_dev.i, *dev_handle)
Global libusb_wrap_sys_device.Prototype_libusb_wrap_sys_device
Prototype.l Prototype_libusb_open(*dev, *pdev_handle)
Global libusb_open.Prototype_libusb_open
Prototype Prototype_libusb_close(*dev_handle)
Global libusb_close.Prototype_libusb_close
Prototype.i Prototype_libusb_get_device(*dev_handle)
Global libusb_get_device.Prototype_libusb_get_device

Prototype.l Prototype_libusb_set_configuration(*dev_handle, configuration.l)
Global libusb_set_configuration.Prototype_libusb_set_configuration
Prototype.l Prototype_libusb_claim_interface(*dev_handle, interface_number.l)
Global libusb_claim_interface.Prototype_libusb_claim_interface
Prototype.l Prototype_libusb_release_interface(*dev_handle, interface_number.l)
Global libusb_release_interface.Prototype_libusb_release_interface

Prototype.i Prototype_libusb_open_device_with_vid_pid(*ctx, vendor_id.uint16_t, product_id.uint16_t)
Global libusb_open_device_with_vid_pid.Prototype_libusb_open_device_with_vid_pid

Prototype.l Prototype_libusb_set_interface_alt_setting(*dev_handle, interface_number.l, alternate_setting.l)
Global libusb_set_interface_alt_setting.Prototype_libusb_set_interface_alt_setting
Prototype.l Prototype_libusb_clear_halt(*dev_handle, endpoint.a)
Global libusb_clear_halt.Prototype_libusb_clear_halt
Prototype.l Prototype_libusb_reset_device(*dev_handle)
Global libusb_reset_device.Prototype_libusb_reset_device

Prototype.l Prototype_libusb_alloc_streams(*dev_handle, num_streams.uint32_t, endpoints.p-Ascii, num_endpoints.l)
Global libusb_alloc_streams.Prototype_libusb_alloc_streams
Prototype.l Prototype_libusb_free_streams(*dev_handle, Array endpoints(1), num_endpoints.l)
Global libusb_free_streams.Prototype_libusb_free_streams

Prototype.i Prototype_libusb_dev_mem_alloc(*dev_handle, length.size_t)
Global libusb_dev_mem_alloc.Prototype_libusb_dev_mem_alloc
Prototype.l Prototype_libusb_dev_mem_free(*dev_handle, *buffer, length.size_t)
Global libusb_dev_mem_free.Prototype_libusb_dev_mem_free


Prototype.l Prototype_libusb_kernel_driver_active(*dev_handle, interface_number.l)
Global libusb_kernel_driver_active.Prototype_libusb_kernel_driver_active
Prototype.l Prototype_libusb_detach_kernel_driver(*dev_handle, interface_number.l)
Global libusb_detach_kernel_driver.Prototype_libusb_detach_kernel_driver
Prototype.l Prototype_libusb_attach_kernel_driver(*dev_handle, interface_number.l)
Global libusb_attach_kernel_driver.Prototype_libusb_attach_kernel_driver
Prototype.l Prototype_libusb_set_auto_detach_kernel_driver(*dev_handle, enable.l)
Global libusb_set_auto_detach_kernel_driver.Prototype_libusb_set_auto_detach_kernel_driver

; async I/O

Procedure.i libusb_control_transfer_get_data(*transfer.libusb_transfer)
	ProcedureReturn *transfer\buffer + #LIBUSB_CONTROL_SETUP_SIZE
EndProcedure

Procedure.i libusb_control_transfer_get_setup(*transfer.libusb_transfer)
	ProcedureReturn *transfer\buffer
EndProcedure

Procedure libusb_fill_control_setup(*buffer, bmRequestType.uint8_t, bRequest.uint8_t, wValue.uint16_t, wIndex.uint16_t, wLength.uint16_t)
  
  Protected *setup.libusb_control_setup
  
  
  *setup = *buffer
	*setup\bmRequestType = bmRequestType
	*setup\bRequest = bRequest
	*setup\wValue = libusb_cpu_to_le16(wValue)
	*setup\wIndex = libusb_cpu_to_le16(wIndex)
	*setup\wLength = libusb_cpu_to_le16(wLength)
	
EndProcedure

Prototype.i Prototype_libusb_alloc_transfer(iso_packets.l)
Global libusb_alloc_transfer.Prototype_libusb_alloc_transfer
Prototype.l Prototype_libusb_submit_transfer(*transfer.libusb_transfer)
Global libusb_submit_transfer.Prototype_libusb_submit_transfer
Prototype.l Prototype_libusb_cancel_transfer(*transfer.libusb_transfer)
Global libusb_cancel_transfer.Prototype_libusb_cancel_transfer
Prototype Prototype_libusb_free_transfer(*transfer.libusb_transfer)
Global libusb_free_transfer.Prototype_libusb_free_transfer
Prototype Prototype_libusb_transfer_set_stream_id(*transfer.libusb_transfer, stream_id.uint32_t)
Global libusb_transfer_set_stream_id.Prototype_libusb_transfer_set_stream_id
Prototype.uint32_t Prototype_libusb_transfer_get_stream_id(*transfer.libusb_transfer)
Global libusb_transfer_get_stream_id.Prototype_libusb_transfer_get_stream_id

Procedure libusb_fill_control_transfer(*transfer.libusb_transfer, *dev_handle.libusb_device_handle, *buffer, callback.Prototype_libusb_transfer_cb_fn, *user_data, timeout.l)
  
  Protected *setup.libusb_control_setup
  
	*setup = *buffer
	*transfer\dev_handle = *dev_handle
	*transfer\endpoint = 0
	*transfer\type = #LIBUSB_TRANSFER_TYPE_CONTROL
	*transfer\timeout = timeout
	*transfer\buffer = *buffer
	If *setup
	  *transfer\length = #LIBUSB_CONTROL_SETUP_SIZE + libusb_le16_to_cpu(*setup\wLength)
	EndIf
	*transfer\user_data = *user_data
	*transfer\callback = callback
EndProcedure

Procedure libusb_fill_bulk_transfer(*transfer.libusb_transfer, *dev_handle.libusb_device_handle, endpoint.a, *buffer, length.l, callback.Prototype_libusb_transfer_cb_fn,	*user_data, timeout.l)
  
	*transfer\dev_handle = *dev_handle
	*transfer\endpoint = endpoint
	*transfer\type = #LIBUSB_TRANSFER_TYPE_BULK
	*transfer\timeout = timeout
	*transfer\buffer = *buffer
	*transfer\length = length
	*transfer\user_data = *user_data
	*transfer\callback = callback
	
EndProcedure

Procedure libusb_fill_bulk_stream_transfer(*transfer.libusb_transfer, *dev_handle.libusb_device_handle, endpoint.a, stream_id.uint32_t, *buffer, length.l, callback.Prototype_libusb_transfer_cb_fn, *user_data, timeout.l)
  
	libusb_fill_bulk_transfer(*transfer, *dev_handle, endpoint, *buffer, length, callback, *user_data, timeout)
	*transfer\type = #LIBUSB_TRANSFER_TYPE_BULK_STREAM
	libusb_transfer_set_stream_id(*transfer, stream_id)
	
EndProcedure

Procedure libusb_fill_interrupt_transfer(*transfer.libusb_transfer, *dev_handle.libusb_device_handle, endpoint.a, *buffer, length.l, callback.Prototype_libusb_transfer_cb_fn, *user_data, timeout.l)
  
	*transfer\dev_handle = *dev_handle
	*transfer\endpoint = endpoint
	*transfer\type = #LIBUSB_TRANSFER_TYPE_INTERRUPT
	*transfer\timeout = timeout
	*transfer\buffer = *buffer
	*transfer\length = length
	*transfer\user_data = *user_data
	*transfer\callback = callback
	
EndProcedure

Procedure libusb_fill_iso_transfer(*transfer.libusb_transfer, *dev_handle.libusb_device_handle, endpoint.a,	*buffer, length.l, num_iso_packets.l,	callback.Prototype_libusb_transfer_cb_fn, *user_data, timeout.l)
  
	*transfer\dev_handle = *dev_handle
	*transfer\endpoint = endpoint
	*transfer\type = #LIBUSB_TRANSFER_TYPE_ISOCHRONOUS
	*transfer\timeout = timeout
	*transfer\buffer = *buffer
	*transfer\length = length
	*transfer\num_iso_packets = num_iso_packets
	*transfer\user_data = *user_data
	*transfer\callback = callback
	
EndProcedure

Procedure libusb_set_iso_packet_lengths(*transfer.libusb_transfer, length.l)
  
  Protected.i i

	For i = 0 To *transfer\num_iso_packets - 1
	  *transfer\iso_packet_desc[i]\length = length
	Next i
	
EndProcedure

Procedure.i libusb_get_iso_packet_buffer(*transfer.libusb_transfer, packet.l)
  
	Protected i.i
	Protected offset.i
	Protected _packet.i
  
	
	If packet > 2147483647
	  ProcedureReturn #Null
	EndIf
	_packet = packet

	If _packet >= *transfer\num_iso_packets
	  ProcedureReturn #Null
	EndIf

	For i = 0 To _packet - 1
	  offset + *transfer\iso_packet_desc[i]\length
	Next i

  ProcedureReturn *transfer\buffer + offset
		
EndProcedure

Procedure.i libusb_get_iso_packet_buffer_simple(*transfer.libusb_transfer, packet.l)
  
	Protected _packet.i
	
	
	If packet > 2147483647
	  ProcedureReturn #Null
	EndIf
	_packet = packet

	If _packet >= *transfer\num_iso_packets
	  ProcedureReturn #Null
	EndIf

  ProcedureReturn *transfer\buffer + *transfer\iso_packet_desc[0]\length * _packet
	
EndProcedure

Prototype.l Prototype_libusb_control_transfer(*dev_handle, bmRequestType.uint8_t, bRequest.uint8_t, wValue.uint16_t, wIndex.uint16_t, *Data, wLength.uint16_t, timeout.l)
Global libusb_control_transfer.Prototype_libusb_control_transfer

Prototype.l Prototype_libusb_bulk_transfer(*dev_handle, endpoint.a, *Data, length.l, *transferred, timeout.l) 	
Global libusb_bulk_transfer.Prototype_libusb_bulk_transfer
Prototype.l Prototype_libusb_interrupt_transfer(*dev_handle, endpoint.a, *Data, length.l, *transferred.Long, timeout.l)
Global libusb_interrupt_transfer.Prototype_libusb_interrupt_transfer

Procedure.l libusb_get_descriptor(*dev_handle.libusb_device_handle, desc_type.uint8_t, desc_index.uint8_t, *Data, length.l)
  
  ProcedureReturn libusb_control_transfer(*dev_handle, #LIBUSB_ENDPOINT_IN, #LIBUSB_REQUEST_GET_DESCRIPTOR, ((desc_type << 8) | desc_index), 0, *Data, length, 1000)
  
EndProcedure

Procedure.l libusb_get_string_descriptor(*dev_handle.libusb_device_handle, desc_index.uint8_t, langid.uint16_t, *Data, length.l)
  
  ProcedureReturn libusb_control_transfer(*dev_handle, #LIBUSB_ENDPOINT_IN, #LIBUSB_REQUEST_GET_DESCRIPTOR, (#LIBUSB_DT_STRING << 8) | desc_index, langid, *Data, length, 1000)
  
EndProcedure

Prototype.l Prototype_libusb_get_string_descriptor_ascii(*dev_handle, desc_index.uint8_t, *Data, length.l)
Global libusb_get_string_descriptor_ascii.Prototype_libusb_get_string_descriptor_ascii

; polling And timeouts

Prototype.l Prototype_libusb_try_lock_events(*ctx)
Global libusb_try_lock_events.Prototype_libusb_try_lock_events
Prototype Prototype_libusb_lock_events(*ctx)
Global libusb_lock_events.Prototype_libusb_lock_events
Prototype Prototype_libusb_unlock_events(*ctx)
Global libusb_unlock_events.Prototype_libusb_unlock_events
Prototype.l Prototype_libusb_event_handling_ok(*ctx)
Global libusb_event_handling_ok.Prototype_libusb_event_handling_ok
Prototype.l Prototype_libusb_event_handler_active(*ctx)
Global libusb_event_handler_active.Prototype_libusb_event_handler_active
Prototype Prototype_libusb_interrupt_event_handler(*ctx)
Global libusb_interrupt_event_handler.Prototype_libusb_interrupt_event_handler
Prototype Prototype_libusb_lock_event_waiters(*ctx)
Global libusb_lock_event_waiters.Prototype_libusb_lock_event_waiters
Prototype Prototype_libusb_unlock_event_waiters(*ctx)
Global libusb_unlock_event_waiters.Prototype_libusb_unlock_event_waiters
Prototype.l Prototype_libusb_wait_for_event(*ctx, *tv.timeval)
Global libusb_wait_for_event.Prototype_libusb_wait_for_event

Prototype.l Prototype_libusb_handle_events_timeout(*ctx, *tv.timeval)
Global libusb_handle_events_timeout.Prototype_libusb_handle_events_timeout
Prototype.l Prototype_libusb_handle_events_timeout_completed(*ctx, *tv.timeval, *completed.Long)
Global libusb_handle_events_timeout_completed.Prototype_libusb_handle_events_timeout_completed
Prototype.l Prototype_libusb_handle_events(*ctx)
Global libusb_handle_events.Prototype_libusb_handle_events
Prototype.l Prototype_libusb_handle_events_completed(*ctx, *completed.Long)
Global libusb_handle_events_completed.Prototype_libusb_handle_events_completed
Prototype.l Prototype_libusb_handle_events_locked(*ctx, *tv.timeval)
Global libusb_handle_events_locked.Prototype_libusb_handle_events_locked
Prototype.l Prototype_libusb_pollfds_handle_timeouts(*ctx)
Global libusb_pollfds_handle_timeouts.Prototype_libusb_pollfds_handle_timeouts
Prototype.l Prototype_libusb_get_next_timeout(*ctx, *tv.timeval)
Global libusb_get_next_timeout.Prototype_libusb_get_next_timeout

Structure libusb_pollfd Align #PB_Structure_AlignC 
  fd.l          ;	Numeric file descriptor.
  events.short  ; Event flags To poll For from <poll.h>. More..
EndStructure

Prototype Prototype_libusb_pollfd_added_cb(fd.l, events.w, *user_data)
Prototype Prototype_libusb_pollfd_removed_cb(fd.l, *user_data)

Prototype.i Prototype_libusb_get_pollfds(*ctx)
Global libusb_get_pollfds.Prototype_libusb_get_pollfds
Prototype Prototype_libusb_free_pollfds(*pollfds)
Global libusb_free_pollfds.Prototype_libusb_free_pollfds
Prototype Prototype_libusb_set_pollfd_notifiers(*ctx, added_cb.Prototype_libusb_pollfd_added_cb, removed_cb.Prototype_libusb_pollfd_removed_cb, *user_data)
Global libusb_set_pollfd_notifiers.Prototype_libusb_set_pollfd_notifiers

Macro libusb_hotplug_callback_handle
  l
EndMacro

Enumeration libusb_hotplug_event
	; A device has been plugged in And is ready To use
	#LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = (1 << 0)

	; A device has left And is no longer available.
	; It is the user's responsibility to call libusb_close on any handle associated with a disconnected device.
	; It is safe To call libusb_get_device_descriptor on a device that has left
	#LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = (1 << 1)
EndEnumeration

Enumeration libusb_hotplug_flag
	; Arm the callback And fire it For all matching currently attached devices.
	#LIBUSB_HOTPLUG_ENUMERATE = (1 << 0)
EndEnumeration

#LIBUSB_HOTPLUG_NO_FLAGS = 0

#LIBUSB_HOTPLUG_MATCH_ANY = -1

Prototype Prototype_libusb_hotplug_callback_fn(*ctx, *device, event.l, *user_data)

Prototype.l Prototype_libusb_hotplug_register_callback(*ctx, events.l, flags.l, vendor_id.l, product_id.l, dev_class.l, cb_fn.Prototype_libusb_hotplug_callback_fn, *user_data, *callback_handle)
Global libusb_hotplug_register_callback.Prototype_libusb_hotplug_register_callback
Prototype.l Prototype_libusb_hotplug_deregister_callback(*ctx, callback_handle.libusb_hotplug_callback_handle)
Global libusb_hotplug_deregister_callback.Prototype_libusb_hotplug_deregister_callback
Prototype Prototype_libusb_hotplug_get_user_data(*ctx, callback_handle.libusb_hotplug_callback_handle)
Global libusb_hotplug_get_user_data.Prototype_libusb_hotplug_get_user_data

Prototype.l Prototype_libusb_set_option(*ctx, option.l, p0=0, p1=0, p3=0)
Global libusb_set_option.Prototype_libusb_set_option



Global libusb.i


Procedure.i UseLibusb()
  
  If Not IsLibrary(libusb)
    
    CompilerSelect #PB_Compiler_OS
      CompilerCase #PB_OS_Windows
        libusb = OpenLibrary(#PB_Any, "libusb-1.0.dll")
        
      CompilerCase #PB_OS_Linux
        libusb = OpenLibrary(#PB_Any, "libusb-1.0.so.0")
          
    CompilerEndSelect
    
    If libusb
      
      _libusb_init = GetFunction(libusb, "libusb_init")
      _libusb_init_context = GetFunction(libusb, "libusb_init_context")
      libusb_exit = GetFunction(libusb, "libusb_exit")
      libusb_set_debug = GetFunction(libusb, "libusb_set_debug")
      libusb_set_log_cb = GetFunction(libusb, "libusb_set_log_cb")
      libusb_get_version = GetFunction(libusb, "libusb_get_version")
      libusb_has_capability = GetFunction(libusb, "libusb_has_capability")
      _libusb_error_name = GetFunction(libusb, "libusb_error_name")
      libusb_setlocale = GetFunction(libusb, "libusb_setlocale")
      _libusb_strerror = GetFunction(libusb, "libusb_strerror")
      
      libusb_get_device_list = GetFunction(libusb, "libusb_get_device_list")
      libusb_free_device_list = GetFunction(libusb, "libusb_free_device_list")
      libusb_ref_device = GetFunction(libusb, "libusb_ref_device")
      libusb_unref_device = GetFunction(libusb, "libusb_unref_device")
      
      libusb_get_configuration = GetFunction(libusb, "libusb_get_configuration")
      libusb_get_device_descriptor = GetFunction(libusb, "libusb_get_device_descriptor")
      libusb_get_active_config_descriptor = GetFunction(libusb, "libusb_get_active_config_descriptor")
      libusb_get_config_descriptor = GetFunction(libusb, "libusb_get_config_descriptor")
      libusb_get_config_descriptor_by_value = GetFunction(libusb, "libusb_get_config_descriptor_by_value")
      libusb_free_config_descriptor = GetFunction(libusb, "libusb_free_config_descriptor")
      libusb_get_ss_endpoint_companion_descriptor = GetFunction(libusb, "libusb_get_ss_endpoint_companion_descriptor")
      libusb_free_ss_endpoint_companion_descriptor = GetFunction(libusb, "libusb_free_ss_endpoint_companion_descriptor")
      libusb_get_bos_descriptor = GetFunction(libusb, "libusb_get_bos_descriptor")
      libusb_free_bos_descriptor = GetFunction(libusb, "libusb_free_bos_descriptor")
      libusb_get_usb_2_0_extension_descriptor = GetFunction(libusb, "libusb_get_usb_2_0_extension_descriptor")
      libusb_free_usb_2_0_extension_descriptor = GetFunction(libusb, "libusb_free_usb_2_0_extension_descriptor")
      libusb_get_ss_usb_device_capability_descriptor = GetFunction(libusb, "libusb_get_ss_usb_device_capability_descriptor")
      libusb_free_ss_usb_device_capability_descriptor = GetFunction(libusb, "libusb_free_ss_usb_device_capability_descriptor")
      libusb_get_container_id_descriptor = GetFunction(libusb, "libusb_get_container_id_descriptor")
      libusb_free_container_id_descriptor = GetFunction(libusb, "libusb_free_container_id_descriptor")
      libusb_get_platform_descriptor = GetFunction(libusb, "libusb_get_platform_descriptor")
      libusb_free_platform_descriptor = GetFunction(libusb, "libusb_free_platform_descriptor")
      libusb_get_bus_number = GetFunction(libusb, "libusb_get_bus_number")
      libusb_get_port_number = GetFunction(libusb, "libusb_get_port_number")
      libusb_get_port_numbers = GetFunction(libusb, "libusb_get_port_numbers")
      libusb_get_port_path = GetFunction(libusb, "libusb_get_port_path")
      libusb_get_device_address = GetFunction(libusb, "libusb_get_device_address")
      libusb_get_device_speed = GetFunction(libusb, "libusb_get_device_speed")
      libusb_get_max_packet_size = GetFunction(libusb, "libusb_get_max_packet_size")
      libusb_get_max_iso_packet_size = GetFunction(libusb, "libusb_get_max_iso_packet_size")
      libusb_get_max_alt_packet_size = GetFunction(libusb, "libusb_get_max_alt_packet_size")
      
      libusb_get_interface_association_descriptors = GetFunction(libusb, "libusb_get_interface_association_descriptors")
      libusb_get_active_interface_association_descriptors = GetFunction(libusb, "libusb_get_active_interface_association_descriptors")
      libusb_free_interface_association_descriptors = GetFunction(libusb, "libusb_free_interface_association_descriptors")
      
      libusb_wrap_sys_device = GetFunction(libusb, "libusb_wrap_sys_device")
      libusb_open = GetFunction(libusb, "libusb_open")
      libusb_close = GetFunction(libusb, "libusb_close")
      libusb_get_device = GetFunction(libusb, "libusb_get_device")
      
      libusb_set_configuration = GetFunction(libusb, "libusb_set_configuration")
      libusb_claim_interface = GetFunction(libusb, "libusb_claim_interface")
      libusb_release_interface = GetFunction(libusb, "libusb_release_interface")
      
      libusb_open_device_with_vid_pid = GetFunction(libusb, "libusb_open_device_with_vid_pid")
      
      libusb_set_interface_alt_setting = GetFunction(libusb, "libusb_set_interface_alt_setting")
      libusb_clear_halt = GetFunction(libusb, "libusb_clear_halt")
      libusb_reset_device = GetFunction(libusb, "libusb_reset_device")
      
      libusb_alloc_streams = GetFunction(libusb, "libusb_alloc_streams")
      libusb_free_streams = GetFunction(libusb, "libusb_free_streams")
      
      libusb_dev_mem_alloc = GetFunction(libusb, "libusb_dev_mem_alloc")
      libusb_dev_mem_free = GetFunction(libusb, "libusb_dev_mem_free")
      
      libusb_kernel_driver_active = GetFunction(libusb, "libusb_kernel_driver_active")
      libusb_detach_kernel_driver = GetFunction(libusb, "libusb_detach_kernel_driver")
      libusb_attach_kernel_driver = GetFunction(libusb, "libusb_attach_kernel_driver")
      libusb_set_auto_detach_kernel_driver = GetFunction(libusb, "libusb_set_auto_detach_kernel_driver")
      
      libusb_alloc_transfer = GetFunction(libusb, "libusb_alloc_transfer")
      libusb_submit_transfer = GetFunction(libusb, "libusb_submit_transfer")
      libusb_cancel_transfer = GetFunction(libusb, "libusb_cancel_transfer")
      libusb_free_transfer = GetFunction(libusb, "libusb_free_transfer")
      libusb_transfer_set_stream_id = GetFunction(libusb, "libusb_transfer_set_stream_id")
      libusb_transfer_get_stream_id = GetFunction(libusb, "libusb_transfer_get_stream_id")

      libusb_control_transfer = GetFunction(libusb, "libusb_control_transfer")
      
      libusb_bulk_transfer = GetFunction(libusb, "libusb_bulk_transfer")
      
      libusb_interrupt_transfer = GetFunction(libusb, "libusb_interrupt_transfer")
      
      libusb_get_string_descriptor_ascii = GetFunction(libusb, "libusb_get_string_descriptor_ascii")
      
      libusb_try_lock_events = GetFunction(libusb, "libusb_try_lock_events")
      libusb_lock_events = GetFunction(libusb, "libusb_lock_events")
      libusb_unlock_events = GetFunction(libusb, "libusb_unlock_events")
      libusb_event_handling_ok = GetFunction(libusb, "libusb_event_handling_ok")
      libusb_event_handler_active = GetFunction(libusb, "libusb_event_handler_active")
      libusb_interrupt_event_handler = GetFunction(libusb, "libusb_interrupt_event_handler")
      libusb_lock_event_waiters = GetFunction(libusb, "libusb_lock_event_waiters")
      libusb_unlock_event_waiters = GetFunction(libusb, "libusb_unlock_event_waiters")
      libusb_wait_for_event = GetFunction(libusb, "libusb_wait_for_event")

      libusb_handle_events_timeout = GetFunction(libusb, "libusb_handle_events_timeout")
      libusb_handle_events_timeout_completed = GetFunction(libusb, "libusb_handle_events_timeout_completed")
      libusb_handle_events = GetFunction(libusb, "libusb_handle_events")
      libusb_handle_events_completed = GetFunction(libusb, "libusb_handle_events_completed")
      libusb_handle_events_locked = GetFunction(libusb, "libusb_handle_events_locked")
      libusb_pollfds_handle_timeouts = GetFunction(libusb, "libusb_pollfds_handle_timeouts")
      libusb_get_next_timeout = GetFunction(libusb, "libusb_get_next_timeout")

      libusb_get_pollfds = GetFunction(libusb, "libusb_get_pollfds")
      libusb_free_pollfds = GetFunction(libusb, "libusb_free_pollfds")
      libusb_set_pollfd_notifiers = GetFunction(libusb, "libusb_set_pollfd_notifiers")
      
      libusb_hotplug_register_callback = GetFunction(libusb, "libusb_hotplug_register_callback")
      
      libusb_hotplug_deregister_callback = GetFunction(libusb, "libusb_hotplug_deregister_callback")

      libusb_hotplug_get_user_data = GetFunction(libusb, "libusb_hotplug_get_user_data")
      
      libusb_set_option = GetFunction(libusb, "libusb_set_option")
      
    EndIf
    
  EndIf
  
  ProcedureReturn libusb
  
EndProcedure


Procedure.i libusb_init(*ctx)
  
  Protected Result.i
  
  
  If Not IsLibrary(libusb)
    UseLibusb()
  EndIf
  
  If _libusb_init
    Result = _libusb_init(*ctx)
  Else
    Result = #LIBUSB_ERROR_OTHER
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


Procedure.i libusb_init_context(*ctx, *options.libusb_init_option, num_options.l)
  
  Protected Result.i
  
  
  If Not IsLibrary(libusb)
    UseLibusb()
  EndIf
  
  If _libusb_init_context
    _libusb_init_context(*ctx, *options, num_options)
  Else
    Result = #LIBUSB_ERROR_OTHER
  EndIf
    
  ProcedureReturn Result
  
EndProcedure



Procedure.s libusb_error_name(error_code.l)
  ProcedureReturn PeekS(_libusb_error_name(error_code), -1, #PB_Ascii)
EndProcedure


Procedure.s libusb_strerror(errcode.l)
  ProcedureReturn PeekS(_libusb_strerror(errcode), -1, #PB_Ascii)
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  
  Structure PointerToPointerStructure
    p.i[0]
  EndStructure
  
  Define *ctx
  Define *Version.libusb_version
  Define *devs.PointerToPointerStructure, *dev
  Define.i cnt, r, i, j
  Define desc.libusb_device_descriptor
  Dim path.a(7)
  Define Line$
  Define.a Bus, Address
  
  
  If libusb_init(#Null) = #LIBUSB_SUCCESS
    Debug "libusb_init Ok"
    
    *Version = libusb_get_version()
    Debug Str(*Version\major) + "." + Str(*Version\minor) + "." + Str(*Version\micro) + "." + Str(*Version\nano) + " " + PeekS(*Version\rc, -1, #PB_Ascii) + " " + PeekS(*Version\describe, -1, #PB_Ascii)
    
    Debug "libusb_error_name(#LIBUSB_ERROR_IO): " + libusb_error_name(#LIBUSB_ERROR_IO)
    Debug "libusb_strerror(#LIBUSB_ERROR_IO): " + libusb_strerror(#LIBUSB_ERROR_IO)
    
    
    cnt = libusb_get_device_list(#Null, @*devs)
    If cnt
      
      *dev = *devs\p[i]
      While *dev <> #Null
        
        r = libusb_get_device_descriptor(*dev, @desc)
        If r < 0
          Debug "failed to get device descriptor"
          Break
        EndIf
        
        ;Debug libusb_get_bus_number(*dev)
        Bus = libusb_get_bus_number(*dev)
        Address = libusb_get_device_address(*dev)
        
        Line$ = RSet(Hex(desc\idVendor), 4, "0") + ":" + RSet(Hex(desc\idProduct), 4, "0") + " (bus " + Str(Bus) + ", device " + Str(Address) + ")"
        
        r = libusb_get_port_numbers(*dev, path(), ArraySize(path()))
        If r > 0
          Line$ +  " path: " + Str(path(0))
          For j = 1 To r - 1
            Line$ + "." + Str(path(j))
          Next j
        EndIf
        
        Debug Line$
        
        i + 1
        *dev = *devs\p[i]
      Wend
      
      
      libusb_free_device_list(*devs, 1)
    EndIf
    
    libusb_exit(PeekI(@*ctx))
  EndIf
  
CompilerEndIf
Last edited by infratec on Sun Jan 19, 2025 11:02 am, edited 7 times in total.
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

listdevs for PB:

listdevs.pb

Code: Select all

;
; port of listdevs.c
;

EnableExplicit

IncludeFile "libusb.pbi"

Procedure print_devs(*devs.libusb_device_array)
  
  Protected *dev.libusb_device
  Protected.i i, j, r
  Protected Dim path.uint8_t(7)
  Protected desc.libusb_device_descriptor
  
  
  *dev = *devs\dev[i]
  While *dev <> #Null
    
    r = libusb_get_device_descriptor(*dev, @desc)
    If r < 0
      PrintN("failed to get device descriptor")
      ProcedureReturn
    EndIf
    
    Print(RSet(Hex(desc\idVendor), 4, "0") + ":" + RSet(Hex(desc\idProduct), 4, "0") + " (bus " + Str(libusb_get_bus_number(*dev)) + ", device " + Str(libusb_get_device_address(*dev)) + ")")
    
    r = libusb_get_port_numbers(*dev, @path(0), ArraySize(path()))
    If r > 0
      Print(" path: " + Str(path(0)))
      For j = 1 To r - 1
        Print("." + Str(path(j)))
      Next j
    EndIf
    PrintN("")
    
    i + 1
    *dev = *devs\dev[i]
  Wend
  
EndProcedure




Define *devs.libusb_device_array
Define	r.i
Define 	cnt.i


If OpenConsole()
  
  r = libusb_init_context(#Null, #Null, 0)
  If r < 0
    End r
  EndIf
  
  cnt = libusb_get_device_list(#Null, @*devs)
  If cnt < 0
    libusb_exit(#Null)
    End cnt
  EndIf
  
  print_devs(*devs)
  libusb_free_device_list(*devs, 1)
  
  libusb_exit(#Null)
  
  CompilerIf #PB_Compiler_Debugger
    PrintN("")
    Print("Press RETURN to end")
    Input()
  CompilerEndIf
EndIf
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

testlibusb for PB:

testlibusb.pb

Code: Select all

;
; port of testlibusb.c
;

EnableExplicit

IncludeFile "libusb.pbi"


Global verbose.i


Procedure print_endpoint_comp(*ep_comp.libusb_ss_endpoint_companion_descriptor)
  PrintN("      USB 3.0 Endpoint Companion:")
  PrintN("        bMaxBurst:           " + Str(*ep_comp\bMaxBurst))
  PrintN("        bmAttributes:        " + RSet(Hex(*ep_comp\bmAttributes), 2, "0") + "h")
  PrintN("        wBytesPerInterval:   " + Str(*ep_comp\wBytesPerInterval))
EndProcedure



Procedure print_endpoint(*endpoint.libusb_endpoint_descriptor)
  
  Protected.i i, ret
  Protected *ep_comp.libusb_ss_endpoint_companion_descriptor
  
  
  PrintN("      Endpoint:")
  PrintN("        bEndpointAddress:    " + RSet(Hex(*endpoint\bEndpointAddress), 2, "0") + "h")
  PrintN("        bmAttributes:        " + RSet(Hex(*endpoint\bmAttributes), 2, "0") + "h")
  PrintN("        wMaxPacketSize:      " + Str(*endpoint\wMaxPacketSize))
  PrintN("        bInterval:           " + Str(*endpoint\bInterval))
  PrintN("        bRefresh:            " + Str(*endpoint\bRefresh))
  PrintN("        bSynchAddress:       " + Str(*endpoint\bSynchAddress))
  
  While i < *endpoint\extra_length
    If #LIBUSB_DT_SS_ENDPOINT_COMPANION = *endpoint\extra\a[i + 1]
      
      ret = libusb_get_ss_endpoint_companion_descriptor(#Null, *endpoint, @*ep_comp)
      If #LIBUSB_SUCCESS <> ret
        Continue
      EndIf
      
      print_endpoint_comp(*ep_comp)
      
      libusb_free_ss_endpoint_companion_descriptor(*ep_comp)
    EndIf
    
    i + *endpoint\extra\a[i]
  Wend
  
EndProcedure



Procedure print_altsetting(*Interface.libusb_interface_descriptor)
  
	Protected i.uint8_t
	
	
	PrintN("    Interface:")
	PrintN("      bInterfaceNumber:      " + Str(*Interface\bInterfaceNumber))
	PrintN("      bAlternateSetting:     " + Str(*Interface\bAlternateSetting))
	PrintN("      bNumEndpoints:         " + Str(*Interface\bNumEndpoints))
	PrintN("      bInterfaceClass:       " + Str(*Interface\bInterfaceClass))
	PrintN("      bInterfaceSubClass:    " + Str(*Interface\bInterfaceSubClass))
	PrintN("      bInterfaceProtocol:    " + Str(*Interface\bInterfaceProtocol))
	PrintN("      iInterface:            " + Str(*Interface\iInterface))
  
	For i = 0 To *Interface\bNumEndpoints - 1
	  print_endpoint(@*Interface\endpoint\led[i])
	Next i
	  
EndProcedure



Procedure print_2_0_ext_cap(*usb_2_0_ext_cap.libusb_usb_2_0_extension_descriptor)
	PrintN("    USB 2.0 Extension Capabilities:")
	PrintN("      bDevCapabilityType:    " + Str(*usb_2_0_ext_cap\bDevCapabilityType))
	PrintN("      bmAttributes:          " + RSet(Hex(*usb_2_0_ext_cap\bmAttributes), 8, "0") + "h")
EndProcedure



Procedure print_ss_usb_cap(*ss_usb_cap.libusb_ss_usb_device_capability_descriptor)
	PrintN("    USB 3.0 Capabilities:")
	PrintN("      bDevCapabilityType:    " + Str(*ss_usb_cap\bDevCapabilityType))
	PrintN("      bmAttributes:          " + RSet(Hex(*ss_usb_cap\bmAttributes), 2, "0") + "h")
	PrintN("      wSpeedSupported:       " + Str(*ss_usb_cap\wSpeedSupported))
	PrintN("      bFunctionalitySupport: " + Str(*ss_usb_cap\bFunctionalitySupport))
	PrintN("      bU1devExitLat:         " + Str(*ss_usb_cap\bU1DevExitLat))
	PrintN("      bU2devExitLat:         " + Str(*ss_usb_cap\bU2DevExitLat))
EndProcedure



Procedure print_bos(*handle.libusb_device_handle)
  
	Protected *bos.libusb_bos_descriptor
	Protected i.uint8_t
	Protected ret.i
	Protected *dev_cap.libusb_bos_dev_capability_descriptor
	Protected *usb_2_0_extension.libusb_usb_2_0_extension_descriptor
	Protected *ss_dev_cap.libusb_ss_usb_device_capability_descriptor
	
	
	ret = libusb_get_bos_descriptor(*handle, @*bos)
	If ret < 0
	  ProcedureReturn
	EndIf

	PrintN("  Binary Object Store (BOS):")
	PrintN("    wTotalLength:            " + Str(*bos\wTotalLength))
	PrintN("    bNumDeviceCaps:          " + Str(*bos\bNumDeviceCaps))
  
	For i = 0 To *bos\bNumDeviceCaps - 1
		*dev_cap = *bos\dev_capability[i]
    
		If *dev_cap\bDevCapabilityType = #LIBUSB_BT_USB_2_0_EXTENSION
			
			ret = libusb_get_usb_2_0_extension_descriptor(#Null, *dev_cap, @*usb_2_0_extension)
			If ret < 0
			  ProcedureReturn
			EndIf
      
			print_2_0_ext_cap(*usb_2_0_extension)
			libusb_free_usb_2_0_extension_descriptor(*usb_2_0_extension)
		ElseIf *dev_cap\bDevCapabilityType = #LIBUSB_BT_SS_USB_DEVICE_CAPABILITY
      
			ret = libusb_get_ss_usb_device_capability_descriptor(#Null, *dev_cap, @*ss_dev_cap)
			If ret < 0
			  ProcedureReturn
			EndIf

			print_ss_usb_cap(*ss_dev_cap)
			libusb_free_ss_usb_device_capability_descriptor(*ss_dev_cap)
		EndIf
	Next i

	libusb_free_bos_descriptor(*bos)
EndProcedure



Procedure print_interface(*Interface.libusb_interface)

	Protected i.i
	
	
	For i = 0 To *Interface\num_altsetting - 1
	  print_altsetting(@*Interface\altsetting\lid[i])
	Next i
	
EndProcedure



Procedure print_configuration(*config.libusb_config_descriptor)
  
	Protected i.uint8_t
	
	
	PrintN("  Configuration:")
	PrintN("    wTotalLength:            " + Str(*config\wTotalLength))
	PrintN("    bNumInterfaces:          " + Str(*config\bNumInterfaces))
	PrintN("    bConfigurationValue:     " + Str(*config\bConfigurationValue))
	PrintN("    iConfiguration:          " + Str(*config\iConfiguration))
	PrintN("    bmAttributes:            " + RSet(Hex(*config\bmAttributes), 2, "0") + "h")
	PrintN("    MaxPower:                " + Str(*config\MaxPower))
  
	For i = 0 To *config\bNumInterfaces - 1
	  print_interface(@*config\Interface\int[i])
	Next i
	
EndProcedure



Procedure print_device(*dev.libusb_device, *handle.libusb_device_handle)
  
	Protected desc.libusb_device_descriptor
	Protected Dim string.a(255)
	Protected speed$
	Protected ret.i
	Protected i.uint8_t
	Protected *config.libusb_config_descriptor
	
  
	Select libusb_get_device_speed(*dev)
	  Case #LIBUSB_SPEED_LOW :		    speed$ = "1.5M"
	  Case #LIBUSB_SPEED_FULL :		    speed$ = "12M"
	  Case #LIBUSB_SPEED_HIGH :		    speed$ = "480M"
	  Case #LIBUSB_SPEED_SUPER :	    speed$ = "5G"
	  Case #LIBUSB_SPEED_SUPER_PLUS :	speed$ = "10G"
	  Default :	                      speed$ = "Unknown"
	EndSelect
  
	ret = libusb_get_device_descriptor(*dev, @desc)
	If ret < 0
		PrintN("failed to get device descriptor")
		ProcedureReturn
	EndIf

	PrintN("Dev (bus " + Str(libusb_get_bus_number(*dev)) + ", device " + Str(libusb_get_device_address(*dev)) + "): " + RSet(Hex(desc\idVendor), 4, "0") + " - " + RSet(Hex(desc\idProduct), 4, "0") + " speed: " + speed$)

	If Not *handle
	  libusb_open(*dev, @*handle)
	EndIf
  
	If *handle
		If desc\iManufacturer
			ret = libusb_get_string_descriptor_ascii(*handle, desc\iManufacturer, @string(0), ArraySize(string()))
			If ret > 0
			  PrintN("  Manufacturer:              " + PeekS(@string(0), -1, #PB_Ascii))
			EndIf
		EndIf

		If desc\iProduct
			ret = libusb_get_string_descriptor_ascii(*handle, desc\iProduct, @string(0), ArraySize(string()))
			If ret > 0
			  PrintN("  Product:                   " + PeekS(@string(0), -1, #PB_Ascii))
			EndIf
		EndIf

		If desc\iSerialNumber And verbose
			ret = libusb_get_string_descriptor_ascii(*handle, desc\iSerialNumber, @string(0), ArraySize(string()))
			If ret > 0
			  PrintN("  Serial Number:             " + PeekS(@string(0), -1, #PB_Ascii))
			EndIf
		EndIf
	EndIf

	If verbose
	  For i = 0 To desc\bNumConfigurations - 1
	    
			ret = libusb_get_config_descriptor(*dev, i, @*config)
			If #LIBUSB_SUCCESS <> ret
				PrintN("  Couldn't retrieve descriptors")
				Continue
			EndIf
      
			print_configuration(*config)
      
			libusb_free_config_descriptor(*config)
		Next i

		If *handle And desc\bcdUSB >= $0201
		  print_bos(*handle)
		EndIf
	EndIf

	If *handle
	  libusb_close(*handle)
	EndIf
	
EndProcedure


CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  Procedure.i test_wrapped_device(device_name$)
    
    ProcedureReturn 1
    
  EndProcedure
CompilerElse
  Procedure.i test_wrapped_device(device_name$)
    
    PrintN("Testing wrapped devices is not supported on your platform")
    
    ProcedureReturn 1
    
  EndProcedure
CompilerEndIf



Define device_name$
Define *devs.libusb_device_array
Define cnt.i
Define.i r, i


If OpenConsole()
  For i = 0 To CountProgramParameters() - 1
		If ProgramParameter(i) = "-v"
			verbose = 1;
		ElseIf ProgramParameter(i) = "-d"
			i + 1
			device_name$ = ProgramParameter(i)
		Else
			PrintN("Usage " + GetFilePart(ProgramFilename(), #PB_FileSystem_NoExtension) + " [-v] [-d </dev/bus/usb/...>]")
			PrintN("Note use -d to test libusb_wrap_sys_device()")
			End 1
		EndIf
	Next i
	
	CompilerIf #PB_Compiler_Debugger
	  verbose = 1
	CompilerEndIf
	
	r = libusb_init_context(#Null, #Null, 0)
	If r < 0
	  End r
	EndIf

	If device_name$ <> ""
		r = test_wrapped_device(device_name$)
	Else
		cnt = libusb_get_device_list(#Null, @*devs)
		If cnt < 0
			libusb_exit(#Null)
			End 1
		EndIf

		For i = 0 To *devs\dev[i]
		  print_device(*devs\dev[i], #Null)
		Next i

		libusb_free_device_list(*devs, 1)
	EndIf

	libusb_exit(#Null)
	
	CompilerIf #PB_Compiler_Debugger
    PrintN("")
    Print("Press RETURN to end")
    Input()
  CompilerEndIf
	
EndIf

End r
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

A starting point:

Code: Select all

EnableExplicit

#VID = $046d
#PID = $c077

IncludeFile "libusb.pbi"


Define *devh.libusb_device_handle

If libusb_init_context(#Null, #Null, 0) = #LIBUSB_SUCCESS
  
  *devh = libusb_open_device_with_vid_pid(#Null, #VID, #PID)
  If *devh
    
    If libusb_claim_interface(*devh, 1) = #LIBUSB_SUCCESS
      
      Debug "do usb stuff"
      
      libusb_release_interface(*devh, 1)
    Else
      Debug "libusb_claim_interface() failed"
    EndIf
    
    libusb_close(*devh)
  Else
    Debug "libusb_open_device_with_vid_pid() failed"
  EndIf
  libusb_exit(#Null)
Else
  Debug "libusb_init_context() failed"
EndIf
But since I don't own a usb device without driver, I can not test anything more.
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

Since I had a bit spare time ...

I ported
https://github.com/kyllikki/EdgeRobotAr ... r/rbtarm.c

Code: Select all

EnableExplicit

IncludeFile "libusb.pbi"


Procedure.i is_interesting(*device.libusb_device)
  
  Protected desc.libusb_device_descriptor
  Protected r.i
  
  r = libusb_get_device_descriptor(*device, @desc)
  If r < 0
    Debug "failed to get device descriptor"
    ProcedureReturn #False
  EndIf
  
  If desc\idVendor = $1267 And desc\idProduct = $0
    ProcedureReturn #True
  EndIf
  
  ProcedureReturn #False
  
EndProcedure


Enumeration motor_dir_e
  #motor_off = 0
  #motor_forward = 1
  #motor_back = 2
EndEnumeration


Procedure stop_arm(*handle.libusb_device_handle)
  
  Dim buf.uint8_t(3)
  
  buf(0) = 0
  buf(1) = 0
  buf(2) = 0
  
  libusb_control_transfer(*handle, #LIBUSB_REQUEST_TYPE_VENDOR | #LIBUSB_RECIPIENT_DEVICE, 6, $100, 0, @buf(0), 3, 0)
  
EndProcedure


Procedure control_arm(*handle.libusb_device_handle, *motors.AsciiArray, led.i)
  
  Protected ctrl.uint32_t
  Protected Dim buf.uint8_t(3)
  Protected motor_loop.i
  
  
  If led
    ctrl | $ff << 16
  EndIf
  
  For motor_loop = 0 To 4
    Debug "control_arm: motors[" + Str(motor_loop) + "] = " + Hex(*motors\a[motor_loop])
    ctrl | (*motors\a[motor_loop] << (motor_loop << 1))
  Next motor_loop
  
  buf(0) = ctrl & $ff
  buf(1) = (ctrl & $ff00) >> 8
  buf(2) = (ctrl & $ff0000) >> 16
  
  Debug "control_arm: ctrl is " + Hex(ctrl) + " buf " + Hex(buf(0)) + "," + Hex(buf(1)) + "," + Hex(buf(2))
  
  libusb_control_transfer(*handle, #LIBUSB_REQUEST_TYPE_VENDOR | #LIBUSB_RECIPIENT_DEVICE, 6, $100, 0, @buf(0), 3, 0)
  
EndProcedure



; motor To test run forwards And back (remember folks its 0 based so whats
; labeled M1 is motor 0

#TEST_MOTOR = 0

Define *handle.libusb_device_handle
Define *motors.AsciiArray
Define *list.libusb_device_array
Define.libusb_device *found, *device
Define.i cnt, i, err



*motors = AllocateMemory(5)

If libusb_init(#Null) = #LIBUSB_SUCCESS
  
  libusb_set_debug(#Null, 3)
  
  ; discover devices
  cnt = libusb_get_device_list(#Null, @*list)
  
  For i = 0 To cnt - 1
    *device = *list\dev[i]
    If is_interesting(*device)
      *found = *device
      Break
    EndIf
  Next i
  
  If *found
    
    err = libusb_open(*found, @*handle)
    If err
      Debug "error: " + Str(err)
    Else
      
      control_arm(*handle, *motors, #True) ; LED go on
      Delay(1000)
      control_arm(*handle, *motors, #False)  ; LED go off
      
      *motors\a[#TEST_MOTOR] = #motor_forward
      control_arm(*handle, *motors, #False) ; motor forward
      Delay(2000)
      
      *motors\a[#TEST_MOTOR] = #motor_back
      control_arm(*handle, *motors, #False) ; motor backward
      Delay(2000)
      
      stop_arm(*handle) ; shut it all off
      
      libusb_close(*handle)
      
    EndIf
    
  EndIf
  
  libusb_free_device_list(*list, 1)
  
  libusb_exit(#Null)
  
EndIf
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

Re: LibUSB in Purebasic

Post by matalog »

Wow, that's amazing infratec it will take me a while to go through all of these, thanks a lot for taking the time to work on that and share them :D .

The good thing is that it will hopefully let anyone that needs it, to get to use libUSB with PB.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

Re: LibUSB in Purebasic

Post by matalog »

infratec post_id=633858 time=1737283529 user_id=4263]
Since I had a bit spare time ...

I ported
https://github.com/kyllikki/EdgeRobotAr ... r/rbtarm.c
With the elanusb driver installed, and the device tested with its own software and working via USB.

I see
1267:0000 (bus 3, device 4) path: 1.3
when I run your libusb.pbi program as one of the connected devices.

When I run your ported robotic arm program I get
error -12
Any ideas what might cause that?
infratec
Always Here
Always Here
Posts: 7662
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: LibUSB in Purebasic

Post by infratec »

Have you tried without the driver?
Remove it via the device manager.

-12 : Operation not supported or unimplemented on this platform.

I will check something.
Post Reply