USB Human Interface Devices

classic Classic list List threaded Threaded
165 messages Options
123456789
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi
Well, I am sure you can find some devices lying around.

For once your USB mouse and keyboard are HID devices - but one usually
avoids messing with them for obvious reasons, in case an USB interface
claimed by a test program is not released.

Out of curiosity, just now I opened my keyboard device (046d:c517
Logitech, Inc. LX710 Cordless Desktop Laser) and interrupt data reports
came right in as I pressed keys (looks like my keyboard generates 16
bytes of data for every key press). Decoding the data though is another
problem altogether. Can't test if this also works in Windows but in
Linux appears to work ok.


But you should be safer testing with a USB game controller or Wii remote
as they are also HID devices. I was amazed that the Wii (being wireless
and all actually worked.) I also just checked and realized that my APC
UPS is also a HID device (ID 051d:0002 American Power Conversion
Uninterruptible Power Supply). In sum, plenty of devices to play around
with. Have fun!



On 8/15/19 8:28 PM, James Richters wrote:

> Thanks for posting the examples and the information. I'll have a look... I am thinking maybe I should buy some of those USB relays  or something simpler just to get SOMETHNG to work so I can figure out what's supposed to even be happening.
>
> James
>
> -----Original Message-----
> From: fpc-pascal <[hidden email]> On Behalf Of Stefan V. Pantazi
> Sent: Thursday, August 15, 2019 5:31 PM
> To: [hidden email]
> Subject: Re: [fpc-pascal] USB Human Interface Devices
>
> Hi James,
>
> I remember going through many similar difficulties with HID. A few years ago I was trying to connect to much simpler devices than yours (game controllers, weather station base, graphic tablet, etc). USB programming is confusing and many abstraction layers have been created aiming at simplifying it. Unfortunately this introduces dependencies. I remember trying to port hidapi headers to Pascal and tried to use the hidraw backend (in linux) with mixed results. Also tried the libhid cross-platform library. In the end I went with libusb 1.0 for which a Pascal header already existed
> (https://forum.lazarus.freepascal.org/index.php?topic=11435.0) and used it to implement on top of it a subset of the HID API calls that suited my needs and kept things simple. I just posted an example on github:
> https://github.com/svpantazi/libusbxhid
> Hope it helps.
>
> In theory you could use the Windows HID API but, as others have suggested, the solution would not be cross platform, or, to put it another way, Windows HID API would become your dependency. My suggestion is also to go the libusb 1.0 route and use a Pascal HID library that depends only on libusb 1.0. Your device appears to be HID-compliant so no additional drivers should be needed for it. As far as I know, the Zadig generic driver is necessary only for non-HID devices. I remember using it for a rtl-sdr USB device on Windows.
>
> Hope you find your solution. Good luck.
>
> On 8/15/19 9:11 AM, James Richters wrote:
>> Yes, in device manager I see it listed as "HID-compliant
>> vendor-defined device"  also Zadig identifies it as "USB Input Device"
>> and it shows Driver: HidUsb (v10.1.17763.1)
>>
>> Is there a way to use the windows system HID interface with FPC already in place as there is for other windows APIs?
>>
>> James
>>
>> -----Original Message-----
>> From: fpc-pascal <[hidden email]> On Behalf
>> Of José Mejuto
>> Sent: Thursday, August 15, 2019 8:34 AM
>> To: [hidden email]
>> Subject: Re: [fpc-pascal] USB Human Interface Devices
>>
>> El 14/08/2019 a las 16:29, James Richters escribió:
>>
>>> I'll have a look at your project.. maybe it will give me some clues.
>>> Can you tell me how to get hid.dll?  I  find it all very confusing, can I just download the dll somewhere or do I have to get this huge confusing package and built it myself?  The sample code that is able to access my device with python on Linux uses hid.dll  I would like to at least be able to try the hid.dll... if I can get hid.dll somewhere.
>>
>> Hello,
>>
>> hid.dll is the windows system HID interface, the API provided by Windows.
>>
>>>> In the other hand, the hardware you are trying to manage is 10CE:EB93 ?
>>> Yes, I got a listing of all devices, then I plugged in the new one, and that is the ID that was not there before.
>>>> If the answer is yes, that device is *not* HID compatible so you can
>>>> not use hid.dll for native access, you must use WinUSB API set, or
>>>> the
>>>> libusb-1.0 abstraction layer.
>>> I'm curious how you can tell that by looking at the number of it?
>>
>> No, I just look for the product and try to find its drivers, no one name the HID interface. Do you see the device in windows device manager under the HID section "Human Interface Devices (HID)" ?
>>
>>
>
> --
> _______________________________________________________
> _______________________________________________
> fpc-pascal maillist  -  [hidden email] https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
DATA!!!!!!!!!!!!!!


Running "i:\programming\libusbxhid\libusbhid_test.exe "
Found 15 devices attached
8086:A36D, bus: 1, address: 0
8087:0AAA, bus: 1, address: 5
0424:2734, bus: 1, address: 51
1D50:6015, bus: 1, address: 38
1B1C:0C15, bus: 1, address: 7
10CE:EB93, bus: 1, address: 47
Found device with vid:pid 4302:60307 at idx:5!
Device instance found: 1  at idx:5!
05E3:0610, bus: 1, address: 3
04E8:61F5, bus: 1, address: 18
1B1C:0C10, bus: 1, address: 4
0424:274C, bus: 1, address: 46
047D:1020, bus: 1, address: 45
1B1C:1B4F, bus: 1, address: 43
1A40:0101, bus: 1, address: 50
0C45:7403, bus: 1, address: 36
10C4:EA60, bus: 1, address: 30
Index of device 4302:60307=5
Device opened. Next I must claim the interface.
Freeing device list with 15 devices
USB device list freed. good boy!
device attempting go clear halt on ep $81
libusb: error [hid_clear_halt] unable to match endpoint to an open interface - cannot clear
clear halt failed
driver inactive - can claim interface
getting configuration....
active config:1
Claiming interface.....fingers crossed...
Interface claimed ... yay!
received:8 bytes from device
04,7F,. ,. ,0F,12,. ,1A,
received:8 bytes from device
. ,69,. ,. ,. ,13,. ,08,
received:8 bytes from device
. ,D3,. ,. ,. ,. ,01,92,
received:8 bytes from device
. ,8F,. ,. ,. ,. ,00,8A,
received:8 bytes from device
. ,2B,. ,. ,. ,. ,. ,0A,
Interface released. Phew..
Heap dump by heaptrc unit of i:\programming\libusbxhid\libusbhid_test.exe
401 memory blocks allocated : 18362/20440
401 memory blocks freed     : 18362/20440
0 unfreed memory blocks : 0
True heap size : 196608 (160 used in System startup)
True free heap : 196448


Yay I FINALLY got somewhere with this thing!!!   Thanks for the example Stefan!   I have a python example of how to decode the meaning of the incoming data, that's how I figured out that it sends 8 bytes at a time.  

Is there a way I can read data from the device with a timeout instead of just waiting forever for it?  It doesn't send anything unless I push a button, but I need to do other things like update the LCD if I am not pushing a button.   My python example uses a function called hid.read(size,timeout) so I'm trying to do something similar.  This is going to be a console application when I am done, do I don't have a way to do anything else, so a timeout would work best.

I'm also trying to figure out how to write to the LCD...
Here is the python code the outputs stuff to the device:

    # send feature report, but breaks it into 7 byte packets
    def write(self, data):
        n = 0
        n += self.hid.send_feature_report(data[0:7], 0x06)
        n += self.hid.send_feature_report(data[7:14], 0x06)
        n += self.hid.send_feature_report(data[14:21], 0x06)
        n += self.hid.send_feature_report(data[21:28], 0x06)
        n += self.hid.send_feature_report(data[28:35], 0x06)
        n += self.hid.send_feature_report(data[35:42], 0x06)
        return n

I think there is a bug because 7 bytes would be data[0..6] and it would not duplicate byte 7.... but the 0x06 must tell it to send from bytes 0 to 6... but anyway, regardless of that, how do I do something like hid.send_feature_report?

I'm guessing that libusbhid_set_report() is maybe something similar?   But it has parameters for reportType and reportNum... any clue what to put there?  Or is this not even the right function?   I thought maybe putting HID_REPORT_TYPE_FEATURE  would mean to send a feature report?  But reportNum I have no idea... I stuck a 1 in there just to see and tried:
libusbhid_set_report(device_context,HID_REPORT_TYPE_FEATURE,1,7,hidOutData[0..6]);
but then I get:
libusb: warning [_hid_set_report] mismatched report ID (data is FE, parameter is 01)
control transfer to usb device failed!

$FE is what I have in hidOutData[0], but I'm not sure what it wants for a report id?  

I put my attempt on Github here:
https://github.com/Zaaphod/libusbxhid

Can you tell me where to get libusb_1.0_X86.dll  ?    I had the x64 version from the sample Jean sent me, but I would like to make my program work on 32bit machines as well.

Thanks to everyone for the help with this!  I really appreciate it.

James

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: *** SPAM *** Re: USB Human Interface Devices

Jean SUZINEAU
Le 16/08/2019 à 12:23, James Richters a écrit :
> Can you tell me where to get libusb_1.0_X86.dll  ?    I had the x64 version from the sample Jean sent me, but I would like to make my program work on 32bit machines as well.
I think you can get it at
https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.7z,
subdirectory MinGW32/dll in the archive
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: *** SPAM *** Re: USB Human Interface Devices

Zaaphod
Thank you, it's working with either 64bit or 32bit interchangeably now.

James

>I think you can get it at
>https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.7z,
>subdirectory MinGW32/dll in the archive
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi
In reply to this post by Zaaphod


On 8/16/19 6:23 AM, James Richters wrote:
> DATA!!!!!!!!!!!!!!
> Is there a way I can read data from the device with a timeout instead of just waiting forever for it?  It doesn't send anything unless I push a button, but I need to do other things like update the LCD if I am not pushing a button.   My python example uses a function called hid.read(size,timeout) so I'm trying to do something similar.  This is going to be a console application when I am done, do I don't have a way to do anything else, so a timeout would work best.

Remember that interrupt reads are  blocking so the way to deal with them
is to put them away from the main thread, in their own thread. The
moment something is available from the device, then the main thread of
your application is signaled to read a buffer with the device report
data. So, I can see some thread programming in your future or,


>
> I'm also trying to figure out how to write to the LCD...
> I think there is a bug because 7 bytes would be data[0..6] and it would not duplicate byte 7.... but the 0x06 must tell it to send from bytes 0 to 6... but anyway, regardless of that, how do I do something like hid.send_feature_report?

I have checked an old example where I use a HID set feature report. I
can see that the first byte of the output data (your hidOutData array)
is always set to the reportNum. So the length of the hidOutData array
send to the device includes the actual report number which prepends one
byte to the data. So the Python example is correct.

For example, in this call where I was trying to set a Wacom graphic
tablet mode, the length of hid_data is 3 bytes (the first being the
report number) but the report length in the call is 2
(WACOM_FEATURE_REPORT_LENGTH).

hid_data[0]:=WACOM_REPORT_NUMBER;
hid_data[1]:=WACOM_TABLET_MODE_FINGER_ENABLED;
hid_data[2]:=0;

libusbhid_set_report(device_context,HID_REPORT_TYPE_FEATURE{=$03},
WACOM_REPORT_NUMBER_ID{=2}, WACOM_FEATURE_REPORT_LENGTH{=2}, hid_data);



> I'm guessing that libusbhid_set_report() is maybe something similar?   But it has parameters for reportType and reportNum... any clue what to put there?  Or is this not even the right

You got it. Report type can be input, output or feature, just choose the
appropriate constant. Report number, for me was a lot of guesses, trial
and error combined with other examples of similar devices, etc.

function?   I thought maybe putting HID_REPORT_TYPE_FEATURE  would mean
to send a feature report?  But reportNum I have no idea... I stuck a 1
in there just to see and tried:
> libusbhid_set_report(device_context,HID_REPORT_TYPE_FEATURE,1,7,hidOutData[0..6]);
> but then I get:
> libusb: warning [_hid_set_report] mismatched report ID (data is FE, parameter is 01)
> control transfer to usb device failed!
> $FE is what I have in hidOutData[0], but I'm not sure what it wants for a report id?

Just make hidOutData[0]=Report_id (i.e., the first byte of your array)
and cross your fingers that the report id is correct.
>
> Can you tell me where to get libusb_1.0_X86.dll  ?    I had the x64 version from the sample Jean sent me, but I would like to make my program work on 32bit machines as well.
I remember that I had to build those from source but I am sure you can
find binaries online.


Happy hacking!
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
>>Remember that interrupt reads are  blocking so the way to deal with them is to put them away from the main thread, in their own thread. The moment something is available from the device, then the main thread of your application is signaled to read a buffer with the device report data. So, I can see some thread programming in your future or,

Can I even do threads in a console program?   Is there another way to do a read that has a timeout?

>You got it. Report type can be input, output or feature, just choose the
>appropriate constant. Report number, for me was a lot of guesses, trial
>and error combined with other examples of similar devices, etc.

>Just make hidOutData[0]=Report_id (i.e., the first byte of your array)
>and cross your fingers that the report id is correct.

So reportID is the same as the first byte, so then I have to repeat it like this:
         libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, hidOutData[0] , 7, hidOutData[ 0.. 6] );               ?

