Controlling a robot arm from PureBasic?

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

Controlling a robot arm from PureBasic?

Post by matalog »

I have an old USB controlled Robotic Arm and would like to have a go at controlling it with PureBasic.

Is it possible to use any of the files in here: https://www.dropbox.com/scl/fi/k6wp6p5z ... yvt7b&dl=0 to allow Purebasic to control it via USB? The .rar file contains ElanUSB.cat, ElanUSB.inf and ElanUSB.sys files as well as setup files.

The files in the .rar are the only files supplied by the manufacturer, and when I allow unsigned drivers in Windows 10, I can install the ElanUSB driver and move the arm with the supplied software - I would prefer to control it with a language I have more control over.

Edit: I think this is the same arm, if any of the files here are better: https://github.com/sulaimanvali/RoboticArm535

Further edit: I found a description of the USB communication with the device -here: https://github.com/kyllikki/EdgeRobotArm
The USB protocol
----------------

I managed to examine the raw USB packets while using the windows
software. This showed that the control protocol is very simple.

The USB attached microcontroller in the arm appears as

Bus 005 Device 007: ID 1267:0000 Logic3 / SpectraVideo plc

It has the mandatory control endpoint and a single interrupt endpoint.

A simple USB vendor control transfer of three bytes appears to be the
entire control method. The bits in these bytes appear to directly
control the physical lines of the microcontroller. Effectively the
microcontroller is behaving as nothing more than a USB attached I/O
expander.

The bits in the first two bytes are used in pairs as inputs to ST1152
motor controllers. The truth table for these controllers is:

Input | Motor
A | B | Output
---+---+-------
0 | 0 | Idle
0 | 1 | Forwards
1 | 0 | Backwards
1 | 1 | Brake

The windows software only ever uses 00, 01 and 10 i.e. it never
applies a brake signal, this is probably because the circuit is so
badly designed with no smoothing capacitors the braking currents would
damage the circuit (alternate explanation is they simply never
bothered). This may be worth investigating as a way to reduce the
backlash problems

So to summarise bits 0 and 1 control the first motor, bits 2 and 3 the
second and so on for all five motors. I know this leaves bits 10-15
unused, these may be hooked up to unused pins or simply do nothing I
have not investigated.

Byte three is either 0xff or 0x0 it activates the led by sinking the
entire current of the LED into the microcontroller without a current
limit resistor!

If anyone knows how I could send those bytes to the device it would be great to know.
infratec
Always Here
Always Here
Posts: 7623
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Controlling a robot arm from PureBasic?

Post by infratec »

You can use libusb also in windows:

http://purebasic.mybb.ru/viewtopic.php?id=389
User avatar
matalog
Enthusiast
Enthusiast
Posts: 304
Joined: Tue Sep 05, 2017 10:07 am

Re: Controlling a robot arm from PureBasic?

Post by matalog »

I have opted to control it with a ZX Spectrum, as I understand the electronics side much more, and don't know anything about libusb or indeed usb control.
User avatar
CDXbow
Enthusiast
Enthusiast
Posts: 100
Joined: Mon Aug 12, 2019 5:32 am
Location: Oz

Re: Controlling a robot arm from PureBasic?

Post by CDXbow »

matalog wrote: Sat Jan 11, 2025 12:32 am I have opted to control it with a ZX Spectrum, as I understand the electronics side much more, and don't know anything about libusb or indeed usb control.
Wow!!!! A robot arm controlled by a Sinclair spectrum! You win the internet for the day, no, for a whole week. I have one of those toy yellow and black robot arms and I have thought about doing something with it. I had this idea to use it to animate a sculptural piece I was going to make based on the "figure" from the Mr Bacons early masterpiece.
Image
The arm would in the neck, and I was going to have it talk to people, actually it was going to abuse them. Nowadays with visual machine learning you would be able to build in some genuine interaction. So when I saw the thread title I got excited, only for you to dash my hopes and consign the project to the dustbin of history.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 304
Joined: Tue Sep 05, 2017 10:07 am

Re: Controlling a robot arm from PureBasic?

Post by matalog »

CDXbow wrote: Sun Jan 12, 2025 9:25 am
matalog wrote: Sat Jan 11, 2025 12:32 am I have opted to control it with a ZX Spectrum, as I understand the electronics side much more, and don't know anything about libusb or indeed usb control.
Wow!!!! A robot arm controlled by a Sinclair spectrum! You win the internet for the day, no, for a whole week. I have one of those toy yellow and black robot arms and I have thought about doing something with it. I had this idea to use it to animate a sculptural piece I was going to make based on the "figure" from the Mr Bacons early masterpiece.
Image
The arm would in the neck, and I was going to have it talk to people, actually it was going to abuse them. Nowadays with visual machine learning you would be able to build in some genuine interaction. So when I saw the thread title I got excited, only for you to dash my hopes and consign the project to the dustbin of history.
Well, to say sorry for dashing your hopes I am sharing a video of me controlling the arm via the Spectrum :-). https://youtu.be/a59P6vhr3VQ It even sounds like the same one.

Your idea to use it, would actually be a possible actual usage of the robot, it isn't strong or fast or accurate, but it would move like a birds neck and possibly look like one when covered in not too thigh light cloth.

I should say, that I think it would be a simple thing for anyone with USB experience in PB, to make the program that would allow us to issue A simple USB vendor control transfer of three bytes to the The USB attached microcontroller in the arm which appears as 'Bus 005 Device 007: ID 1267:0000 Logic3 / SpectraVideo plc' that has the mandatory control endpoint and a single interrupt endpoint.
User avatar
CDXbow
Enthusiast
Enthusiast
Posts: 100
Joined: Mon Aug 12, 2019 5:32 am
Location: Oz

Re: Controlling a robot arm from PureBasic?

Post by CDXbow »

I'm afraid I can't see the video as it's says it is private. Don't tease.

I didn't want to have to sort out too much low level stuff with the project, it has a few risks in it. I thought of making the neck and head out of silicon, this is something I have no experience with and goes into the high risk category. The body I would sculpture out of polystyrene, which I have experience with. The arm would be mounted in the body along with a computer, as per image below.

https://teamxbow.web.fc2.com/images/robotarm01.gif
User avatar
matalog
Enthusiast
Enthusiast
Posts: 304
Joined: Tue Sep 05, 2017 10:07 am

Re: Controlling a robot arm from PureBasic?

Post by matalog »

CDXbow wrote: Tue Jan 14, 2025 12:40 am I'm afraid I can't see the video as it's says it is private. Don't tease.
Sorry, you're right, I set it to private instead of unlisted.

I have fixed that and you should be able to view it now.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 304
Joined: Tue Sep 05, 2017 10:07 am

Re: Controlling a robot arm from PureBasic?

Post by matalog »

Infratec has helped out and showed a working example of libUSB vendor control transfer.

We now have a working Manual robot arm control program:

Code: Select all

EnableExplicit

IncludeFile "libusb.pbi"

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

InitSprite()
InitKeyboard()

OpenWindow(0,0,0,800,200,"Robot Arm Test - Manual Movement")
OpenWindowedScreen(WindowID(0),0,0,800,200)
StartDrawing(ScreenOutput())
Box(0,0,800,200,RGB(240,240,240))
StopDrawing()
TextGadget(0,10,8,800,80,"")
LoadFont(1, "Arial", 12)

SetGadgetFont(0,FontID(1))

Define *handle.libusb_device_handle
Define *motors.AsciiArray
Define *list.libusb_device_array
Define.libusb_device *found, *device
Define.i cnt, i, err,event,quit,LED,c
Define.s S$



*motors = AllocateMemory(5)