James
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi

On 8/16/19 11:11 AM, James Richters wrote:
>>> Remember that interrupt reads are  blocking so the way to deal with them is to put them away from the main thread, in their own thread. The moment something is available from the device, then the main thread of your application is signaled to read a buffer with the device report data. So, I can see some thread programming in your future or,

I see I did not finish my sentence. What I had in mind is that you could
use a library that already implements (using a thread I assume) a call
with a timeout. I checked and it looks like the original libusb call
that I used did have a timeout parameter that I hardcoded to 0 (infinite
timeout). libusb report a timeout as an error code. That did not sit
well with me and I preferred to use threads instead of time-out mechanism.

 > Is there another way to do a read that has a timeout?

yes, it took only a few minutes to add the time-out parameter to the
libusbhid_interrupt_read call. Have a look at the github repository for
the updated version.

>
> Can I even do threads in a console program?  

Sure you can, here is one of the simplest example you can start with
should you ever need to have multiple threads in your programs.

https://github.com/graemeg/freepascal/blob/master/packages/fcl-base/examples/threads.pp


--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: *** SPAM *** Re: USB Human Interface Devices

Jean SUZINEAU
In reply to this post by Zaaphod
Le 16/08/2019 à 17:11, James Richters a écrit :
> Can I even do threads in a console program?

Yes, you can.  I have in production some console code (worse: in a dll
called by a console program written in 4gl (4js Genero www.4js.com))
with threads which compile unmodified  under Linux and Windows.

By writing a descendant of TThread it's relatively easy to write a
thread in FreePascal (
https://wiki.freepascal.org/Multithreaded_Application_Tutorial ).
 From your (non main) thread you can execute a procedure in the main
thread by calling TThread.Synchronize.

 From what I remember, the main problem in console is that you need to
call regularly CheckSynchronize() ( from unit Classes ) from your
program which run the main thread.
That will be simpler for you, in my case, I had  to export from my dll a
pascal function calling CheckSynchronize() and call it regularly from
the 4gl program with a timer ...

As far as I remember, it works just with a queue, when you call
Synchronize you add a function call to the queue, and CheckSynchronize()
read the queue and do the actual call of your function.





_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
In reply to this post by Stefan V. Pantazi
Thank you for adding the timeout!  That will work for this project, but I may look into threads in my console program,  I could simplify a lot of things where I am maintaining a buffer while something else is being fed by the buffer that would probably be a lot easier if I had threads.

I've got the read working and have decoded all the buttons and switches on my device, but I still can't write to the display... well not on purpose.. something wrote a bunch of garbage to it at some point, which it is remembering.

The problem I am going to have with the LCD is that this device is not the exact one that I have sample code for.. when I decoded all my buttons and switches I realized that I was getting NOTHING like the sample.  The sample is for an HB04 and this is a WHB04B,   the W is just for wireless.. but the B is a completely different thing..  unfortunately I can't seem to even buy the original one without the B without waiting for a month for it to get here from China... I ordered one today.. but maybe before it gets here I'll figure out some way to just blast data to this one until something happens on the screen, and then I can figure it out.  

Thanks for the help with all this!!

James

-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Stefan V. Pantazi
Sent: Friday, August 16, 2019 1:30 PM
To: [hidden email]
Subject: Re: [fpc-pascal] USB Human Interface Devices


On 8/16/19 11:11 AM, James Richters wrote:
>>> Remember that interrupt reads are  blocking so the way to deal with
>>> them is to put them away from the main thread, in their own thread.
>>> The moment something is available from the device, then the main
>>> thread of your application is signaled to read a buffer with the
>>> device report data. So, I can see some thread programming in your
>>> future or,

I see I did not finish my sentence. What I had in mind is that you could use a library that already implements (using a thread I assume) a call with a timeout. I checked and it looks like the original libusb call that I used did have a timeout parameter that I hardcoded to 0 (infinite timeout). libusb report a timeout as an error code. That did not sit well with me and I preferred to use threads instead of time-out mechanism.

 > Is there another way to do a read that has a timeout?

yes, it took only a few minutes to add the time-out parameter to the libusbhid_interrupt_read call. Have a look at the github repository for the updated version.

>
> Can I even do threads in a console program?  

Sure you can, here is one of the simplest example you can start with should you ever need to have multiple threads in your programs.

https://github.com/graemeg/freepascal/blob/master/packages/fcl-base/examples/threads.pp


--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  [hidden email] https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: *** SPAM *** Re: USB Human Interface Devices

Zaaphod
In reply to this post by Jean SUZINEAU
Thanks for the link to the tutorial,  I'll have to look into that!   I have kind of a mess of things that runs through this whole sequential list checking all these different timings to see what needs to be done.. if all the things that required different timings were each in their own thread it would simplify things greatly

James

-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Jean SUZINEAU
Sent: Friday, August 16, 2019 1:34 PM
To: [hidden email]
Subject: Re: [fpc-pascal] *** SPAM *** Re: USB Human Interface Devices

Le 16/08/2019 à 17:11, James Richters a écrit :
> Can I even do threads in a console program?

Yes, you can.  I have in production some console code (worse: in a dll called by a console program written in 4gl (4js Genero www.4js.com)) with threads which compile unmodified  under Linux and Windows.

By writing a descendant of TThread it's relatively easy to write a thread in FreePascal ( https://wiki.freepascal.org/Multithreaded_Application_Tutorial ).
 From your (non main) thread you can execute a procedure in the main thread by calling TThread.Synchronize.

 From what I remember, the main problem in console is that you need to call regularly CheckSynchronize() ( from unit Classes ) from your program which run the main thread.
That will be simpler for you, in my case, I had  to export from my dll a pascal function calling CheckSynchronize() and call it regularly from the 4gl program with a timer ...

As far as I remember, it works just with a queue, when you call Synchronize you add a function call to the queue, and CheckSynchronize() read the queue and do the actual call of your function.





_______________________________________________
fpc-pascal maillist  -  [hidden email] https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
In reply to this post by José Mejuto
Jose,

Can you tell me which relays work with your project at:
https://github.com/JoshyFun/VUSBRelayPascal  ?

I have inputs from my device working but not outputs, I think it would be helpful for me to learn how to output to anything as a stepping stone... and actually USB relays sound like fun.

James

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

José Mejuto
El 16/08/2019 a las 20:45, James Richters escribió:
> Jose,
>
> Can you tell me which relays work with your project at:
> https://github.com/JoshyFun/VUSBRelayPascal  ?

"spam" sent by private.

>
> I have inputs from my device working but not outputs, I think it would be helpful for me to learn how to output to anything as a stepping stone... and actually USB relays sound like fun.

Hello,

In the case of USB relays you must invoke a "GetReport" with ReportID =
0 and you get a bitmasked state in 8 bytes of data. To activate and
deactivate the code invoke a "SetReport" in the same way.

Without a proper API description it could be really hard to implement
you hardware :-(

--

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
In reply to this post by Zaaphod

I’m trying to figure out why I get an access violation when I try to open my device with pas-libusb but it works with libusbxhid  they both are using libusb-1.0.dll

 

I put a bunch of hacks into pas-libusb to try to figure it out… just a lot of writeln’s so I can try to track down exactly what’s happening.  Because if I try to trace through the program I get “Program received signal SIGSEGV  Segmentation fault” before I get to the problem

 

I put this in a branch here:

 

https://github.com/Zaaphod/pas-libusb/tree/Hack/src

 

I’m using testopendevic_vidpid2.pas to test it with. 

 

Here’s my output:

start

1

2

a05472131

a10CEEB93

b

c

FALSE  8086  10CE  A36D  EB93

FALSE  8087  10CE  0AAA  EB93

FALSE  0424  10CE  2734  EB93

FALSE  1D50  10CE  6015  EB93

FALSE  1B1C  10CE  0C15  EB93

TRUE  10CE  10CE  EB93  EB93

FALSE  05E3  10CE  0610  EB93

FALSE  04E8  10CE  61F5  EB93

FALSE  1B1C  10CE  0C10  EB93

FALSE  0424  10CE  274C  EB93

FALSE  047D  10CE  1020  EB93

FALSE  1B1C  10CE  1B4F  EB93

FALSE  1A40  10CE  0101  EB93

FALSE  0C45  10CE  7403  EB93

FALSE  10C4  10CE  EA60  EB93

d

e

H1

I

4

Cousldn't connect to device: Access violation

 

 

 

Here’s as far as I could get….

(**

* Find endpoint according to MatchFunc

*

* @param MatchFunc  method to compare a given endpoint descriptor with a

*                   criterion

*

* @returns endpoint or Nil

*)

Function TLibUsbInterface.FindEndpoint(MatchFunc : TLibUsbEndpointMatchMethod) : Plibusb_endpoint_descriptor;

Var IEP : Integer;

    ED  : Plibusb_endpoint_descriptor;

Begin

   writeln('H',FInterface^.bNumEndpoints);

  For IEP := 0 to FInterface^.bNumEndpoints-1 do

    Begin

    Writeln('I');

      ED:= @(FInterface^.endpoint^[IEP]);

      if MatchFunc(ED) then

        Begin

           Writeln('J');

           Exit(ED);

        End

      else

       Writeln('K');

    End;

  Result := Nil;

End;

MatchFunc(ED) is where the access violation occurs, but I can’t trace any further because I can’t find the function MatchFunc()   I just don’t understand where the actual function is.

 

Maybe I made an error in the way I’m trying to open the device?   It can’t be any problem with the device itself or using libusb-1.0.dll because that is all working with libusbxhid.. in fact I have all inputs from my device mapped out.. Still don’t have the LCD working…. I can just use libusbxhid, but this is bugging me and I wanted to try to figure out what’s going on.

 

 

James

 


_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Jean SUZINEAU
Le 17/08/2019 à 15:00, James Richters a écrit :

Function TLibUsbInterface.FindEndpoint(MatchFunc : TLibUsbEndpointMatchMethod) : Plibusb_endpoint_descriptor;

MatchFunc(ED) is where the access violation occurs, but I can’t trace any further because I can’t find the function MatchFunc()   I just don’t understand where the actual function is.

MatchFunc is a parameter (its type is TLibUsbEndpointMatchMethod) of TLibUsbInterface.FindEndpoint.

To find which function is actually called, you should trace back where TLibUsbInterface.FindEndpoint is called and what function is provided as parameter MatchFunc.

It's likely you'll have to "climb up" through several calls, may be that TLibUsbInterface.FindEndpoint has itself a parameter MatchFunc

If you use the debugger, the callstack and a breakpoint just before the offending call to MatchFunc should help you to find from where comes your MatchFunc.

I wouldn't be surprised that it resolves somewhere to an overridden method Match of an instance of a class derived from TLibUsbDeviceMatchClass, likely TLibUsbDeviceMatchVidPid.Match, TLibUsbDeviceMatchVidPidSerial.Match or TLibUsbInterfaceMatchNumAlt.Match from unit libusbutil.pas

This can sound difficult  for you at the beginning if you're not too much accustomed with variables of type procedure and inheritance, but after a few practice it's not that complicated.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi
In reply to this post by Zaaphod
The obvious first thing to make sure is that the calling convention
matches the library for the platform. I see that in
https://github.com/Zaaphod/pas-libusb/blob/Hack/src/libusb.pas 9line 46)
the calling convention on Windows is cdecl (the stdcall is commented
out). In libusbxhid, if I remember correctly, the calling convention for
windows dlls is set to stdcall.

One other thing is that debugging is much more tedious without an
integrated debugger that allows you to step through each line before you
can see which function call blows up with a segfault.



On 8/17/19 9:00 AM, James Richters wrote:

> I’m trying to figure out why I get an access violation when I try to open my device with pas-libusb but it works with libusbxhid  they both are using libusb-1.0.dll
>
>  
>
> I put a bunch of hacks into pas-libusb to try to figure it out… just a lot of writeln’s so I can try to track down exactly what’s happening.  Because if I try to trace through the program I get “Program received signal SIGSEGV  Segmentation fault” before I get to the problem
>
>  
>
> I put this in a branch here:
>
>  
>
> https://github.com/Zaaphod/pas-libusb/tree/Hack/src
>
>  
>
> I’m using testopendevic_vidpid2.pas to test it with.
>
>  
>
> Here’s my output:
>
> start
>
> 1
>
> 2
>
> a05472131
>
> a10CEEB93
>
> b
>
> c
>
> FALSE  8086  10CE  A36D  EB93
>
> FALSE  8087  10CE  0AAA  EB93
>
> FALSE  0424  10CE  2734  EB93
>
> FALSE  1D50  10CE  6015  EB93
>
> FALSE  1B1C  10CE  0C15  EB93
>
> TRUE  10CE  10CE  EB93  EB93
>
> FALSE  05E3  10CE  0610  EB93
>
> FALSE  04E8  10CE  61F5  EB93
>
> FALSE  1B1C  10CE  0C10  EB93
>
> FALSE  0424  10CE  274C  EB93
>
> FALSE  047D  10CE  1020  EB93
>
> FALSE  1B1C  10CE  1B4F  EB93
>
> FALSE  1A40  10CE  0101  EB93
>
> FALSE  0C45  10CE  7403  EB93
>
> FALSE  10C4  10CE  EA60  EB93
>
> d
>
> e
>
> H1
>
> I
>
> 4
>
> Cousldn't connect to device: Access violation
>
>  
>
>  
>
>  
>
> Here’s as far as I could get….
>
> (**
>
> * Find endpoint according to MatchFunc
>
> *
>
> * @param MatchFunc  method to compare a given endpoint descriptor with a
>
> *                   criterion
>
> *
>
> * @returns endpoint or Nil
>
> *)
>
> Function TLibUsbInterface.FindEndpoint(MatchFunc : TLibUsbEndpointMatchMethod) : Plibusb_endpoint_descriptor;
>
> Var IEP : Integer;
>
>      ED  : Plibusb_endpoint_descriptor;
>
> Begin
>
>     writeln('H',FInterface^.bNumEndpoints);
>
>    For IEP := 0 to FInterface^.bNumEndpoints-1 do
>
>      Begin
>
>      Writeln('I');
>
>        ED:= @(FInterface^.endpoint^[IEP]);
>
>        if MatchFunc(ED) then
>
>          Begin
>
>             Writeln('J');
>
>             Exit(ED);
>
>          End
>
>        else
>
>         Writeln('K');
>
>      End;
>
>    Result := Nil;
>
> End;
>
> MatchFunc(ED) is where the access violation occurs, but I can’t trace any further because I can’t find the function MatchFunc()   I just don’t understand where the actual function is.
>
>  
>
> Maybe I made an error in the way I’m trying to open the device?   It can’t be any problem with the device itself or using libusb-1.0.dll because that is all working with libusbxhid.. in fact I have all inputs from my device mapped out.. Still don’t have the LCD working…. I can just use libusbxhid, but this is bugging me and I wanted to try to figure out what’s going on.
>
>  
>
>  
>
> James
>
>  
>
>
>
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Jean SUZINEAU
Le 17/08/2019 à 17:10, Stefan V. Pantazi a écrit :
> The obvious first thing to make sure is that the calling convention
> matches the library for the platform. I see that in
> https://github.com/Zaaphod/pas-libusb/blob/Hack/src/libusb.pas 9line 46)
> the calling convention on Windows is cdecl (the stdcall is commented
> out). In libusbxhid, if I remember correctly, the calling convention
> for windows dlls is set to stdcall.
Yes it's curious.

Usually with Microsoft dlls from the Windows API, you use stdcall. Here
with stdcall I get an error "Import library not found  for  libusb-1.0".

So I commented out the stcall changed it to cdecl.

This allows to compile without errors and test1library.pas works without
error, it seems cdecl is the right calling convention for libusb-1.0.

> One other thing is that debugging is much more tedious without an
> integrated debugger that allows you to step through each line before
> you can see which function call blows up with a segfault.
James works on the command line but fp.exe seems to integrate gdb.exe
the same way that lazarus does, you nearly have the same shortcuts keys
for debugging between Turbo Pascal 5.5, fp.exe and lazarus ...
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi
Libusb can be compiled with either calling convention - one just has to
be sure which one.
In https://github.com/Zaaphod/libusbxhid/blob/master/libusbx.pas (line
35), the windows calling convention is stdcall and that apparently works
for both 64 and 32 bit windows. So, James' libusb10 dlls use stdcall.

Also, I was under the impression that unlike linux, Windows apps would
compile regardless of the calling convention. Only when launching the
app and loading a dynamic library a wrong calling convention make things
blow up. Anyway, this is definitely something to look into.

On 8/17/19 11:46 AM, Jean SUZINEAU wrote:

> Le 17/08/2019 à 17:10, Stefan V. Pantazi a écrit :
>> The obvious first thing to make sure is that the calling convention
>> matches the library for the platform. I see that in
>> https://github.com/Zaaphod/pas-libusb/blob/Hack/src/libusb.pas 9line 46)
>> the calling convention on Windows is cdecl (the stdcall is commented
>> out). In libusbxhid, if I remember correctly, the calling convention
>> for windows dlls is set to stdcall.
> Yes it's curious.
>
> Usually with Microsoft dlls from the Windows API, you use stdcall. Here
> with stdcall I get an error "Import library not found  for  libusb-1.0".
>
> So I commented out the stcall changed it to cdecl.
>
> This allows to compile without errors and test1library.pas works without
> error, it seems cdecl is the right calling convention for libusb-1.0.
>
>> One other thing is that debugging is much more tedious without an
>> integrated debugger that allows you to step through each line before
>> you can see which function call blows up with a segfault.
> James works on the command line but fp.exe seems to integrate gdb.exe
> the same way that lazarus does, you nearly have the same shortcuts keys
> for debugging between Turbo Pascal 5.5, fp.exe and lazarus ...
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
I think maybe it is the calling convention...  First I tried to change libusboop.pas (libusb.pas is the old unit, libusboop.pas is the one it uses) to stdcall,  I was unable to compile it, I get an error
libusboop.pas(1456,28) Error: Incompatible types: got "<address of procedure(Plibusb_transfer);StdCall>" expected "<procedure variable type of procedure(Plibusb_transfer);CDecl>"
libusboop.pas(1726) Fatal: There were 1 errors compiling module, stopping

I'm not sure where or how it's expecting CDecl or how to change that to use stdcall.

So for fun I tried doing it the other way around, and changed libusbxhid to cdecl... well it compiled ok but then I tried to run it I got this:
device attempting go clear halt on ep $81
libusb: error [hid_clear_halt] unable to match endpoint to an open interface - cannot clear
clear halt failed

So I don't know what all that really means, but it was an endpoint match problem causing access denied..... so maybe just need to figure out how to get stdcall to properly work with pas-libusb.

James


-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Stefan V. Pantazi
Sent: Saturday, August 17, 2019 12:11 PM
To: [hidden email]
Subject: Re: [fpc-pascal] USB Human Interface Devices

Libusb can be compiled with either calling convention - one just has to be sure which one.
In https://github.com/Zaaphod/libusbxhid/blob/master/libusbx.pas (line 35), the windows calling convention is stdcall and that apparently works for both 64 and 32 bit windows. So, James' libusb10 dlls use stdcall.

Also, I was under the impression that unlike linux, Windows apps would compile regardless of the calling convention. Only when launching the app and loading a dynamic library a wrong calling convention make things blow up. Anyway, this is definitely something to look into.

On 8/17/19 11:46 AM, Jean SUZINEAU wrote:

> Le 17/08/2019 à 17:10, Stefan V. Pantazi a écrit :
>> The obvious first thing to make sure is that the calling convention
>> matches the library for the platform. I see that in
>> https://github.com/Zaaphod/pas-libusb/blob/Hack/src/libusb.pas 9line
>> 46) the calling convention on Windows is cdecl (the stdcall is
>> commented out). In libusbxhid, if I remember correctly, the calling
>> convention for windows dlls is set to stdcall.
> Yes it's curious.
>
> Usually with Microsoft dlls from the Windows API, you use stdcall.
> Here with stdcall I get an error "Import library not found  for  libusb-1.0".
>
> So I commented out the stcall changed it to cdecl.
>
> This allows to compile without errors and test1library.pas works
> without error, it seems cdecl is the right calling convention for libusb-1.0.
>
>> One other thing is that debugging is much more tedious without an
>> integrated debugger that allows you to step through each line before
>> you can see which function call blows up with a segfault.
> James works on the command line but fp.exe seems to integrate gdb.exe
> the same way that lazarus does, you nearly have the same shortcuts
> keys for debugging between Turbo Pascal 5.5, fp.exe and lazarus ...
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  [hidden email] https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi
fromt he copy of your github, looks like libusboop.pas has a uses
statement for libusb.pas; so libusb.pas is still used