If libusb_init(#Null) = #LIBUSB_SUCCESS
  Debug "LIBUSB OKAY"
  libusb_set_debug(#Null, 3)
  
  
  *handle = libusb_open_device_with_vid_pid(#Null, $1267, $0)
  If *handle
  Repeat
    event=WaitWindowEvent()
    ExamineKeyboard()
    S$=""
    For c=0 To 4
      *motors\a[c]=#motor_off
    Next

    If KeyboardPushed(#PB_Key_All)
      
      If KeyboardPushed(#PB_Key_Q)
        *motors\a[3] = #motor_forward
        S$=S$+"SHOULDER UP "
      EndIf
      If KeyboardPushed(#PB_Key_A)
        *motors\a[3] = #motor_back
        S$=S$+"SHOULDER DOWN "
      EndIf
      If KeyboardPushed(#PB_Key_W)
        *motors\a[2] = #motor_forward
        S$=S$+"ELBOW UP "
      EndIf
      If KeyboardPushed(#PB_Key_S)
        *motors\a[2] = #motor_back
        S$=S$+"ELBOW DOWN "
      EndIf
      If KeyboardPushed(#PB_Key_E)
        *motors\a[1] = #motor_forward
        S$=S$+"WRIST UP "  
      EndIf
      If KeyboardPushed(#PB_Key_D)
        *motors\a[1] = #motor_back
        S$=S$+"WRIST DOWN "
      EndIf
      If KeyboardPushed(#PB_Key_O)
        *motors\a[4] = #motor_back
        S$=S$+"BASE CLOCKWISE "
      EndIf
      If KeyboardPushed(#PB_Key_P)
        *motors\a[4] = #motor_forward
        S$=S$+"BASE ANTI-CLOCKWISE "
      EndIf
      If KeyboardPushed(#PB_Key_K)
        *motors\a[0] = #motor_forward
        S$=S$+"HAND CLOSE "
      EndIf
      If KeyboardPushed(#PB_Key_L)
        *motors\a[0] = #motor_back
        S$=S$+"HAND OPEN "
      EndIf
      If KeyboardPushed(#PB_Key_V)
        LED=0
      EndIf
      If KeyboardPushed(#PB_Key_B)
        LED=1
      EndIf
      SetGadgetText(0,S$)
      control_arm(*handle, *motors, LED) ; send latest
    Else
      S$="INACTIVE"
      SetGadgetText(0,S$)
      control_arm(*handle, *motors, LED)
    EndIf
    
  Until KeyboardPushed(#PB_Key_Escape) Or  WindowEvent() = #PB_Event_CloseWindow
Else
  MessageRequester("Error","Device Not Connected")
    
  libusb_close(*handle)
  
  libusb_free_device_list(*list, 1)
  
  libusb_exit(#Null)
  End
  EndIf
  stop_arm(*handle) ; shut it all off
  
  libusb_close(*handle)
  
  libusb_free_device_list(*list, 1)
  
  libusb_exit(#Null)
  
EndIf

Last edited by matalog on Sun Jan 19, 2025 11:22 pm, edited 1 time in total.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 304
Joined: Tue Sep 05, 2017 10:07 am

Re: Controlling a robot arm from PureBasic?

Post by matalog »

It requires this include:

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
User avatar
matalog
Enthusiast
Enthusiast
Posts: 304
Joined: Tue Sep 05, 2017 10:07 am

Re: Controlling a robot arm from PureBasic?

Post by matalog »

And requires the robot arm driver for windows to be changed to WinUSB - the Elan driver in the list.

You do that with the program available here: https://zadig.akeo.ie/
infratec
Always Here
Always Here
Posts: 7623
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Controlling a robot arm from PureBasic?

Post by infratec »

The 'hardware' is still available:

https://owirobot.com/robotic-arm-edge/
User avatar
matalog
Enthusiast
Enthusiast
Posts: 304
Joined: Tue Sep 05, 2017 10:07 am

Re: Controlling a robot arm from PureBasic?

Post by matalog »

infratec wrote: Mon Jan 20, 2025 9:23 am The 'hardware' is still available:

https://owirobot.com/robotic-arm-edge/
That is the same Robotic Arm, but it is controlled with a hand-held controller - not necessarily USB. The difference may only be that the controller plugs into the same place that the proprietary USB cable would otherwise plug into, but I couldn't be sure about that.
tj1010
Enthusiast
Enthusiast
Posts: 716
Joined: Mon Feb 25, 2013 5:51 pm

Re: Controlling a robot arm from PureBasic?

Post by tj1010 »

43 USD for that arm is good value

It looks like it can do every axis, and the only shortcoming is probably lifting.

The only downside(?) is a printer and 3d-printer does everything it can do except pick&place and welding production work. Small-volume surface-mount PCB production would be cool with this.
KosterNET
User
User
Posts: 34
Joined: Tue Mar 22, 2016 10:08 pm

Re: Controlling a robot arm from PureBasic?

Post by KosterNET »

I only have experience with controlling FANUC from PureBasic ;-)
infratec
Always Here
Always Here
Posts: 7623
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Controlling a robot arm from PureBasic?

Post by infratec »

That's a different league :wink:
Post Reply