https://github.com/Zaaphod/pas-libusb/blob/Hack/src/libusboop.pas (line 30)

Uses
   Classes, SysUtils, LibUsb;




On 8/17/19 1:39 PM, James Richters wrote:

> I think maybe it is the calling convention...  First I tried to change libusboop.pas (libusb.pas is the old unit, libusboop.pas is the one it uses) to stdcall,  I was unable to compile it, I get an error
> libusboop.pas(1456,28) Error: Incompatible types: got "<address of procedure(Plibusb_transfer);StdCall>" expected "<procedure variable type of procedure(Plibusb_transfer);CDecl>"
> libusboop.pas(1726) Fatal: There were 1 errors compiling module, stopping
>
> I'm not sure where or how it's expecting CDecl or how to change that to use stdcall.
>
> So for fun I tried doing it the other way around, and changed libusbxhid to cdecl... well it compiled ok but then I tried to run it I got this:
> device attempting go clear halt on ep $81
> libusb: error [hid_clear_halt] unable to match endpoint to an open interface - cannot clear
> clear halt failed
>
> So I don't know what all that really means, but it was an endpoint match problem causing access denied..... so maybe just need to figure out how to get stdcall to properly work with pas-libusb.
>
> James
>
>
> -----Original Message-----
> From: fpc-pascal <[hidden email]> On Behalf Of Stefan V. Pantazi
> Sent: Saturday, August 17, 2019 12:11 PM
> To: [hidden email]
> Subject: Re: [fpc-pascal] USB Human Interface Devices
>
> Libusb can be compiled with either calling convention - one just has to be sure which one.
> In https://github.com/Zaaphod/libusbxhid/blob/master/libusbx.pas (line 35), the windows calling convention is stdcall and that apparently works for both 64 and 32 bit windows. So, James' libusb10 dlls use stdcall.
>
> Also, I was under the impression that unlike linux, Windows apps would compile regardless of the calling convention. Only when launching the app and loading a dynamic library a wrong calling convention make things blow up. Anyway, this is definitely something to look into.
>
> On 8/17/19 11:46 AM, Jean SUZINEAU wrote:
>> Le 17/08/2019 à 17:10, Stefan V. Pantazi a écrit :
>>> The obvious first thing to make sure is that the calling convention
>>> matches the library for the platform. I see that in
>>> https://github.com/Zaaphod/pas-libusb/blob/Hack/src/libusb.pas 9line
>>> 46) the calling convention on Windows is cdecl (the stdcall is
>>> commented out). In libusbxhid, if I remember correctly, the calling
>>> convention for windows dlls is set to stdcall.
>> Yes it's curious.
>>
>> Usually with Microsoft dlls from the Windows API, you use stdcall.
>> Here with stdcall I get an error "Import library not found  for  libusb-1.0".
>>
>> So I commented out the stcall changed it to cdecl.
>>
>> This allows to compile without errors and test1library.pas works
>> without error, it seems cdecl is the right calling convention for libusb-1.0.
>>
>>> One other thing is that debugging is much more tedious without an
>>> integrated debugger that allows you to step through each line before
>>> you can see which function call blows up with a segfault.
>> James works on the command line but fp.exe seems to integrate gdb.exe
>> the same way that lazarus does, you nearly have the same shortcuts
>> keys for debugging between Turbo Pascal 5.5, fp.exe and lazarus ...
>> _______________________________________________
>> fpc-pascal maillist  -  [hidden email]
>> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
> --
> _______________________________________________________
> _______________________________________________
> fpc-pascal maillist  -  [hidden email] https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

--
_______________________________________________________
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: *** SPAM *** Re: USB Human Interface Devices

Jean SUZINEAU
In reply to this post by Zaaphod
Le 17/08/2019 à 19:39, James Richters a écrit :
> I think maybe it is the calling convention...  First I tried to change libusboop.pas (libusb.pas is the old unit, libusboop.pas is the one it uses) to stdcall,  I was unable to compile it, I get an error
> libusboop.pas(1456,28) Error: Incompatible types: got "<address of procedure(Plibusb_transfer);StdCall>" expected "<procedure variable type of procedure(Plibusb_transfer);CDecl>"
> libusboop.pas(1726) Fatal: There were 1 errors compiling module, stopping

Yes , this is because extdecl is defined a first time in libusb.pas line
45 and a second time in libusboop.pas line 21.
If you change it in libusboop, you need to change it accordingly in
libusb.pas.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
123456789