Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2019-07

USB Human Interface Devices

165 messages · 9 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

James Richters

Does Freepascal have support for USB Human Interface devices? I am attempting to interface to an WHB04B-4 https://www.amazon.com/gp/product/B07M5ZY1P2

I have an example of how to do it that was written in Python, so I’m trying to figure out how to get it to work with my FPC console application. Figuring out how to interface with the device at all is what is holding me up, I don’t have any experience with direct interfacing to any USB devices.

Any suggestions?

James

Reply by email

Dimitrios Chr. Ioannidis
to James Richters

Hi,

Στις 26/7/2019 1:04 π.μ., ο James Richters έγραψε:

Show quoted text 13 lines
Does Freepascal have support for USB Human Interface devices?   I am attempting to interface to an WHB04B-4 https://www.amazon.com/gp/product/B07M5ZY1P2 I have an example of how to do it that was written in Python, so I’m trying to figure out how to get it to work with my FPC console application.   Figuring out how to interface with the device at all is what is holding me up, I don’t have any experience with direct interfacing to any USB devices. Any suggestions?

you could try Alfred's HID library ( works in windows and linux ) .

https://github.com/LongDirtyAnimAlf/FPC-USB-HID.

regards,

Dimitrios Chr. Ioannidis

Reply by email

James Richters
to Brian

I am using synapse for RS-232 and I have played with ethernet with it with good results. This device I am trying to use now is only available in USB and it's NOT a USB-Serial device.. The sample program I am referencing accesses it thorough an HID interface

James

Earlier message 16 lines
-----Original Message----- From: fpc-pascal On Behalf Of Brian Sent: Thursday, July 25, 2019 8:00 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices If you can find a controller with an Ethernet input then Synapse is simple and works well. I have used it for RS-232 and Ethernet , but it claims to work with USB http://www.ararat.cz/synapse/doku.php/start -- Sent from: http://free-pascal-general.1045716.n5.nabble.com/

Reply by email

James Richters
to Brian

I've been trying to get some of these suggestions to work, but they all seem to require Lazarus, which I don't have and don't even know how to use. I'm looking for a solution that will work in a pure FPC console application in Windows, without Lazarus. I started trying to convert the demo programs into FPC only demos but there are just too many units I don't have and I don't know how to get around that. The project I am trying to integrate this into is huge and several hundred thousand lines of code, and has been in development for 30 years, starting back with Turbo Pascal it would be completely impossible to port it all over to Lazarus. I've tried just compiling my project with Lazarus before and just ran into issue after issue with it. I’m currently using FPC 3.0.4RC1

Anyone have any suggestions for an FPC only console application method or demo I could use to access this USB HID device?

James

Earlier message 14 lines
-----Original Message----- From: fpc-pascal On Behalf Of Brian Sent: Thursday, July 25, 2019 10:41 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Try the libusb library Free Pascal interface .. but be aware of his license requirements. It works well. http://johann-glaser.blogspot.com/2012/07/libusb-for-pascal.html -- Sent from: http://free-pascal-general.1045716.n5.nabble.com/

Reply by email

Dimitrios Chr. Ioannidis
to James Richters

Hi,

On 2019-07-26 13:39, James Richters wrote:
< snip >

Anyone have any suggestions for an FPC only console application method or demo I could use to access this USB HID device?

< snip >

As I suggested in my previous mail You can use the fpc-usb-hid library from Alfred. I don't see any dependency for Lazarus in the usbcontroller.pas which is, AFAIU, the main unit.

If you're not in a hurry, I could try to make a simple console demo this weekend.

regards,

Dimitrios Chr. Ioannidis

Reply by email

José Mejuto
to James Richters: I've been trying to get some of these suggestions to work, but they all seem to require…
James Richters wrote
Anyone have any suggestions for an FPC only console application method or demo I could use to access this USB HID device?

Hello,

This is not a complete HID interface but it can help you to start working with them. It has been designed to handle USB Relays which are managed using HID interface. Demos with and without GUI.

https://github.com/JoshyFun/VUSBRelayPascal

Reply by email

James Richters
to Dimitrios Chr. Ioannidis: < snip > < snip > As I suggested in my previous mail You can use the fpc-usb-hid library…

I did try fpc-usb-hid, it uses units: BaseUnix and Unix which I don't have, and don't know what they are. I tried commenting them out thinking maybe they were needed for Linux, but then it just can't find a lot of other things... I am on Windows and using FPX 3.0.4RC1, if the units I need are in a later version of FPC I can update it.

A console demo would be a great help and very much appreciated, I am not in a huge hurry.

Earlier message 25 lines
-----Original Message----- From: fpc-pascal On Behalf Of Dimitrios Chr. Ioannidis via fpc-pascal Sent: Friday, July 26, 2019 6:51 AM To: FPC-Pascal users discussions Cc: Dimitrios Chr. Ioannidis Subject: Re: [fpc-pascal] USB Human Interface Devices Hi, On 2019-07-26 13:39, James Richters wrote: < snip > > Anyone have any suggestions for an FPC only console application method > or demo I could use to access this USB HID device? < snip > As I suggested in my previous mail You can use the fpc-usb-hid library from Alfred. I don't see any dependency for Lazarus in the usbcontroller.pas which is, AFAIU, the main unit. If you're not in a hurry, I could try to make a simple console demo this weekend. regards, -- Dimitrios Chr. Ioannidis

Reply by email

Marc Santhoff
to James Richters
James Richters wrote 5 lines
I did try fpc-usb-hid, it uses units: BaseUnix and Unix which I don't have, and don't know what they are. I tried commenting them out thinking maybe they were needed for Linux, but then it just can't find a lot of other things... I am on Windows and using FPX 3.0.4RC1, if the units I need are in a later version of FPC I can update it.

If baseUnix ans Unix are in use, the code is for unixoid OS. Linux, *BSD, etc. The current LibUSB does support Windows, as you can see here:

https://libusb.info/

But I _think_ the Pascal header adaption will need to be ported to Windows. Maybe someone else knows better?

Show quoted text 38 lines
A console demo would be a great help and very much appreciated, I am not in a huge hurry. -----Original Message----- From: fpc-pascal On Behalf Of Dimitrios Chr. Ioannidis via fpc-pascal Sent: Friday, July 26, 2019 6:51 AM To: FPC-Pascal users discussions Cc: Dimitrios Chr. Ioannidis Subject: Re: [fpc-pascal] USB Human Interface Devices Hi, On 2019-07-26 13:39, James Richters wrote: < snip > > Anyone have any suggestions for an FPC only console application method > or demo I could use to access this USB HID device? < snip > As I suggested in my previous mail You can use the fpc-usb-hid library from Alfred. I don't see any dependency for Lazarus in the usbcontroller.pas which is, AFAIU, the main unit. If you're not in a hurry, I could try to make a simple console demo this weekend. regards, -- Dimitrios Chr. Ioannidis _______________________________________________ fpc-pascal maillist - https://lists.freepa scal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Marc Santhoff

Reply by email

Johann Glaser
to Marc Santhoff: http://johann-glaser.blogspot.com/2012/09/libusb-10-for-pascal.html Marc Santhoff

Hi!

Marc Santhoff wrote 8 lines
On Thu, 2019-07-25 at 19:40 -0700, Brian wrote: > Try the libusb library Free Pascal interface .. but be aware of his > license > requirements. It works well. > > http://johann-glaser.blogspot.com/2012/07/libusb-for-pascal.html http://johann-glaser.blogspot.com/2012/09/libusb-10-for-pascal.html

Thanks for referring to my translation!

@Brian: I wasn't even aware of a license topic, but when checking back now, the wrapper for the "old" libusb 0.1 states GPL in the README. I think this was a bad idea.

Thanks to Marc to point to the newer wrapper for libusb 1.0, which uses the same license as libusb, and for all stuff from me the same as the FPC units. Just use the branch "libusb-1.0".

Anyhow, I would recommend to use libusb 1.0.

If you need any support, feel free to contact me.

Bye
Hansi

Reply by email

Jean SUZINEAU
to James Richters: I've been trying to get some of these suggestions to work, but they all seem to require…

You can compile console projects with Lazarus, and even use non visual components and datamodules. I've coded a dll (several hundred thousand lines of code too) which is used by console programs on web servers. I compile the dll with the same lazarus project in Lazarus for Windows  and in Lazarus for Linux. The dll include datamodules with dataset components.

Reply by email

Marc Santhoff
to Johann Glaser: Hi! Thanks for referring to my translation! @Brian: I wasn't even aware of a license…
Johann Glaser wrote 23 lines
Hi! Am Freitag, den 26.07.2019, 15:56 +0200 schrieb Marc Santhoff: > On Thu, 2019-07-25 at 19:40 -0700, Brian wrote: > > Try the libusb library Free Pascal interface .. but be aware of his > > license > > requirements. It works well. > > > > http://johann-glaser.blogspot.com/2012/07/libusb-for-pascal.html > > http://johann-glaser.blogspot.com/2012/09/libusb-10-for-pascal.html Thanks for referring to my translation! @Brian: I wasn't even aware of a license topic, but when checking back now, the wrapper for the "old" libusb 0.1 states GPL in the README. I think this was a bad idea. Thanks to Marc to point to the newer wrapper for libusb 1.0, which uses the same license as libusb, and for all stuff from me the same as the FPC units. Just use the branch "libusb-1.0". Anyhow, I would recommend to use libusb 1.0.

I've seen "$ifdef Windows" in the Code, so it does support Windows without any change?

If so, that would be James' solution.

Marc Santhoff

Reply by email

Johann Glaser
to Marc Santhoff

Hi!

Marc Santhoff wrote 29 lines
On Fri, 2019-07-26 at 22:37 +0200, Johann Glaser wrote: > Hi! > > Am Freitag, den 26.07.2019, 15:56 +0200 schrieb Marc Santhoff: > > On Thu, 2019-07-25 at 19:40 -0700, Brian wrote: > > > Try the libusb library Free Pascal interface .. but be aware of his > > > license > > > requirements. It works well. > > > > > > http://johann-glaser.blogspot.com/2012/07/libusb-for-pascal.html > > > > http://johann-glaser.blogspot.com/2012/09/libusb-10-for-pascal.html > > Thanks for referring to my translation! > > @Brian: I wasn't even aware of a license topic, but when checking back > now, the wrapper for the "old" libusb 0.1 states GPL in the README. I > think this was a bad idea. > > Thanks to Marc to point to the newer wrapper for libusb 1.0, which uses > the same license as libusb, and for all stuff from me the same as the > FPC units. Just use the branch "libusb-1.0". > > Anyhow, I would recommend to use libusb 1.0. I've seen "$ifdef Windows" in the Code, so it does support Windows without any change? If so, that would be James' solution.

I've never tested it on Windows myself, but I integrated some changes provided by other users quite some time ago.

BTW: A few weeks ago I was contacted on Github regarding Windows support. The user had some issues, but then he found a solution.

https://github.com/hansiglaser/pas-libusb/issues/4

Due to my lack of understanding of Windows, I've not yet taken over his changes, because I wanted to wait for confirmation from other users. So if James had some feedback, I'd appreciate it greatly.

Thanks
Hansi

Reply by email

James Richters
to Johann Glaser
>Due to my lack of understanding of Windows, I've not yet taken over his changes, because I wanted to wait for confirmation from other users. So if James had some feedback, I'd appreciate it greatly.

I'm trying to get this to work on windows, I'm having a lot of units not found errors when I try to compile anything at all.. I'm not sure what I need here to get the examples to work. Here is a list of units I can't find when I try to compile with FPC 3.0.4RC1 on Windows:

ezusb.pas(42,15) Fatal: Can't find unit Errors used by EZUSB
I have no idea what Unit Errors is or what it might be for.

libusb.pas(1350) Warning: Library c.dll not found, Linking may fail ! ■ libusb.pas(1350) Warning: Library usb-1.0 not found, Linking may fail ! I'm not really following where c.dll and usb1.0 are supposed to come from

usb.pas(31,22) Fatal: Can't find unit Baseunix used by USB
mydevice.pas(27,20) Fatal: Can't find unit BaseUnix used by MyDevice
I have no idea what BaseUnix does or if I can do something windows compatible instead somehow.

Test1Library.pas:
║ (0) Error: Import library not found for c
║ (0) Error: Import library not found for usb-1.0

To be honest this is quite a bit over my head. I'm trying to follow https://github.com/hansiglaser/pas-libusb/issues/4 but I'm just lost.

James

Reply by email

Johann Glaser
to James Richters

Hi James!

James Richters wrote 13 lines
> > Due to my lack of understanding of Windows, I've not yet taken > > over his changes, because I wanted to wait for confirmation from > > other users. So if James had some feedback, I'd appreciate it > > greatly. I'm trying to get this to work on windows, I'm having a lot of units not found errors when I try to compile anything at all.. I'm not sure what I need here to get the examples to work. Here is a list of units I can't find when I try to compile with FPC 3.0.4RC1 on Windows: ezusb.pas(42,15) Fatal: Can't find unit Errors used by EZUSB I have no idea what Unit Errors is or what it might be for.

Thanks for pointing this out. This is a Unix unit, but it is obviously not used in Ezusb. I've removed it now.

libusb.pas(1350) Warning: Library c.dll not found, Linking may fail ! ■ libusb.pas(1350) Warning: Library usb-1.0 not found, Linking may fail ! I'm not really following where c.dll and usb1.0 are supposed to come from

It seems you didn't install the development stuff for libc and lib-usb? At least in Linux, I always have to install these additionally (e.g., libusb-1.0-0-dev) to the "productive" libraries (e.g., libusb-1.0-0).

usb.pas(31,22) Fatal: Can't find unit Baseunix used by USB

Same as above for Errors. However, this file is unused.

mydevice.pas(27,20) Fatal: Can't find unit BaseUnix used by MyDevice I have no idea what BaseUnix does or if I can do something windows compatible instead somehow.

Same as above for Errors.

Test1Library.pas: ║ (0) Error: Import library not found for c ║ (0) Error: Import library not found for usb-1.0

This seems to be again a problem because of the missing development stuff for libc anc libusb.

To be honest this is quite a bit over my head. I'm trying to follow https://github.com/hansiglaser/pas-libusb/issues/4 but I'm just lost.

I would recommend, first to just compile the pristine pas-libusb without any hints from that Github issue. Only if you get the same errors, please try them and let me know.

As stated above, I've now removed all references to the units Errors and Baseunix. Please "git pull" to the newest state on Github and compile again. If you still face problems, please don't hesitate to ask again.

Thanks
Hansi

Reply by email

James Richters
to Johann Glaser: Hi James! Thanks for pointing this out. This is a Unix unit, but it is obviously not used…

Thanks for removing the un-needed units. I have been trying to compile as-is without any modifications. I was not aware that this was dependent on LibC and Lib-USB. I am not really clear on how to install these, maybe I just need to download the correct files and have them in the same directory I am trying to compile Pas-LibUSB from? I quite literally have a stock installation of FPC3.0.4RC1 and that is all.. nothing else, no Lazarus, no LibC or LibUSB anything development or otherwise. So it seems the first step will be to install the prerequisite packages. I'll see if I can figure that out.

James

Earlier message 61 lines
-----Original Message----- From: fpc-pascal On Behalf Of Johann Glaser Sent: Tuesday, July 30, 2019 4:54 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi James! Am Dienstag, den 30.07.2019, 13:52 -0400 schrieb James Richters: > > > Due to my lack of understanding of Windows, I've not yet taken > > > over his changes, because I wanted to wait for confirmation from > > > other users. So if James had some feedback, I'd appreciate it > > > greatly. > > I'm trying to get this to work on windows, I'm having a lot of units > not found errors when I try to compile anything at all.. I'm not sure > what I need here to get the examples to work. Here is a list of > units I can't find when I try to compile with FPC 3.0.4RC1 on > Windows: > > ezusb.pas(42,15) Fatal: Can't find unit Errors used by EZUSB I have no > idea what Unit Errors is or what it might be for. Thanks for pointing this out. This is a Unix unit, but it is obviously not used in Ezusb. I've removed it now. > libusb.pas(1350) Warning: Library c.dll not found, Linking may fail ! ■ > libusb.pas(1350) Warning: Library usb-1.0 not found, Linking may fail ! > I'm not really following where c.dll and usb1.0 are supposed to come > from It seems you didn't install the development stuff for libc and lib-usb? At least in Linux, I always have to install these additionally (e.g., libusb-1.0-0-dev) to the "productive" libraries (e.g., libusb-1.0-0). > usb.pas(31,22) Fatal: Can't find unit Baseunix used by USB Same as above for Errors. However, this file is unused. > mydevice.pas(27,20) Fatal: Can't find unit BaseUnix used by MyDevice I > have no idea what BaseUnix does or if I can do something windows > compatible instead somehow. Same as above for Errors. > Test1Library.pas: > ║ (0) Error: Import library not found for c ║ (0) Error: Import > library not found for usb-1.0 This seems to be again a problem because of the missing development stuff for libc anc libusb. > To be honest this is quite a bit over my head. I'm trying to follow > https://github.com/hansiglaser/pas-libusb/issues/4 but I'm just lost. I would recommend, first to just compile the pristine pas-libusb without any hints from that Github issue. Only if you get the same errors, please try them and let me know. As stated above, I've now removed all references to the units Errors and Baseunix. Please "git pull" to the newest state on Github and compile again. If you still face problems, please don't hesitate to ask again. Thanks Hansi

Reply by email

Johann Glaser
to James Richters

Hi!

James Richters wrote 11 lines
Thanks for removing the un-needed units. I have been trying to compile as-is without any modifications. I was not aware that this was dependent on LibC and Lib-USB. I am not really clear on how to install these, maybe I just need to download the correct files and have them in the same directory I am trying to compile Pas-LibUSB from? I quite literally have a stock installation of FPC3.0.4RC1 and that is all.. nothing else, no Lazarus, no LibC or LibUSB anything development or otherwise. So it seems the first step will be to install the prerequisite packages. I'll see if I can figure that out.

Yes, pas-libusb is a Pascal wrapper for the Linux library libusb. That library itself further depends on libc. Thats why you have to install them, and including their respective development packages.

Was the message of Jean helpful for you?

Thanks
Hansi

Show quoted text 86 lines
-----Original Message----- From: fpc-pascal On Behalf Of Johann Glaser Sent: Tuesday, July 30, 2019 4:54 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi James! Am Dienstag, den 30.07.2019, 13:52 -0400 schrieb James Richters: > > > Due to my lack of understanding of Windows, I've not yet taken > > > over his changes, because I wanted to wait for confirmation > > > from > > > other users. So if James had some feedback, I'd appreciate it > > > greatly. > > I'm trying to get this to work on windows, I'm having a lot of > units > not found errors when I try to compile anything at all.. I'm not > sure > what I need here to get the examples to work. Here is a list of > units I can't find when I try to compile with FPC 3.0.4RC1 on > Windows: > > ezusb.pas(42,15) Fatal: Can't find unit Errors used by EZUSB I have > no > idea what Unit Errors is or what it might be for. Thanks for pointing this out. This is a Unix unit, but it is obviously not used in Ezusb. I've removed it now. > libusb.pas(1350) Warning: Library c.dll not found, Linking may fail > ! ■ > libusb.pas(1350) Warning: Library usb-1.0 not found, Linking may > fail ! > I'm not really following where c.dll and usb1.0 are supposed to > come > from It seems you didn't install the development stuff for libc and lib- usb? At least in Linux, I always have to install these additionally (e.g., libusb-1.0-0-dev) to the "productive" libraries (e.g., libusb-1.0-0). > usb.pas(31,22) Fatal: Can't find unit Baseunix used by USB Same as above for Errors. However, this file is unused. > mydevice.pas(27,20) Fatal: Can't find unit BaseUnix used by > MyDevice I > have no idea what BaseUnix does or if I can do something windows > compatible instead somehow. Same as above for Errors. > Test1Library.pas: > ║ (0) Error: Import library not found for c ║ (0) Error: Import > library not found for usb-1.0 This seems to be again a problem because of the missing development stuff for libc anc libusb. > To be honest this is quite a bit over my head. I'm trying to > follow > https://github.com/hansiglaser/pas-libusb/issues/4 but I'm just > lost. I would recommend, first to just compile the pristine pas-libusb without any hints from that Github issue. Only if you get the same errors, please try them and let me know. As stated above, I've now removed all references to the units Errors and Baseunix. Please "git pull" to the newest state on Github and compile again. If you still face problems, please don't hesitate to ask again. Thanks Hansi _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser

I understand it better now, but I've been out of town and haven't been able to work on it. I'm not sure what is meant by installing development packages though.. I see libusb at https://libusb.info/ I see where to download that.. but I don't know about development packages? As for LibC, I'm not really sure where to find the proper package for that. I found http://gnuwin32.sourceforge.net/packages/libc.htm.bak but I'm not sure that is right, and again not sure about development package for that. I would really appreciate links to the exact packages I will need to use for Windows.

James

Yes, pas-libusb is a Pascal wrapper for the Linux library libusb. That library itself further depends on libc. Thats why you have to install them, and including their respective development packages. Was the message of Jean helpful for you?

Reply by email

Jean SUZINEAU
to James Richters

@Johann: Is the Readme.rst at https://github.com/hansiglaser/pas-libusb up to date ?
It states that only the legacy version 0.1 of libusb is supported, but the binary package for Windows on libusb.info is in version 1.0.22. You can get source code for old versions of libusb on github but it seems at first glance that there are no release of windows version before 1.0.20 (14 sep 2015) (
https://github.com/libusb/libusb/releases?after=v1.0.21-rc4 ).

I tried to compile TestFirmware.pas on windows, I made a few modifications. I join the diff files.
In ezusb.pas I replaced the dependency to Errors unit by a quick and dirty rewrite of StrError function, just to allow compilation. In paslibusbutils.pas I replace the call to fpGetTimeOfDay by a call to DateTimeToUnix(Now),  I'm not sure may be the result of DateTimeToUnix is truncated to seconds where fpGetTimeOfDay gives a result in microseconds. In usb.pas I duplicated some constant definitions from errno.inc included in unit BaseUnix: ESysETIMEDOUT, ESysEAGAIN... I also replaced the call to fpSelect(0,Nil,Nil,Nil,100) by Sleep(100) which should do the same thing, waiting for 100 milliseconds.

@James: Now, I just get the two final errors "Import library not found for c" and "Import library not found for usb".
For now I haven't found which library to use for c. I'm preparing another mail for this.

Reply by email

Jean SUZINEAU
to Jean SUZINEAU

I've forgotten to give the command line to compile (change "C:\lazarus\fpc\3.0.4\bin\x86_64-win64" to your fpc installation):

C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.exe -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -Filib\x86_64-win64 -Fu..\pas-libusb\src -Fu. -FUlib\x86_64-win64 -FE. -olsusb.exe lsusb.lpr

Reply by email

Johann Glaser
to Jean SUZINEAU

Hi Jean!

Thanks for your effort and please excuse my late reply, I was busy the last few days.

Please note that for pas-libusb there is a dedicated Git branch for the newer LibUSB 1.0. The branch is called "libusb-1.0". Marc pointed to that in his EMail from Fri, 26 Jul 2019 15:56:17 +0200.

I'm sorry for the confusion! I've now updated the Readme.rst in the branch "master" to point that out.

In the branch "libusb-1.0" I've lately changed a few things (see my EMail from Tue, 30 Jul 2019 22:54:07 +0200) so that all dependencies to Linux units should be gone.

Actually, with the branch "libusb-1.0" you should not need any "compat" stuff any more.

Could you please give that a try and see whether you are more successful with it?

Regarding "lsusb": The "test1library.pas" example should be just that.

Regarding the testfirmware example: This is specifically for devices with the EZUSB Chip (e.g., Cypress AN2131). It is included to demonstrate, how you could implement your own interface to your own device with other chips with SRAM firmware (e.g. Cypress FX2 or FX3).

Bye
Hansi

Jean SUZINEAU wrote 35 lines
Zadig I found a way to make my test with libusb-win32 work. You just need to install a specific driver for the usb device you want to see. This can be done using Zadig ( https://zadig.akeo.ie/ ). If you change the driver to "libusbK" or "libusb-win32" for a certain device with Zadig, it will appear with lsusb_libusb-win32\lsusb.exe . But it doesn't change anything for the version with libusb-compat, lsusb_libusb-compat-msys2_mingw64\lsusb.exe wich shows nothing. And it doesn't change anything either to the version with libusb, https://github.com/jsuzineau/pascal_o_r_mapping/releases/tag/2019_08_03_lsusb which continue to show all the usb devices. I have also tried libusbK ( http://libusbk.sourceforge.net/UsbK3/index.html ). You can download it at https://sourceforge.net/projects/libusbk/ There are delphi examples in the subdirectory bindings\examples_delphi . They can be compiled easily with freepascal, you just need to compile in delphi mode. For "bindings\examples_delphi\enumerate.dpr" you can use this command line ( from a cmd in the directory examples_delphi) C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.exe -MDelphi -Scghi -O1 -g -gl -l -vewnhibq -Filib\x86_64-win64 -Fu. -FUlib\x86_64-win64 -FE. -oenumerate.exe enumerate.dpr For "bindings\examples_delphi\opendevice.dpr" it didn't found unit UExampleHelpers. I didn't investigated further but it seems you can find the unit at : https://github.com/SimaWB/libusbkDelphi/blob/master/UExampleHelpers.pas _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Johann Glaser
to James Richters: I understand it better now, but I've been out of town and haven't been able to work on…

Hi James!

James Richters wrote 10 lines
I understand it better now, but I've been out of town and haven't been able to work on it. I'm not sure what is meant by installing development packages though.. I see libusb at https://libusb.info/ I see where to download that.. but I don't know about development packages? As for LibC, I'm not really sure where to find the proper package for that. I found http://gnuwin32.sourceforge.net/packages/libc.htm.bak but I'm not sure that is right, and again not sure about development package for that. I would really appreciate links to the exact packages I will need to use for Windows.

I'm sorry that I can't help you here with these Windows-specific questions.

Could somebody else please help out here?

Thanks
Hansi

Reply by email

James Richters
to Jean SUZINEAU

Hi Jean, Thank you very much for your help getting this to work. I’ve been out of town on a business trip but I’m finally back now, and trying to follow all this. I’ve been trying to follow along the conversation with Email but I did not have a very reliable internet connection. I did see a zip file you posted, but then it seems you made more changes since then, I’m not sure how to apply .diff files.

Would it be possible to get an update zip file of the current files?

I’m afraid a lot of this is just way over my head, I did not expect it to be anywhere near this complicated to get this to work, they python code I am trying to duplicate in my FPC application is so simple, but without access to the packages it uses, it’s turning out to be very complicated indeed.. ironically, the unit I am trying to get to work is called EasyHID, but it seem to be anything but easy.

Here is the python code that I am trying to implement in my FPC program:

https://github.com/wolfmanjm/kivy-smoothie-host/blob/master/modules/hb04.py

James

Earlier message 48 lines
From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Sunday, August 4, 2019 12:39 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Le 04/08/2019 à 14:07, Johann Glaser a écrit : Hi James! Am Donnerstag, den 01.08.2019, 22:45 -0400 schrieb James Richters: I understand it better now, but I've been out of town and haven't been able to work on it. I'm not sure what is meant by installing development packages though.. I see libusb at https://libusb.info/ I see where to download that.. but I don't know about development packages? As for LibC, I'm not really sure where to find the proper package for that. I found http://gnuwin32.sourceforge.net/packages/libc.htm.bak but I'm not sure that is right, and again not sure about development package for that. I would really appreciate links to the exact packages I will need to use for Windows. I'm sorry that I can't help you here with these Windows-specific questions. Could somebody else please help out here? When you link to the dll, you can remove the {$LINKLIB c}. But for now I haven't been able to make it work with a static link. I added to project library search path in lazarus: E:\03_travail\libusb\libusb-1.0.22\MinGW64\static\ wich contains libusb-1.0.a Then I changed {$LINKLIB usb-1.0} to {$LINKLIB libusb-1.0}, and removed {$LINKLIB c} (I join the diff files) In this way, libusb-1.0.a is found by the compiler, but the dependencies of libusb-1.0.a on C runtime and several Windows system function are not fullfilled and you get these errors (I join them in file Compiler_output.txt) Some of them like WaitForSingleObject are provided by Kernel32.dll but I don't know which lib from MinGW64 to use to provide __imp_WaitForSingleObject. Some others like atoi seem to be from the c runtime, but I haven't found yet where are its libs (interesting link: https://stackoverflow.com/questions/52376724/mingw-w64-c-versions-support )

Reply by email

James Richters
to Jean SUZINEAU

Hi Jean,

Thank you very much for posting the zip, I’ll download it and see if I can figure it out. Also thank you very much for your efforts and help with this. It is VERY much appreciated!

James

Earlier message 44 lines
From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Monday, August 5, 2019 6:49 AM To: James Richters ; 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices Hi James, Le 05/08/2019 à 04:40, James Richters a écrit : Hi Jean, Thank you very much for your help getting this to work. I’ve been out of town on a business trip but I’m finally back now, and trying to follow all this. I’ve been trying to follow along the conversation with Email but I did not have a very reliable internet connection. I did see a zip file you posted, but then it seems you made more changes since then, I’m not sure how to apply .diff files. Would it be possible to get an update zip file of the current files? I put a zip of my working directory of pas-libusb as a pseudo "convenience" release on my github repository : https://github.com/jsuzineau/pascal_o_r_mapping/releases/tag/pas-libusb_convenience_release You should find every thing needed in it, you can even see my modifications with Tortoise Git, the .git subdirectory is included. Let me know if I forgot something or if you get a problem. I’m afraid a lot of this is just way over my head, I did not expect it to be anywhere near this complicated to get this to work, they python code I am trying to duplicate in my FPC application is so simple, but without access to the packages it uses, it’s turning out to be very complicated indeed.. ironically, the unit I am trying to get to work is called EasyHID, but it seem to be anything but easy. Here is the python code that I am trying to implement in my FPC program: https://github.com/wolfmanjm/kivy-smoothie-host/blob/master/modules/hb04.py I'm busy today, I had a quick , I haven't yet tried to open a device with pas-usb but I don't think it would be too much difficult.

Reply by email

Johann Glaser
to Jean SUZINEAU:

Hi Jean!

Jean SUZINEAU wrote 36 lines
Hi Hansi, Le 04/08/2019 à 14:05, Johann Glaser a écrit : > Thanks for your effort and please excuse my late reply, I was > busy thelast few days. > With pleasure. test1library.pas from branch "libusb-1.0" worked nearly out of the box. I nearly just needed to redefine extdecl from stdcall to cdecl as in Linux. I copied (libusb-1.0.22)\MinGW64\dll\libusb-1.0.dll of 274 Ko to (pas-libusb branch libusb-1.0)\src\examples. In libusb.pas I removed {$LINKLIB c} and changed {$LINKLIB usb-1.0} to {$LINKLIB libusb-1.0.dll} I join my diff files. Lazarus made a few changes to test1library.lpi but I don't think they are important.

Amazing, thanks for trying and giving feedback!

So, from my perspective, your results and modifications are the same as those of Vitaly at
https://github.com/hansiglaser/pas-libusb/issues/4

Referring to your EMail to James, it seems that Vitaly even got it working with static linking. Especially "$LINKLIB msvcrt" and "$LINKLIB usb-1.0.dll.a" look promising. Hmm, OTOH he writes of dynamically linked, I don't know.

Could you please also have a look at his comments in that Github issue?

Show quoted text 39 lines
I verified, test1library can be build with this command line: C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.exe -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -Filib\x86_64-win64 -Fu.. -Fu. -FUlib\x86_64-win64 -FE. -otest1library.exe test1library.pas (eventually you need to create subdirectory lib\x86_64-win64 by hand) Upon execution, I got this results: :\03_travail\libusb\pas-libusb\src\examples>test1library.exeUsing libusb(x) v1.0.22.11312Found 13 devices: Bus 1 Device 15: ID 10C4:EA60, port: 14, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 12: ID 28DE:2101, port: 7, port path from HCD: 0->11->11, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 0: ID 8086:A2AF, port: 0, Speed: Unknown Bus 1 Device 10: ID 0BB4:2C87, port: 5, port path from HCD: 0->5->5, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 9: ID 0BB4:2C87, port: 2, port path from HCD: 0->0->0, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 4: ID 1C4F:0002, port: 7, port path from HCD: 0, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 1 Device 2: ID 046D:C077, port: 8, port path from HCD: 0, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 1 Device 8: ID 28DE:2000, port: 1, port path from HCD: 0->1->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 7: ID 0BB4:0306, port: 2, port path from HCD: 0->33, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 11: ID 28DE:2101, port: 6, port path from HCD: 0->128- >128, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 5: ID 07CA:A110, port: 5, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 6: ID 0BB4:2134, port: 1, port path from HCD: 0->0, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 1: ID 0BB4:2210, port: 11, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) E:\03_travail\libusb\pas-libusb\src\examples>

Yay! That looks great!

As a next step you can try test2controlsync.pas which uses control transfers to query the device descriptors. Just change the constants DevVID and DevPID at the top to the values of a device connected to your PC. I'd recommend to use a device you don't depend on during testing, i.e., don't use your primary keyboard and mouse. :-) There shouldn't be a problem, but better safe than sorry. And I hope that Windows doesn't cross your plans and already has allocated that device to a certain driver.

You can also try test3controlasync.pas, which does a very similar test, just using the asynchronous interface to libusb (and it is less verbose and estensive).

For trying real custom communication (e.g., to bulk endpoints) you would need an appropriate USB device. For example at https://github.com/hansiglaser/pas-gpib/blob/master/usb/usbtmc.pas I've implemented communication with electrical measurement devices (GPIB via USB). Somewhere on my harddisk I should have a driver for a barcode reader. And also drivers for a few devices built by myself. If you are interested or have questions, I can provide some sources too.

Bye
Hansi

Reply by email

James Richters

Or for me to learn anything at all about it…. As you probably can guess I haver zero USB experience.

James

With pleasure. It's a good occasion for me to learn a bit more on USB.

Reply by email

James Richters
to Johann Glaser: Hi Jean! Amazing, thanks for trying and giving feedback! So, from my perspective, your…

I am trying to compile this with a stock installation of FPC 3.0.4 for windows… which does not have 64bit.. it only installs i386-win32 and then there is a cross compiler for x86_64-win64

I started with the zip file at:

https://github.com/jsuzineau/pascal_o_r_mapping/releases/tag/pas-libusb_convenience_release_2

then I created an lib\i386-win32 subdirectory

then from this subdirectory: I:\Programming\pas-libusb_test_dll\src\examples>

I used this command line:

I:\Programming\FPC\3.0.4\bin\i386-win32\fpc.exe -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -Filib\i386-win32\ -Fu.. -Fu. -FUlib\i386-win32\ -FE. -otest1library.exe test1library.pas

Here is the output:

Hint: (11030) Start of reading config file I:\Programming\FPC\3.0.4\bin\i386-win32\fpc.cfg

Hint: (11031) End of reading config file I:\Programming\FPC\3.0.4\bin\i386-win32\fpc.cfg

Free Pascal Compiler version 3.0.4 [2017/10/06] for i386

Copyright (c) 1993-2017 by Florian Klaempfl and others

(1002) Target OS: Win32 for i386

(3104) Compiling test1library.pas

(3104) Compiling I:\Programming\pas-libusb_test_dll\src\libusb.pas

I:\Programming\pas-libusb_test_dll\src\libusb.pas(1315,13) Hint: (4035) Mixing signed expressions and longwords gives a 64bit result
I:\Programming\pas-libusb_test_dll\src\libusb.pas(1333,13) Hint: (4035) Mixing signed expressions and longwords gives a 64bit result

libusb.pas(1355) Error: Invalid DLL libusb-1.0.dll, invalid header size

I:\Programming\pas-libusb_test_dll\src\libusb.pas(1351,1) Fatal: (10026) There were 1 errors compiling module, stopping

Fatal: (1018) Compilation aborted

Error: I:\Programming\FPC\3.0.4\bin\i386-win32\ppc386.exe returned an error exitcode

Any ideas? Is this just from using i386-win32? Maybe the DLL is only for 64bit? Maybe some completely unrelated issue? If 64bit is needed, what’s the best way to install FPC3.0.4 for x86_64-win64? It seems like I tried to do that before and it wasn’t really very easy to try to learn how to compile it.

James

I verified, test1library can be build with this command line:

C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.exe -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -Filib\ x86_64-win64 -Fu.. -Fu. -FUlib\x86_64-win64 -FE. -otest1library.exe test1library.pas

(eventually you need to create subdirectory lib\x86_64-win64 by hand)

Reply by email

James Richters
to Jean SUZINEAU:

I’m trying to avoid using Lazarus because the last few times I tried to compile the rest of my project with it, I had all kinds of issues. I can’t remember what all the problems were but it was significant enough for me to stick with the FPC blue screen text mode IDE, and that has been working fine. I’m not sure if it’s because I have a lot of $Mode TP units mixed with FPC units, or if it’s that some of the Lazarus procedures and functions have the same name as other procedures and functions but don’t work the same way… I would have to just try it again to see what was up. I may make another try with Lazarus, but I’m hoping to find a solution that works with just FPC, as I know for a fact the rest of my project has no problems with that.

I tried just replacing libusb-1.0.dll with the one from libusb-1.0.22\MinGW32\dll from https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.7z as suggested, but now I get this:

I:\Programming\FPC\3.0.4\bin\i386-win32\fpc.exe -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -Filib\i386-win32\ -Fu.. -Fu. -FUlib\i386-win32\ -FE. -otest1library.exe test1library.pas

Hint: (11030) Start of reading config file I:\Programming\FPC\3.0.4\bin\i386-win32\fpc.cfg

Hint: (11031) End of reading config file I:\Programming\FPC\3.0.4\bin\i386-win32\fpc.cfg

Free Pascal Compiler version 3.0.4 [2017/10/06] for i386

Copyright (c) 1993-2017 by Florian Klaempfl and others

(1002) Target OS: Win32 for i386

(3104) Compiling test1library.pas

(3104) Compiling I:\Programming\pas-libusb_test_dll\src\libusb.pas

I:\Programming\pas-libusb_test_dll\src\libusb.pas(1315,13) Hint: (4035) Mixing signed expressions and longwords gives a 64bit result
I:\Programming\pas-libusb_test_dll\src\libusb.pas(1333,13) Hint: (4035) Mixing signed expressions and longwords gives a 64bit result

(3104) Compiling I:\Programming\pas-libusb_test_dll\src\libusboop.pas

I:\Programming\pas-libusb_test_dll\src\libusboop.pas(275,5) Warning: (3018) Constructor should be public

(3104) Compiling I:\Programming\pas-libusb_test_dll\src\paslibusbutils.pas

I:\Programming\pas-libusb_test_dll\src\paslibusbutils.pas(45,30) Hint: (4080) Converting the operands to "Int64" before doing the subtract could prevent overflow errors.
I:\Programming\pas-libusb_test_dll\src\paslibusbutils.pas(65,44) Hint: (5057) Local variable "PerfCount" does not seem to be initialized
I:\Programming\pas-libusb_test_dll\src\paslibusbutils.pas(70,45) Hint: (5058) Variable "PerfFreq" does not seem to be initialized
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(545,11) Hint: (4055) Conversion between ordinals and pointers is not portable
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(546,11) Hint: (4055) Conversion between ordinals and pointers is not portable
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(564,72) Hint: (4055) Conversion between ordinals and pointers is not portable
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(852,29) Hint: (5057) Local variable "Status" does not seem to be initialized
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(922,18) Hint: (4055) Conversion between ordinals and pointers is not portable
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(923,18) Hint: (4055) Conversion between ordinals and pointers is not portable
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(937,45) Hint: (4055) Conversion between ordinals and pointers is not portable
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(1046,24) Hint: (4055) Conversion between ordinals and pointers is not portable
I:\Programming\pas-libusb_test_dll\src\libusboop.pas(1059,43) Warning: (4056) Conversion between ordinals and pointers is not portable

(9015) Linking .\test1library.exe

Error: Import library not found for libusb-1.0

Fatal: (10026) There were 1 errors compiling module, stopping

Fatal: (1018) Compilation aborted

Error: I:\Programming\FPC\3.0.4\bin\i386-win32\ppc386.exe returned an error exitcode

Not sure why it can’t find it now, I renamed libusb-1.0.dll and the new one is right under the one I renamed.

James

Earlier message 22 lines
From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Tuesday, August 6, 2019 11:51 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Le 06/08/2019 à 17:18, James Richters a écrit : Any ideas? Is this just from using i386-win32? Maybe the DLL is only for 64bit? Maybe some completely unrelated issue? If 64bit is needed, what’s the best way to install FPC3.0.4 for x86_64-win64? It seems like I tried to do that before and it wasn’t really very easy to try to learn how to compile it. I'm going to have a , it seems there's no package for fpc windows 64 bits. The short answer would be to advise you to download and install lazarus ( https://www.lazarus-ide.org/ ) from https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2064%20bits/Lazarus%202.0.4/lazarus-2.0.4-fpc-3.0.4-win64.exe/download If you install it in C:\lazarus\, you'll end up with a 64 bits fpc in C:\lazarus\fpc\3.0.4\bin\x86_64-win64 . You can run it from command line as usual. You can also try to replace the libusb-1.0.dll with the one from libusb-1.0.22\MinGW32\dll from https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.7z .

Reply by email

Johann Glaser
to Jean SUZINEAU:

Hi!

Jean SUZINEAU wrote 97 lines
Hello I haven't had time yet to read everything but I join below a few more tests. Le 05/08/2019 à 21:38, Johann Glaser a écrit : > > Yay! That looks great! > > > > As a next step you can try test2controlsync.pas > which uses control transfers to query the device > descriptors. > Just change the constants DevVID > and DevPID at the top to > the values of a device connected to your PC. I'd recommend > to > use a device you don't depend on during testing, i.e., > don't use > your primary keyboard and mouse. There shouldn't be a > problem, but better safe than > sorry. And I hope that Windows doesn't cross your plans and > already has allocated that device to a certain driver. > > > > You can also try test3controlasync.pas, > which does a very similar test, just using the asynchronous > interface to libusb (and it is less verbose and estensive). > > > > I tested successfully test2controlsync and test3controlasync on Windows 10 and Ubuntu 19.04 with a Seeeduino lotus (recognized as manufacturer Silicon Labs, Product CP2102N USB to UART Bridge Controller). I've zipped the code in a new "convenience release" at : https://github.com/jsuzineau/pascal_o_r_mapping/releases/tag/pas-libusb_convenience_release_2 This is the output on Windows: E:\03_travail\libusb\pas- libusb_test_dll\src\examples>test2controlsync.exeBus 001 Device 010: ID 10C4:EA60Device Descriptor: bLength 18 bDescriptorType 1 bc dUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVen dor $10C4 idProduct $EA60 bcdDevice 1.00 iManufacturer 1 Silicon Labs iProduct 2 CP2102N USB to UART Bridge Controller iSerialNumber 3 0001 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfig urationValue 1 iConfiguration 0 bmAttributes $80 MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 bInt erfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress $02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize $0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress $82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize $0040 1x 64 bytes bInterval 0 E:\03_travail\libusb\pas- libusb_test_dll\src\examples>test3controlasync.exeSubmitting control transferFinished Transfer, Data = 38, Status = 0, ActualLength = 18Device Descriptor: bLength 18 bDescriptorType 1 bc dUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVen dor $10C4 idProduct $EA60 bcdDevice 1.00 iManufacturer 1 iProduct 2 iSerialN umber 3 bNumConfigurations 1Done. E:\03_travail\libusb\pas-libusb_test_dll\src\examples>

Thats great, it works! Then have fun with all further experiments. If you need help, just ping me.
Bye Hansi

Reply by email

James Richters
to Jean SUZINEAU:
I'm going to have a , it seems there's no package for fpc windows 64 bits.

No there isn’t , which is odd because 64bit computers vastly outnumber 32bit computers… but I guess since 32bit code runs on both if you needed to pick one then 32 would be the one to pick… I do see that the reason some platforms aren't available is that more builders and testers are needed.. this is not the first time I've wanted the full FPC package for Win64, I'd be happy to volunteer to build and test the x86_64-win64 versions.... if someone can teach me how to build it... I've managed to get previous versions of FPC win x86_64-win64 but I remember it wasn't easy for me to build and someone was kind enough to give me a copy that they built.

I gave this a try and…. Success!! I was able to compile it!

If you install it in C:\lazarus\, you'll end up with a 64 bits fpc in C:\lazarus\fpc\3.0.4\bin\x86_64-win64 . You can run it from command line as usual.

Yes the command line works, but the Lazarus copy of FPC 3.0.4 is incomplete, mainly it is missing FP.Exe… The Text IDE, which I actually really like and prefer. It is also missing a lot of other things.. I didn’t investigate fully but there are 81 files in the bin directory of FPC3.0.4 and only 68 in the Lazarus version.

Does anyone know how I can get the full FPC3.0.4 package compiled for X86_64-win64? I can try to figure out how to build it again.. I seem to recall there was some issue with the text IDE and I just ended up going back to i386-Win32 when 3.0.4RC1 came out.

You can also try to replace the libusb-1.0.dll with the one from libusb-1.0.22\MinGW32\dll from https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.7z .

I could not get i386-win32 to work no matter what I did. It would be nice to be able to use 32bit windows, but for my purposes, 64bit would be fine, I’ll have to just figure out how to compile everything else 64bit… I can use the command line of course with what I have, but I really like to have an IDE to take me to the source code of any compiler errors. I may try to compile the rest of my project with Lazarus again and see what the exact problems are… maybe I’m just missing something simple. I think part of the problem is that I have the FPC text IDE already set up with all my options and I don’t know how to put what is needed into Lazarus… and the default settings won’t work. I have a lot of {$mode TP} units mixed with other types of units but I don’t have everything defined in my source, it depends on the compiler settings being the way I have them in the text IDE

Here’s my output from using FPC3.0.4 x86_64-win64 included with Lazarus:

I:\Programming\Lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.exe -MObjFPC -Scghi -O1 -g -gl -l -vewnhibq -Filib\x86_64-win64\ -Fu.. -Fu. -FUlib\x86_64-win64\ -FE. -o.\test1library.exe .\test1library.pas

Hint: (11030) Start of reading config file I:\Programming\Lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.cfg

Hint: (11031) End of reading config file I:\Programming\Lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.cfg

Free Pascal Compiler version 3.0.4 [2019/08/04] for x86_64

Copyright (c) 1993-2017 by Florian Klaempfl and others

(1002) Target OS: Win64 for x64

(3104) Compiling .\test1library.pas

(9015) Linking .\test1library.exe

(1008) 96 lines compiled, 0.2 sec, 166944 bytes code, 6612 bytes data

(1022) 2 hint(s) issued

I:\Programming\pas-libusb_test_dll\src\examples>test1library

Using libusb(x) v1.0.22.11312

Found 21 devices:

Bus 3 Device 0: ID 1B21:2142, port: 0, Speed: Unknown

Bus 1 Device 0: ID 1B21:2142, port: 0, Speed: Unknown

Bus 2 Device 14: ID 1B1C:0C10, port: 3, port path from HCD: 0->3, Speed: 12 Mbit/s (USB FullSpeed)

Bus 2 Device 8: ID 1B1C:0C12, port: 10, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed)

Bus 2 Device 10: ID 0E50:0002, port: 2, port path from HCD: 0->0, Speed: 1.5 Mbit/s (USB LowSpeed)

Bus 2 Device 39: ID 0424:274C, port: 5, port path from HCD: 0->5->5, Speed: 480 Mbit/s (USB HighSpeed)

Bus 2 Device 38: ID 047D:1020, port: 3, port path from HCD: 0->1->1, Speed: 1.5 Mbit/s (USB LowSpeed)

Bus 2 Device 12: ID 0C45:7403, port: 2, port path from HCD: 0->2, Speed: 12 Mbit/s (USB FullSpeed)

Bus 2 Device 6: ID 051D:0002, port: 3, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed)

Bus 2 Device 36: ID 04E8:61F5, port: 1, port path from HCD: 0->128, Speed: unknown (4)

Bus 2 Device 40: ID 1B1C:1B4F, port: 4, port path from HCD: 0->19->19, Speed: 12 Mbit/s (USB FullSpeed)

Bus 2 Device 5: ID 05E3:0608, port: 7, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed)

Bus 2 Device 7: ID 05E3:0608, port: 8, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed)

Bus 2 Device 13: ID 1B1C:1C08, port: 2, port path from HCD: 0->0, Speed: 12 Mbit/s (USB FullSpeed)

Bus 2 Device 1: ID 0BDA:0411, port: 17, port path from HCD: 0, Speed: unknown (4)

Bus 2 Device 4: ID 1A40:0101, port: 5, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed)

Bus 2 Device 0: ID 8086:A2AF, port: 0, Speed: Unknown

Bus 2 Device 37: ID 0424:2734, port: 1, port path from HCD: 0->38, Speed: 480 Mbit/s (USB HighSpeed)

Bus 2 Device 15: ID 05E3:0610, port: 4, port path from HCD: 0->16, Speed: 480 Mbit/s (USB HighSpeed)

Bus 2 Device 41: ID 0A5F:0006, port: 2, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed)

Bus 2 Device 2: ID 0BDA:5411, port: 1, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed)

YAY! I have no idea what this means yet.. but I can see these are the USB devices on my system!

I’m going to figure out how to compile the rest of my project with x86_64-win64 and switch to some IDE that works with that, and then I can continue trying to figure this usb stuff out.

James

Reply by email

James Richters
to Jean SUZINEAU

Is the static linking issue just with Windows, and it works on Linux, or it isn’t working with FPC at all on either?

James

Earlier message 65 lines
From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Thursday, August 8, 2019 5:40 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Static linking : Le 05/08/2019 à 21:38, Johann Glaser a écrit : Referring to your EMail to James, it seems that Vitaly even got it working with static linking. Especially "$LINKLIB msvcrt" and "$LINKLIB usb-1.0.dll.a" look promising. Hmm, OTOH he writes of dynamically linked, I don't know. Could you please also have a look at his comments in that Github issue? For now I couldn't achieve static linking. I couldn't find a reliable way to find the dependencies of libusb-1.0 on other libraries, may be I would have to dig into the makefile and autoconf files of libusb sources, but it seems difficult. I used MSYS2 (https://www.msys2.org/) in which I installed the following packages: pacman -S mingw64/mingw-w64-x86_64-libusb pacman -S mingw-w64-x86_64-headers-git pacman -S mingw-w64-x86_64-crt-git pacman -S mingw-w64-x86_64-gcc In LibUsb.pas I changed the $LINKLIBs to (the errors removed by a particular $LINKLIB are after //Error: ) : {$LINKLIB usb-1.0} {$ifdef windows} {$LINKLIB mingwex} //Error: Undefined symbol: __mingw_vsnprintf, __mingw_vsprintf, __mingw_vsscanf //{$LINKLIB mingw32} //doesn't improve anything {$LINKLIB kernel32} // Error: Undefined symbol: __imp_TlsGetValue, __imp_EnterCriticalSection, __imp_LeaveCriticalSection, ... +41 others {$LINKLIB advapi32} // Error: Undefined symbol: __imp_OpenSCManagerA, __imp_OpenServiceA, __imp_CloseServiceHandle //{$LINKLIB winpthread} //doesn't improve anything //{$LINKLIB stdc++} //doesn't improve anything {$LINKLIB gcc} //Error: Undefined symbol: ___chkstk_ms {$LINKLIB crtdll} //Error: malloc, memcpy, ... + 37 others //{$LINKLIB msvcrt} //same as crtdll, Error: malloc, memcpy, ... + 37 others{$else} {$LINKLIB c} {$endif} Here are the errors of the compilation, it's the minimu I could obtain: Hint: (11030) Start of reading config file C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.cfg Hint: (11031) End of reading config file C:\lazarus\fpc\3.0.4\bin\x86_64-win64\fpc.cfg Free Pascal Compiler version 3.0.4 [2019/02/03] for x86_64 Copyright (c) 1993-2017 by Florian Klaempfl and others (1002) Target OS: Win64 for x64 (3104) Compiling test1library.pas (9015) Linking E:\03_travail\libusb\pas-libusb\src\examples\test1library.exe Error: Multiple defined symbol .refptr.usbi_backend Error: Multiple defined symbol .refptr.usbi_backend Error: Multiple defined symbol .refptr.usbi_default_context Error: Multiple defined symbol .refptr.INVALID_WINFD Error: Multiple defined symbol .refptr.pCancelIoEx Error: Multiple defined symbol .refptr.__tens_D2A Error: Multiple defined symbol .refptr.__hexdig_D2A Error: Undefined symbol: atexit Fatal: (10026) There were 8 errors compiling module, stopping Fatal: (1018) Compilation aborted Error: C:\lazarus\fpc\3.0.4\bin\x86_64-win64\ppcx64.exe returned an error exitcode

Reply by email

Johann Glaser
to Jean SUZINEAU

Hi!

Jean SUZINEAU wrote 9 lines
Le 08/08/2019 à 12:07, James Richters a écrit : > Is the static linking issue just with Windows, and it works on > Linux, or it isn’t working with FPC at all on either? > > James It seems that right out of the box pas-libusb uses static linking for me.

I think you meant to write "dynamic linking" here. :-) When I use the Makefile, it also uses dynamic linking. Actually, I've never tried to do static linking with libusb, because dynamic linking works so flawlessly on Linux.

Bye
Hansi

Reply by email

Jean SUZINEAU
to Johann Glaser

Ooops, sorry. Of course I meant dynamic linking ... Le 08/08/2019 à 23:32, Johann Glaser a écrit :

Show quoted text 10 lines
Am Donnerstag, den 08.08.2019, 13:14 +0200 schrieb Jean SUZINEAU: > It seems that right out of the box pas-libusb uses static linking for > me. I think you meant to write "dynamic linking" here. :-) When I use the Makefile, it also uses dynamic linking. Actually, I've never tried to do static linking with libusb, because dynamic linking works so flawlessly on Linux. Bye Hansi

Reply by email

James Richters
to Jean SUZINEAU

I finally got the text IDE working with x86_64-Win64! I was thinking of making a bug report on the problem with the Text IDE but before I did that I thought I would test the current Trunk, and surprisingly that worked just fine! so I got my settings all put in it and I was able to compile my project with it.

So the next thing I thought I would do is use the IDE to compile the pas-libusb_test_dll examples. With the IDE it was easier to just copy the units into the same directory as the files. I started with test1library.pas... it compiled fine so I ran it, and here's what I got....

Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312
Found 23 devices:
Bus 3 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 1 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 2 Device 14: ID 1B1C:0C10, port: 3, port path from HCD: 0An unhandled exception occurred at $0000000100001DC8: ERangeError: Range check error
$0000000100001DC8 main, line 82 of ../../pas-libusb_test_dll/src/examples/test1library.pas

->

so this was strange... it was working before

line 81            For J := 1 to Length(PortPath)-1 do
line 82              Write('->',PortPath[I]);

Line 82 is using variable I but it's in a loop that uses J, I didn't think that made a lot of sense.. so without really analyzing how any of this was supposed to work.. I just changed the I to a J and then I got this:

->Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312
Found 23 devices:
Bus 3 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 1 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 2 Device 14: ID 1B1C:0C10, port: 3, port path from HCD: 0->7, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 8: ID 1B1C:0C12, port: 10, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 1: ID 1D50:6015, port: 3, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 58: ID 0424:274C, port: 5, port path from HCD: 0->5->1, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 62: ID 10CE:EB93, port: 2, port path from HCD: 0->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 57: ID 047D:1020, port: 3, port path from HCD: 0->5->1, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 2 Device 44: ID 0C45:7403, port: 2, port path from HCD: 0->5, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 6: ID 051D:0002, port: 3, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 36: ID 04E8:61F5, port: 1, port path from HCD: 0->17, Speed: unknown (4) Bus 2 Device 59: ID 1B1C:1B4F, port: 4, port path from HCD: 0->5->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 5: ID 05E3:0608, port: 7, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 7: ID 05E3:0608, port: 8, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 13: ID 1B1C:1C08, port: 2, port path from HCD: 0->7, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 1: ID 0BDA:0411, port: 17, port path from HCD: 0, Speed: unknown (4) Bus 2 Device 42: ID 1A40:0101, port: 5, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 0: ID 8086:A2AF, port: 0, Speed: Unknown Bus 2 Device 56: ID 0424:2734, port: 1, port path from HCD: 0->5, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 15: ID 05E3:0610, port: 4, port path from HCD: 0->7, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 61: ID 0E50:0002, port: 4, port path from HCD: 0, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 2 Device 41: ID 0A5F:0006, port: 2, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 2: ID 0BDA:5411, port: 1, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed)

Looks like it worked fine with line 82 reading:  Write('->',PortPath[J]);
I'm perplexed at how this could have possibly worked before...

So is it supposed to be Write('->',PortPath[J]); and the I was just a typo, or is something else going on here?

Reply by email

James Richters
to James Richters

I changed the VID and PID to match the device I am trying to use and I was able to successfully compile and run test2controlsync.pas and test3controlasync.pas, but when I tried to use my VID and PID in test_arduino_with_bmp280.pas I can't even compile it.. using the x86_64-win64 Text IDE I get the following:

Warning: PIC directive or switch ignored
Hint: End of reading config file I:\Programming\FPC\W64_Trunk\Bin\x86_64-win64\fp.cfg
libusbutil.pas(35,63) Error: Constructor name must be INIT
libusbutil.pas(45,78) Error: Constructor name must be INIT
libusbutil.pas(58,50) Error: Constructor name must be INIT
libusbutil.pas(73,108) Error: Constructor name must be INIT
libusbutil.pas(76,1) Fatal: There were 4 errors compiling module, stopping
libusbutil.pas(0) Fatal: Compilation aborted

Anyone know what this means and how I might fix it?

James

Earlier message 60 lines
-----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Thursday, August 8, 2019 8:20 PM To: ; 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices I finally got the text IDE working with x86_64-Win64! I was thinking of making a bug report on the problem with the Text IDE but before I did that I thought I would test the current Trunk, and surprisingly that worked just fine! so I got my settings all put in it and I was able to compile my project with it. So the next thing I thought I would do is use the IDE to compile the pas-libusb_test_dll examples. With the IDE it was easier to just copy the units into the same directory as the files. I started with test1library.pas... it compiled fine so I ran it, and here's what I got.... Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312 Found 23 devices: Bus 3 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 1 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 2 Device 14: ID 1B1C:0C10, port: 3, port path from HCD: 0An unhandled exception occurred at $0000000100001DC8: ERangeError: Range check error $0000000100001DC8 main, line 82 of ../../pas-libusb_test_dll/src/examples/test1library.pas -> so this was strange... it was working before line 81 For J := 1 to Length(PortPath)-1 do line 82 Write('->',PortPath[I]); Line 82 is using variable I but it's in a loop that uses J, I didn't think that made a lot of sense.. so without really analyzing how any of this was supposed to work.. I just changed the I to a J and then I got this: ->Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312 Found 23 devices: Bus 3 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 1 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 2 Device 14: ID 1B1C:0C10, port: 3, port path from HCD: 0->7, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 8: ID 1B1C:0C12, port: 10, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 1: ID 1D50:6015, port: 3, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 58: ID 0424:274C, port: 5, port path from HCD: 0->5->1, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 62: ID 10CE:EB93, port: 2, port path from HCD: 0->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 57: ID 047D:1020, port: 3, port path from HCD: 0->5->1, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 2 Device 44: ID 0C45:7403, port: 2, port path from HCD: 0->5, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 6: ID 051D:0002, port: 3, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 36: ID 04E8:61F5, port: 1, port path from HCD: 0->17, Speed: unknown (4) Bus 2 Device 59: ID 1B1C:1B4F, port: 4, port path from HCD: 0->5->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 5: ID 05E3:0608, port: 7, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 7: ID 05E3:0608, port: 8, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 13: ID 1B1C:1C08, port: 2, port path from HCD: 0->7, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 1: ID 0BDA:0411, port: 17, port path from HCD: 0, Speed: unknown (4) Bus 2 Device 42: ID 1A40:0101, port: 5, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 0: ID 8086:A2AF, port: 0, Speed: Unknown Bus 2 Device 56: ID 0424:2734, port: 1, port path from HCD: 0->5, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 15: ID 05E3:0610, port: 4, port path from HCD: 0->7, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 61: ID 0E50:0002, port: 4, port path from HCD: 0, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 2 Device 41: ID 0A5F:0006, port: 2, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 2: ID 0BDA:5411, port: 1, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Looks like it worked fine with line 82 reading: Write('->',PortPath[J]); I'm perplexed at how this could have possibly worked before... So is it supposed to be Write('->',PortPath[J]); and the I was just a typo, or is something else going on here?

Reply by email

James Richters
to Jean SUZINEAU:

I am compiling with the Text IDE, and I set it up with the same settings I was using with the 32bit version… and yes I did turn on Range checking, so that explains why we didn’t notice it before.

James

Earlier message 29 lines
From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Friday, August 9, 2019 12:34 AM To: James Richters ; 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices Hi James, Le 09/08/2019 à 02:19, James Richters a écrit : so this was strange... it was working before line 81 For J := 1 to Length(PortPath)-1 do line 82 Write('->',PortPath[I]); Line 82 is using variable I but it's in a loop that uses J, I didn't think that made a lot of sense.. so without really analyzing how any of this was supposed to work.. I just changed the I to a J and then I got this: I think it's a typo. I think we didn't saw it before because Range type checking was disabled ( {$RANGECHECKS OFF} or {$R-} ). It seems it's the default value for the compiler: https://www.freepascal.org/docs-html/prog/progsu65.html . Very often in Windows system functions you have to deal with records with declared with a length of 1 and the real length stored a few bytes before in the record. This could not work with {$R+} But it's seems that for some reason it's enabled for your compiler (may be a different default value when your recompiled with fpcupdeluxe, or more likely a different default value in your settings for fp.exe ?). I'm not an expert in memory allocation, but I think that while a certain amount of memory is allocated after the memory pointed to by PortPath and you're in {$R-} mode, you can happily read several bytes after the actual end of PortPath without any segmentation fault or memory access exception.

Reply by email

James Richters
to James Richters: I changed the VID and PID to match the device I am trying to use and I was able to…

I had "Use STATIC in objects" turned on in compiler setings.. once I turned that off I was able to compile libusbutil.pas successfully.

Now when I try to run it though, I am getting : Couldn't connect to device: Access violation

I don't know why.
I don't really know what I am doing.. but here is what I did so far...

I ran test1library (which also has the line Write('->',PortPath[J]); in it... I changed the J to an I again) I got the list of devices, then I plugged in the one I am trying to access and ran Test1library once again... then I saw the new device in the list, which was this one: Bus 2 Device 62: ID 10CE:EB93, port: 2, port path from HCD: 0->1, Speed: 12 Mbit/s (USB FullSpeed)

So I changed the lines in testcontrolsync.pas as follow:
Const
     WHB04B_VID= $10CE;
     WHB04B_PID= $EB93;
Const DevVID = WHB04B_VID;
      DevPID = WHB04B_PID;

Then I get this output:
Running "i:\programming\pas-libusb_test_dll\src\examples\test2controlsync.exe " Bus 002 Device 062: ID 10CE:EB93
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor $10CE
idProduct $EB93
bcdDevice 1.00
iManufacturer 1 KTURT.LTD
iProduct 0
iSerialNumber 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 27
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes $80
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 3
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Unknown descriptor type $21 with length 9

So that looks promising... I don't know about the unknown descriptor, but at least I have some information that seems reasonable. With the same modifications to test3controlasync.pas I get this:

Running "i:\programming\pas-libusb_test_dll\src\examples\test3controlasync.exe " Submitting control transfer
Finished Transfer, Data = 38, Status = 0, ActualLength = 18 Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor $10CE
idProduct $EB93
bcdDevice 1.00
iManufacturer 1
iProduct 0
iSerialNumber 0
bNumConfigurations 1
Done.

So I again put my device VID and PID into test_arduino_with_bmp280.pas and got this:

Running "i:\programming\pas-libusb_test_dll\src\examples\test_arduino_with_bmp280.exe " No unconfigured devices found.
Couldn't connect to device: No configured devices found.

I suspect it has something to do with the firmware.ihx file mentioned in the comments, but I do not understand how to get that file. It says to compile EZ-USB, but I don't know what to do with it.. When I say I compiled it, I am referring to EZUSB.PAS that is included in pas-libusb... but that is just a unit, and I don't know how I could use that to create this firmware.ihx file.

What is the correct procedure to obtain firmware.ihx? Is there something else I need besides the EZUSB unit that would use that unit to create this file?

James

Earlier message 82 lines
-----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Thursday, August 8, 2019 9:37 PM To: 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices I changed the VID and PID to match the device I am trying to use and I was able to successfully compile and run test2controlsync.pas and test3controlasync.pas, but when I tried to use my VID and PID in test_arduino_with_bmp280.pas I can't even compile it.. using the x86_64-win64 Text IDE I get the following: Warning: PIC directive or switch ignored Hint: End of reading config file I:\Programming\FPC\W64_Trunk\Bin\x86_64-win64\fp.cfg libusbutil.pas(35,63) Error: Constructor name must be INIT libusbutil.pas(45,78) Error: Constructor name must be INIT libusbutil.pas(58,50) Error: Constructor name must be INIT libusbutil.pas(73,108) Error: Constructor name must be INIT libusbutil.pas(76,1) Fatal: There were 4 errors compiling module, stopping libusbutil.pas(0) Fatal: Compilation aborted Anyone know what this means and how I might fix it? James -----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Thursday, August 8, 2019 8:20 PM To: ; 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices I finally got the text IDE working with x86_64-Win64! I was thinking of making a bug report on the problem with the Text IDE but before I did that I thought I would test the current Trunk, and surprisingly that worked just fine! so I got my settings all put in it and I was able to compile my project with it. So the next thing I thought I would do is use the IDE to compile the pas-libusb_test_dll examples. With the IDE it was easier to just copy the units into the same directory as the files. I started with test1library.pas... it compiled fine so I ran it, and here's what I got.... Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312 Found 23 devices: Bus 3 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 1 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 2 Device 14: ID 1B1C:0C10, port: 3, port path from HCD: 0An unhandled exception occurred at $0000000100001DC8: ERangeError: Range check error $0000000100001DC8 main, line 82 of ../../pas-libusb_test_dll/src/examples/test1library.pas -> so this was strange... it was working before line 81 For J := 1 to Length(PortPath)-1 do line 82 Write('->',PortPath[I]); Line 82 is using variable I but it's in a loop that uses J, I didn't think that made a lot of sense.. so without really analyzing how any of this was supposed to work.. I just changed the I to a J and then I got this: ->Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312 Found 23 devices: Bus 3 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 1 Device 0: ID 1B21:2142, port: 0, Speed: Unknown Bus 2 Device 14: ID 1B1C:0C10, port: 3, port path from HCD: 0->7, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 8: ID 1B1C:0C12, port: 10, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 1: ID 1D50:6015, port: 3, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 58: ID 0424:274C, port: 5, port path from HCD: 0->5->1, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 62: ID 10CE:EB93, port: 2, port path from HCD: 0->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 57: ID 047D:1020, port: 3, port path from HCD: 0->5->1, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 2 Device 44: ID 0C45:7403, port: 2, port path from HCD: 0->5, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 6: ID 051D:0002, port: 3, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 36: ID 04E8:61F5, port: 1, port path from HCD: 0->17, Speed: unknown (4) Bus 2 Device 59: ID 1B1C:1B4F, port: 4, port path from HCD: 0->5->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 5: ID 05E3:0608, port: 7, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 7: ID 05E3:0608, port: 8, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 13: ID 1B1C:1C08, port: 2, port path from HCD: 0->7, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 1: ID 0BDA:0411, port: 17, port path from HCD: 0, Speed: unknown (4) Bus 2 Device 42: ID 1A40:0101, port: 5, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 0: ID 8086:A2AF, port: 0, Speed: Unknown Bus 2 Device 56: ID 0424:2734, port: 1, port path from HCD: 0->5, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 15: ID 05E3:0610, port: 4, port path from HCD: 0->7, Speed: 480 Mbit/s (USB HighSpeed) Bus 2 Device 61: ID 0E50:0002, port: 4, port path from HCD: 0, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 2 Device 41: ID 0A5F:0006, port: 2, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 2 Device 2: ID 0BDA:5411, port: 1, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Looks like it worked fine with line 82 reading: Write('->',PortPath[J]); I'm perplexed at how this could have possibly worked before... So is it supposed to be Write('->',PortPath[J]); and the I was just a typo, or is something else going on here?

Reply by email

James Richters
to James Richters

Maybe I am going down the wrong path trying to get test_arduino_with_bmp280.pas to work with my device... I think I am confusing easyusb with easyhid which is what is used to communicate with the device in the python code I am trying to use. It looks like easyusb is to send firmware to a specific usb device that has no rom in it... and that's not exactly what I'm trying to do...

I'm trying to figure out how to open the device and read data and write data to this device. Is there an example of how to do that with pas-libusb?

Sorry I am so confused by all this. I feel like I'm almost to where I will understand things again but I'm just missing something.

James

Reply by email

Johann Glaser
to James Richters

Hi!

Just a quick reply while at work, I'll reply to all EMails in the evening.

First of all: Thanks for finding the bug with the index variable I vs. J. I'll fix that in the evening.

Secondly: You are correct, the "EZ-USB" is a specific chip family by Cypress, e.g., AN2131, without Flash/ROM but with SRAM for the firmware. I built a few devices with that chip, therefore I also implemented the Pascal "driver" to download the firmware into the "naked" device. There are also many (old) devices on the marked which use that chip, e.g., the Keil uLink (1st generation).

To understand how USB actually works (endpoints, in and out transfers, control/bulk/interrupt/isochronous transfers, ...), I have learned a lot from the Technical Reference Manual (TRM) of the EZ-USB. Just search for it, there are plenty of sources. Chapter 1 is the interesting one. If you directly search at the Cypress page, they will redirect you to the successor product FX2, but its chapter 1 is nearly identical to that of EZ-USB.

The EZ-USB firmware download is performed with control transfers to EP0. So you can find examples for control transfers in ezusb.pas.

You can find example code for bulk and interrupt endpoints e.g., in https://github.com/hansiglaser/pas-gpib/blob/master/usb/usbtmc.pas.

I can provide more examples in the evening.

Bye
Hansi

Show quoted text 16 lines
Gesendet: Freitag, 09. August 2019 um 12:09 Uhr Von: "James Richters" An: "'FPC-Pascal users discussions'" Betreff: Re: [fpc-pascal] USB Human Interface Devices Maybe I am going down the wrong path trying to get test_arduino_with_bmp280.pas to work with my device... I think I am confusing easyusb with easyhid which is what is used to communicate with the device in the python code I am trying to use. It looks like easyusb is to send firmware to a specific usb device that has no rom in it... and that's not exactly what I'm trying to do... I'm trying to figure out how to open the device and read data and write data to this device. Is there an example of how to do that with pas-libusb? Sorry I am so confused by all this. I feel like I'm almost to where I will understand things again but I'm just missing something. James _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser

Hi Hansi,
Thanks for the explanation.

Here's the python code I’m trying to port over to FPC: https://github.com/wolfmanjm/kivy-smoothie-host/blob/master/modules/hb04.py

it uses functions like hid.open, hid.close, hid.read, hid.write, and hid.send_feature_report I'm trying to figure out how to somehow get similar functions to those in FPC. Some example of how to perform those kinds of functions would be extremely helpful!

Thank you for your help with this

James

Earlier message 41 lines
-----Original Message----- From: fpc-pascal On Behalf Of Johann Glaser Sent: Friday, August 9, 2019 7:17 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi! Just a quick reply while at work, I'll reply to all EMails in the evening. First of all: Thanks for finding the bug with the index variable I vs. J. I'll fix that in the evening. Secondly: You are correct, the "EZ-USB" is a specific chip family by Cypress, e.g., AN2131, without Flash/ROM but with SRAM for the firmware. I built a few devices with that chip, therefore I also implemented the Pascal "driver" to download the firmware into the "naked" device. There are also many (old) devices on the marked which use that chip, e.g., the Keil uLink (1st generation). To understand how USB actually works (endpoints, in and out transfers, control/bulk/interrupt/isochronous transfers, ...), I have learned a lot from the Technical Reference Manual (TRM) of the EZ-USB. Just search for it, there are plenty of sources. Chapter 1 is the interesting one. If you directly search at the Cypress page, they will redirect you to the successor product FX2, but its chapter 1 is nearly identical to that of EZ-USB. The EZ-USB firmware download is performed with control transfers to EP0. So you can find examples for control transfers in ezusb.pas. You can find example code for bulk and interrupt endpoints e.g., in https://github.com/hansiglaser/pas-gpib/blob/master/usb/usbtmc.pas. I can provide more examples in the evening. Bye Hansi > Gesendet: Freitag, 09. August 2019 um 12:09 Uhr > Von: "James Richters" > An: "'FPC-Pascal users discussions'" > Betreff: Re: [fpc-pascal] USB Human Interface Devices > > Maybe I am going down the wrong path trying to get test_arduino_with_bmp280.pas to work with my device... I think I am confusing easyusb with easyhid which is what is used to communicate with the device in the python code I am trying to use. It looks like easyusb is to send firmware to a specific usb device that has no rom in it... and that's not exactly what I'm trying to do... > > I'm trying to figure out how to open the device and read data and write data to this device. Is there an example of how to do that with pas-libusb? > > Sorry I am so confused by all this. I feel like I'm almost to where I will understand things again but I'm just missing something. > > James > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal >

Reply by email

Johann Glaser
to James Richters

Hi!

James Richters wrote 10 lines
Hi Hansi, Thanks for the explanation. Here's the python code I’m trying to port over to FPC: https://github.com/wolfmanjm/kivy-smoothie-host/blob/master/modules/hb04.py it uses functions like hid.open, hid.close, hid.read, hid.write, and hid.send_feature_report I'm trying to figure out how to somehow get similar functions to those in FPC. Some example of how to perform those kinds of functions would be extremely helpful!

These hid.open, hid.close, ... functions are all methods of the object "hid", which was previously assigned to from devices[0] (line 68), which itself was returned from en.find(), where en is an object of Enumeration() from the package easyhid.

To communicate with USB HID devices, please peek into the outdated branch “master” of pas-libust (for legacy libusb-0.1) and open file src/usb.pas. This is the old analogous to the new libusboop.pas.

It has the class TUSBPseudoHIDInterface which implements basic communication with USB HID devices.

I've used that for a project with a barcode scanner. Please find attached the two files snapi.pas (implementing the "standard" SNAPI for barcode scanners, which is based on USB HID), and
barcodescannersymbolms4407.pas (implementing a few more specific methods for a Symbol MS4407 barcode scanner). The latter file uses several units of my project, therefore it will not compile on your host. It is just to see how to use the SNAPI devices. I release these files with the same license as libusboop.pas.

Please excuse that these files are still based on the outdated pas- libusb for the old libusb-0.1. Therefore they would need translation for the newer libusb-1.0 stuff. Unfortunately I've never head time to transition the project. Actually you could copy the class TUSBPseudoHIDInterface (plus the types THIDReport and TIntrReportFunc) from usb.pas to libusboop.pas and change everything necessary.

At least one difference is that all names change from TUSB* to TLibUsb*. I'm sure there are more, but I don't know by heart.

Please also excuse that I can’t recall why its just “PseudoHID” and not a fully-fledged HID. Probably I didn’t implement all HID functions, or the SNAPI HID interface just isn't registered with descriptor type $21.

This brings me to the second topic, where you got the message Unknown descriptor type $21 with length 9
from test2controlsync. That's a HID descriptor (see LIBUSB_DT_HID). It is just not decoded in test2controlsync.

And finally, the third point regarding the bug with PortPath index. I've fixed that now and pushed to Github. Thanks for pointing this out!

Thanks
Hansi

Show quoted text 74 lines
-----Original Message----- From: fpc-pascal On Behalf Of Johann Glaser Sent: Friday, August 9, 2019 7:17 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi! Just a quick reply while at work, I'll reply to all EMails in the evening. First of all: Thanks for finding the bug with the index variable I vs. J. I'll fix that in the evening. Secondly: You are correct, the "EZ-USB" is a specific chip family by Cypress, e.g., AN2131, without Flash/ROM but with SRAM for the firmware. I built a few devices with that chip, therefore I also implemented the Pascal "driver" to download the firmware into the "naked" device. There are also many (old) devices on the marked which use that chip, e.g., the Keil uLink (1st generation). To understand how USB actually works (endpoints, in and out transfers, control/bulk/interrupt/isochronous transfers, ...), I have learned a lot from the Technical Reference Manual (TRM) of the EZ- USB. Just search for it, there are plenty of sources. Chapter 1 is the interesting one. If you directly search at the Cypress page, they will redirect you to the successor product FX2, but its chapter 1 is nearly identical to that of EZ-USB. The EZ-USB firmware download is performed with control transfers to EP0. So you can find examples for control transfers in ezusb.pas. You can find example code for bulk and interrupt endpoints e.g., in https://github.com/hansiglaser/pas-gpib/blob/master/usb/usbtmc.pas. I can provide more examples in the evening. Bye Hansi > Gesendet: Freitag, 09. August 2019 um 12:09 Uhr > Von: "James Richters" > An: "'FPC-Pascal users discussions'" < > > > Betreff: Re: [fpc-pascal] USB Human Interface Devices > > Maybe I am going down the wrong path trying to get > test_arduino_with_bmp280.pas to work with my device... I think I > am confusing easyusb with easyhid which is what is used to > communicate with the device in the python code I am trying to > use. It looks like easyusb is to send firmware to a specific usb > device that has no rom in it... and that's not exactly what I'm > trying to do... > > I'm trying to figure out how to open the device and read data and > write data to this device. Is there an example of how to do that > with pas-libusb? > > Sorry I am so confused by all this. I feel like I'm almost to > where I will understand things again but I'm just missing > something. > > James > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser

Hi Hansi,

Thanks for the sample programs and information. I'm going to try to do as you suggest and try to translate to the new libusb-1.0.. I'm not sure I'll understand it enough but it seems like it's heading in the right directions so would be worth a try.

James

Earlier message 117 lines
-----Original Message----- From: fpc-pascal On Behalf Of Johann Glaser Sent: Friday, August 9, 2019 7:33 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi! Am Freitag, den 09.08.2019, 08:08 -0400 schrieb James Richters: > Hi Hansi, > Thanks for the explanation. > > Here's the python code I’m trying to port over to FPC: > https://github.com/wolfmanjm/kivy-smoothie-host/blob/master/modules/hb > 04.py > > it uses functions like hid.open, hid.close, hid.read, hid.write, and > hid.send_feature_report I'm trying to figure out how to somehow get > similar functions to those in FPC. Some example of how to perform > those kinds of functions would be extremely helpful! These hid.open, hid.close, ... functions are all methods of the object "hid", which was previously assigned to from devices[0] (line 68), which itself was returned from en.find(), where en is an object of Enumeration() from the package easyhid. To communicate with USB HID devices, please peek into the outdated branch “master” of pas-libust (for legacy libusb-0.1) and open file src/usb.pas. This is the old analogous to the new libusboop.pas. It has the class TUSBPseudoHIDInterface which implements basic communication with USB HID devices. I've used that for a project with a barcode scanner. Please find attached the two files snapi.pas (implementing the "standard" SNAPI for barcode scanners, which is based on USB HID), and barcodescannersymbolms4407.pas (implementing a few more specific methods for a Symbol MS4407 barcode scanner). The latter file uses several units of my project, therefore it will not compile on your host. It is just to see how to use the SNAPI devices. I release these files with the same license as libusboop.pas. Please excuse that these files are still based on the outdated pas- libusb for the old libusb-0.1. Therefore they would need translation for the newer libusb-1.0 stuff. Unfortunately I've never head time to transition the project. Actually you could copy the class TUSBPseudoHIDInterface (plus the types THIDReport and TIntrReportFunc) from usb.pas to libusboop.pas and change everything necessary. At least one difference is that all names change from TUSB* to TLibUsb*. I'm sure there are more, but I don't know by heart. Please also excuse that I can’t recall why its just “PseudoHID” and not a fully-fledged HID. Probably I didn’t implement all HID functions, or the SNAPI HID interface just isn't registered with descriptor type $21. This brings me to the second topic, where you got the message Unknown descriptor type $21 with length 9 from test2controlsync. That's a HID descriptor (see LIBUSB_DT_HID). It is just not decoded in test2controlsync. And finally, the third point regarding the bug with PortPath index. I've fixed that now and pushed to Github. Thanks for pointing this out! Thanks Hansi > -----Original Message----- > From: fpc-pascal On Behalf > Of Johann Glaser > Sent: Friday, August 9, 2019 7:17 AM > To: > Subject: Re: [fpc-pascal] USB Human Interface Devices > > Hi! > > Just a quick reply while at work, I'll reply to all EMails in the > evening. > > First of all: Thanks for finding the bug with the index variable I vs. > J. I'll fix that in the evening. > > Secondly: You are correct, the "EZ-USB" is a specific chip family by > Cypress, e.g., AN2131, without Flash/ROM but with SRAM for the > firmware. I built a few devices with that chip, therefore I also > implemented the Pascal "driver" to download the firmware into the > "naked" device. There are also many (old) devices on the marked which > use that chip, e.g., the Keil uLink (1st generation). > > To understand how USB actually works (endpoints, in and out transfers, > control/bulk/interrupt/isochronous transfers, ...), I have learned a > lot from the Technical Reference Manual (TRM) of the EZ- USB. Just > search for it, there are plenty of sources. Chapter 1 is the > interesting one. If you directly search at the Cypress page, they will > redirect you to the successor product FX2, but its chapter 1 is nearly > identical to that of EZ-USB. > > The EZ-USB firmware download is performed with control transfers to > EP0. So you can find examples for control transfers in ezusb.pas. > > You can find example code for bulk and interrupt endpoints e.g., in > https://github.com/hansiglaser/pas-gpib/blob/master/usb/usbtmc.pas. > > I can provide more examples in the evening. > > Bye > Hansi > > > Gesendet: Freitag, 09. August 2019 um 12:09 Uhr > > Von: "James Richters" > > An: "'FPC-Pascal users discussions'" < > > > > > Betreff: Re: [fpc-pascal] USB Human Interface Devices > > > > Maybe I am going down the wrong path trying to get > > test_arduino_with_bmp280.pas to work with my device... I think I am > > confusing easyusb with easyhid which is what is used to communicate > > with the device in the python code I am trying to use. It looks > > like easyusb is to send firmware to a specific usb device that has > > no rom in it... and that's not exactly what I'm trying to do... > > > > I'm trying to figure out how to open the device and read data and > > write data to this device. Is there an example of how to do that > > with pas-libusb? > > > > Sorry I am so confused by all this. I feel like I'm almost to where > > I will understand things again but I'm just missing something. > > > > James > > _______________________________________________ > > fpc-pascal maillist - > > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > > > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser: Hi! These hid.open, hid.close, ... functions are all methods of the object "hid", which…

I'm making an attempt to copy TUSBPseudoHIDInterface into libusboop.pas. I've made the recomended name changes and then tried to compile it. Some things I found like the names changing from things like

PUSBInterfaceDescriptop to Plibusb_interface_descriptor

are pretty obvious, but just taking a guess on other things like:

changing:
if (EP.bmAttributes and USB_ENDPOINT_TYPE_MASK = USB_ENDPOINT_TYPE_INTERRUPT) and (EP.bEndpointAddress and USB_ENDPOINT_DIR_MASK 0) then

To:
if (EP^.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = LIBUSB_TRANSFER_TYPE_INTERRUPT) and (EP^.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) then

Based on looking at something similar in libusbutil... but I'm not sure it's right at all.... I'm not sure if USB_ENDPOINT_TYPE_MASK was really changed to LIBUSB_TRANSFER_TYPE_MASK or if something else happened. But at least it compiles... but now I've hit a few items that I just don't know what to do with. I can't find anything similar to get a reference from:

libusboop.pas(1198,28) Error: Identifier not found "USB_TYPE_CLASS"
libusboop.pas(1199,5) Error: Identifier not found "USB_REQ_HID_SET_REPORT"
libusboop.pas(1216,27) Error: Identifier not found "USB_TYPE_CLASS"
libusboop.pas(1217,5) Error: Identifier not found "USB_REQ_HID_GET_REPORT"
libusboop.pas(1227,23) Error: Identifier not found "HID_REPORT_TYPE_OUTPUT"

I've tried things that seem to be in line with other changes, like changing USB_Type_Class to LIBUSB_TYPE_CLASS or spelling out REQUEST instead of REQ which also seems to be done in other places, but still the identifiers are not found... the problem is I have no idea where these identifiers were/are defined.

I made a fork in github and a branch called "test" here: https://github.com/Zaaphod/pas-libusb/tree/Test

Any advice is greatly appreciated

James

Actually you could copy the class TUSBPseudoHIDInterface (plus the types THIDReport and TIntrReportFunc) from usb.pas to libusboop.pas and change everything necessary. At least one difference is that all names change from TUSB* to TLibUsb*. I'm sure there are more, but I don't know by heart.

Reply by email

Johann Glaser
to James Richters

Hi!

James Richters wrote 6 lines
I'm making an attempt to copy TUSBPseudoHIDInterface into libusboop.pas. I've made the recomended name changes and then tried to compile it. Some things I found like the names changing from things like PUSBInterfaceDescriptop to Plibusb_interface_descriptor

OK, there are two things. Names directly from libusb-1.0 (as used in libusb.pas) should be identical to the original C code, i.e., Plibusb_interface_descriptor as you've written.

The second thing are the classes in the OOP wrapper in libusboop.pas. Please use CamelCase for them, e.g., TLibusbPseudoHIDInterface.

Show quoted text 12 lines
are pretty obvious, but just taking a guess on other things like: changing: if (EP.bmAttributes and USB_ENDPOINT_TYPE_MASK = USB_ENDPOINT_TYPE_INTERRUPT) and (EP.bEndpointAddress and USB_ENDPOINT_DIR_MASK 0) then To: if (EP^.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = LIBUSB_TRANSFER_TYPE_INTERRUPT) and (EP^.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) then

Yes, very good, thanks!

Whether EP is a pointer (--> EP^.bmAttributes) or a record (EP.bmAttributs) just depends on the usage in the code. As I see in usb.pas in line 846, in TUSBPseudoHIDInterface.Create, it is actually the record, so you should stay without the '^'.

Based on looking at something similar in libusbutil... but I'm not sure it's right at all.... I'm not sure if USB_ENDPOINT_TYPE_MASK was really changed to LIBUSB_TRANSFER_TYPE_MASK or if something else happened. But at least it compiles...

You translated it correctly.

but now I've hit a few items that I just don't know what to do with. I can't find anything similar to get a reference from: libusboop.pas(1198,28) Error: Identifier not found "USB_TYPE_CLASS"

Use LIBUSB_REQUEST_TYPE_CLASS.

Show quoted text 7 lines
libusboop.pas(1199,5) Error: Identifier not found "USB_REQ_HID_SET_REPORT" libusboop.pas(1216,27) Error: Identifier not found "USB_TYPE_CLASS" libusboop.pas(1217,5) Error: Identifier not found "USB_REQ_HID_GET_REPORT" libusboop.pas(1227,23) Error: Identifier not found "HID_REPORT_TYPE_OUTPUT"

Please copy the constants USB_REQ_HID_* and HID_REPORT_* from libusb.pas (branch master) lines 248-257 to the interface section of libusboop.pas (branch libusb-1.0) directly above the class declaration of TLibusbPseudoHIDInterface. Then please rename USB_REQ_HID_* to LIBUSB_REQUEST_HID_* and HID_REPORT_* to LIBUSB_HID_REPORT_*.

Show quoted text 8 lines
I've tried things that seem to be in line with other changes, like changing USB_Type_Class to LIBUSB_TYPE_CLASS or spelling out REQUEST instead of REQ which also seems to be done in other places, but still the identifiers are not found... the problem is I have no idea where these identifiers were/are defined. I made a fork in github and a branch called "test" here: https://github.com/Zaaphod/pas-libusb/tree/Test

Great approach, thanks, then we can use pull requests.

Thanks
Hansi

Show quoted text 9 lines
> Actually you could copy the class TUSBPseudoHIDInterface (plus the > types THIDReport and TIntrReportFunc) from usb.pas to libusboop.pas > and change everything necessary. > At least one difference is that all names change from TUSB* to > TLibUsb*. I'm sure there are more, but I don't know by heart. _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser

Thank you for the help. I made most of the changes you recommend and I was able to get it to compile, the only one I had trouble with was If I take out the ^ from:
if (EP^.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = LIBUSB_TRANSFER_TYPE_INTERRUPT) and
(EP^.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) then

So it looks like this:
if (EP.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = LIBUSB_TRANSFER_TYPE_INTERRUPT) and
(EP.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) then

I get a compiler error:
libusboop.pas(1168,14) Error: Illegal qualifier
libusboop.pas(1168,14) Fatal: Syntax error, ")" expected but "identifier BMATTRIBUTES" found
libusboop.pas(0) Fatal: Compilation aborted

With the ^ in it compiles anyway... I don't know how to adjust the format to not have the ^

I have not tried to do anything with TLibUsbPseudoHIDInterface yet, I was just trying to get libusboop.pas to compile, and be able to still run the previous examples.

I've updated my repository at https://github.com/Zaaphod/pas-libusb/tree/Test

Let me know if I should do something different with the ^ above, or if you see anything else I missed.

James

Earlier message 88 lines
-----Original Message----- From: fpc-pascal On Behalf Of Johann Glaser Sent: Sunday, August 11, 2019 4:16 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi! Am Samstag, den 10.08.2019, 17:50 -0400 schrieb James Richters: > I'm making an attempt to copy TUSBPseudoHIDInterface into > libusboop.pas. I've made the recomended name changes and then tried > to compile it. Some things I found like the names changing from > things like > > PUSBInterfaceDescriptop to Plibusb_interface_descriptor OK, there are two things. Names directly from libusb-1.0 (as used in libusb.pas) should be identical to the original C code, i.e., Plibusb_interface_descriptor as you've written. The second thing are the classes in the OOP wrapper in libusboop.pas. Please use CamelCase for them, e.g., TLibusbPseudoHIDInterface. > are pretty obvious, but just taking a guess on other things like: > > changing: > if (EP.bmAttributes and USB_ENDPOINT_TYPE_MASK = > USB_ENDPOINT_TYPE_INTERRUPT) and > (EP.bEndpointAddress and USB_ENDPOINT_DIR_MASK 0) then > > To: > if (EP^.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = > LIBUSB_TRANSFER_TYPE_INTERRUPT) and > (EP^.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) then Yes, very good, thanks! Whether EP is a pointer (--> EP^.bmAttributes) or a record (EP.bmAttributs) just depends on the usage in the code. As I see in usb.pas in line 846, in TUSBPseudoHIDInterface.Create, it is actually the record, so you should stay without the '^'. > Based on looking at something similar in libusbutil... but I'm not > sure it's right at all.... I'm not sure if USB_ENDPOINT_TYPE_MASK was > really changed to LIBUSB_TRANSFER_TYPE_MASK or if something else > happened. But at least it compiles... You translated it correctly. > but now I've hit a few items that I just don't know what to do > with. I can't find anything similar to get a reference from: > > libusboop.pas(1198,28) Error: Identifier not found "USB_TYPE_CLASS" Use LIBUSB_REQUEST_TYPE_CLASS. > libusboop.pas(1199,5) Error: Identifier not found > "USB_REQ_HID_SET_REPORT" > libusboop.pas(1216,27) Error: Identifier not found "USB_TYPE_CLASS" > libusboop.pas(1217,5) Error: Identifier not found > "USB_REQ_HID_GET_REPORT" > libusboop.pas(1227,23) Error: Identifier not found > "HID_REPORT_TYPE_OUTPUT" Please copy the constants USB_REQ_HID_* and HID_REPORT_* from libusb.pas (branch master) lines 248-257 to the interface section of libusboop.pas (branch libusb-1.0) directly above the class declaration of TLibusbPseudoHIDInterface. Then please rename USB_REQ_HID_* to LIBUSB_REQUEST_HID_* and HID_REPORT_* to LIBUSB_HID_REPORT_*. > I've tried things that seem to be in line with other changes, like > changing USB_Type_Class to LIBUSB_TYPE_CLASS or spelling out REQUEST > instead of REQ which also seems to be done in other places, but still > the identifiers are not found... the problem is I have no idea where > these identifiers were/are defined. > > I made a fork in github and a branch called "test" here: > https://github.com/Zaaphod/pas-libusb/tree/Test Great approach, thanks, then we can use pull requests. Thanks Hansi > > Actually you could copy the class TUSBPseudoHIDInterface (plus the > > types THIDReport and TIntrReportFunc) from usb.pas to libusboop.pas > > and change everything necessary. > > At least one difference is that all names change from TUSB* to > > TLibUsb*. I'm sure there are more, but I don't know by heart. > > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Johann Glaser
to James Richters

Hi!

James Richters wrote 32 lines
Thank you for the help. I made most of the changes you recommend and I was able to get it to compile, the only one I had trouble with was If I take out the ^ from: if (EP^.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = LIBUSB_TRANSFER_TYPE_INTERRUPT) and (EP^.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) then So it looks like this: if (EP.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = LIBUSB_TRANSFER_TYPE_INTERRUPT) and (EP.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) then I get a compiler error: libusboop.pas(1168,14) Error: Illegal qualifier libusboop.pas(1168,14) Fatal: Syntax error, ")" expected but "identifier BMATTRIBUTES" found libusboop.pas(0) Fatal: Compilation aborted With the ^ in it compiles anyway... I don't know how to adjust the format to not have the ^ I have not tried to do anything with TLibUsbPseudoHIDInterface yet, I was just trying to get libusboop.pas to compile, and be able to still run the previous examples. I've updated my repository at https://github.com/Zaaphod/pas-libusb/tree/Test Let me know if I should do something different with the ^ above, or if you see anything else I missed.

Ah, I see. You declared EP as Plibusb_endpoint_descriptor (i.e., the pointer to an endpoint descriptor record), while in the original code it is a USBEndpointDescriptor (i.e., the record itself).

Your version is more memory efficient but uses "ugly pointer- arithmetic" by taking the address of an array element. However, just keep it as you implemented it.

While reviewing your changes, I found a few small things.

Could you please keep the indenting and coding style as the existing code? This is especially for the constant and type declarations around TLibUsbPseudoHIDInterface (IIRC the keywords Type and Const should start at character 1, therefore you also should un-indent the 6+3 constants and the P/THIDReport record (except its final "End;" by 2 spaces.

Secondly, in your improved TLibUsbInterface.FindEndpoint, please revert the capitalization and indenting changes (i.e., capital "Function", "For", ..., and "do" and "then" in the same line, ... IMHO the only changed lines in comparison to the original code should be the extra variable EP, its assignment without range checks, and its use in MatchFunc and Exit.

And thirdly, you introduced a class type TLibUsbInterruptInEndpoint, which is IMHO unused. If its so, please remove it. I like to avoid clutter. :-)

Apart form these cosmetic things, thank you very much for your effort! I'm looking forward hearing from you your success when accessing a HID device (or call for help :-) ).

Thanks
Hansi

Show quoted text 110 lines
-----Original Message----- From: fpc-pascal On Behalf Of Johann Glaser Sent: Sunday, August 11, 2019 4:16 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi! Am Samstag, den 10.08.2019, 17:50 -0400 schrieb James Richters: > I'm making an attempt to copy TUSBPseudoHIDInterface into > libusboop.pas. I've made the recomended name changes and then > tried > to compile it. Some things I found like the names changing from > things like > > PUSBInterfaceDescriptop to Plibusb_interface_descriptor OK, there are two things. Names directly from libusb-1.0 (as used in libusb.pas) should be identical to the original C code, i.e., Plibusb_interface_descriptor as you've written. The second thing are the classes in the OOP wrapper in libusboop.pas. Please use CamelCase for them, e.g., TLibusbPseudoHIDInterface. > are pretty obvious, but just taking a guess on other things like: > > changing: > if (EP.bmAttributes and USB_ENDPOINT_TYPE_MASK = > USB_ENDPOINT_TYPE_INTERRUPT) and > (EP.bEndpointAddress and USB_ENDPOINT_DIR_MASK 0) then > > To: > if (EP^.bmAttributes and LIBUSB_TRANSFER_TYPE_MASK = > LIBUSB_TRANSFER_TYPE_INTERRUPT) and > (EP^.bEndpointAddress and LIBUSB_ENDPOINT_DIR_MASK 0) > then Yes, very good, thanks! Whether EP is a pointer (--> EP^.bmAttributes) or a record (EP.bmAttributs) just depends on the usage in the code. As I see in usb.pas in line 846, in TUSBPseudoHIDInterface.Create, it is actually the record, so you should stay without the '^'. > Based on looking at something similar in libusbutil... but I'm not > sure it's right at all.... I'm not sure if USB_ENDPOINT_TYPE_MASK > was > really changed to LIBUSB_TRANSFER_TYPE_MASK or if something else > happened. But at least it compiles... You translated it correctly. > but now I've hit a few items that I just don't know what to do > with. I can't find anything similar to get a reference from: > > libusboop.pas(1198,28) Error: Identifier not found "USB_TYPE_CLASS" Use LIBUSB_REQUEST_TYPE_CLASS. > libusboop.pas(1199,5) Error: Identifier not found > "USB_REQ_HID_SET_REPORT" > libusboop.pas(1216,27) Error: Identifier not found "USB_TYPE_CLASS" > libusboop.pas(1217,5) Error: Identifier not found > "USB_REQ_HID_GET_REPORT" > libusboop.pas(1227,23) Error: Identifier not found > "HID_REPORT_TYPE_OUTPUT" Please copy the constants USB_REQ_HID_* and HID_REPORT_* from libusb.pas (branch master) lines 248-257 to the interface section of libusboop.pas (branch libusb-1.0) directly above the class declaration of TLibusbPseudoHIDInterface. Then please rename USB_REQ_HID_* to LIBUSB_REQUEST_HID_* and HID_REPORT_* to LIBUSB_HID_REPORT_*. > I've tried things that seem to be in line with other changes, like > changing USB_Type_Class to LIBUSB_TYPE_CLASS or spelling out > REQUEST > instead of REQ which also seems to be done in other places, but > still > the identifiers are not found... the problem is I have no idea > where > these identifiers were/are defined. > > I made a fork in github and a branch called "test" here: > https://github.com/Zaaphod/pas-libusb/tree/Test Great approach, thanks, then we can use pull requests. Thanks Hansi > > Actually you could copy the class TUSBPseudoHIDInterface (plus > > the > > types THIDReport and TIntrReportFunc) from usb.pas to > > libusboop.pas > > and change everything necessary. > > At least one difference is that all names change from TUSB* to > > TLibUsb*. I'm sure there are more, but I don't know by heart. > > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser
>Ah, I see. You declared EP as Plibusb_endpoint_descriptor (i.e., the pointer to an endpoint descriptor record), while in the original code it is a USBEndpointDescriptor (i.e., the record itself). >Your version is more memory efficient but uses "ugly pointer- arithmetic" by taking the address of an array element. However, just keep it as you implemented it.
Well that wasn’t my idea,  I was trying to get it to compile and I saw the existing function:
// helper function for method below, this can't be a local function
Function MyEndpointMatch(EP:Plibusb_endpoint_descriptor;Data:Pointer):Boolean;
Var bEndpointAddress : Byte;
Begin
  bEndpointAddress := (PtrUInt(Data) shr 0) and $FF;
  Result := (EP^.bEndpointAddress = bEndpointAddress);
End;
	It compiled and had the pointer, so I stuck a pointer in the one I was having a problem with and it compiled.... it was just a guess at how to get it to compile honestly. I figured that the other code had it so maybe something to do with the way things are defined now require it to be a pointer.. without the pointer it gives errors.
>While reviewing your changes, I found a few small things. >Could you please keep the indenting and coding style as the existing code? This is especially for the constant and type declarations around TLibUsbPseudoHIDInterface (IIRC the >>keywords Type and Const should start at character 1, therefore you also should un-indent the 6+3 constants and the P/THIDReport record (except its final "End;" by 2 spaces.

Yes, I will keep the indenting and coding style the same, No problem, I adjusted this as you requested. I'll go through later and see if there are any other things I missed.. most of what I've done is cutting and pasting, but I'll keep it consistent.

>Secondly, in your improved TLibUsbInterface.FindEndpoint, please revert the capitalization and indenting changes (i.e., capital "Function", "For", ..., and "do" and "then" in the same line, ... IMHO the only changed lines in comparison to the original code should be the extra variable EP, its assignment without range checks, and its use in MatchFunc and Exit.

That was code the Jean sent me to get it to work under windows, but I wend an retrieved the original function and re-did the modifications to match the formatting. It compiles fine without turning off range check, but I think there was some reason why Jean had to put them in there.. I'll leave it out for now unless we figure out why they were needed.

>And thirdly, you introduced a class type TLibUsbInterruptInEndpoint, which is IMHO unused. If its so, please remove it. I like to avoid clutter. :-)
	I guess you are talking about line 128:   TLibUsbInterruptInEndpoint   = class; ?
              When I copied over { TUSBPseudoHIDInterface } and then renamed everything I needed it to be able to compile
	Line 211:    FIntrEndpoint : TLibUsbInterruptInEndpoint;
              Without it I was getting libusboop.pas(212,21) Error: Identifier not found "TLibUsbInterruptInEndpoint"
              So I went back to usb.pas and copied that line over to prevent this error... perhaps I have it in the wrong place??
>Apart form these cosmetic things, thank you very much for your effort!

No problem, please let me know if I missed anything, I'm happy to make it conform to the coding standards. I’m a little confused by the capitalization, for example sometimes it's LibUsb, sometimes it's Libusb.. I'm trying to figure out when the U is capitated and when it is not.... maybe it should always be one way or the other? Please continue to correct me on anything you see.

>I'm looking forward hearing from you your success when accessing a HID device (or call for help :-) ).

Well..... since you asked... I'm having a real challenge trying to figure out how I can use all this to access my device... I'm just not familiar with this kind of programming... constructors, destructors, and all this inherited stuff, it's not what I am used to, I never have anything like that.. I know how to program in Turbo Pascal for DOS pretty much and normal in-line console style programming, but very little of anything past that, so a lot of this just goes over my head. On top of that, I really don't understand USB communications at all, I have written programs with all kinds of features, programs that send e-mails, communicate over ethernet and serial connections, Modbus, etc... but this USB stuff is just not making any sense to me... and it seems like the python code I have as an example is so simple... you open the device, send and receive some stuff and close it... but I don't really know python either, so I really don't understand everything going on there... I still don't really see how to open and close the device or how to send or receive anything from it... I'm struggling to see how the somewhat simple looking functions in HB04.py can be implemented....

I'm trying to use one of the examples to just open and close the device, but I am not successful with that, Here is what I am trying to do:

I ran Test1library.pas and got the following:

Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312
Found 14 devices:
Bus 1 Device 0: ID 8086:A36D, port: 0, Speed: Unknown Bus 1 Device 5: ID 8087:0AAA, port: 14, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 33: ID 0424:2734, port: 1, port path from HCD: 0->1, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 7: ID 1B1C:0C15, port: 2, port path from HCD: 0->9, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 16: ID 10CE:EB93, port: 4, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 3: ID 05E3:0610, port: 9, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 18: ID 04E8:61F5, port: 19, port path from HCD: 0, Speed: unknown (4) Bus 1 Device 4: ID 1B1C:0C10, port: 10, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 25: ID 0424:274C, port: 5, port path from HCD: 0->1->1, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 34: ID 047D:1020, port: 3, port path from HCD: 0->1->1, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 1 Device 26: ID 1B1C:1B4F, port: 4, port path from HCD: 0->1->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 12: ID 1A40:0101, port: 1, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 14: ID 0C45:7403, port: 2, port path from HCD: 0->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 30: ID 10C4:EA60, port: 5, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed)

The one I want to try to use is this one:
Bus 1 Device 16: ID 10CE:EB93, port: 4, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) I assume that $10CE and $EB93 are the Vid and Pid??

I tried plugging those into the following test program:

program test_open_WHB04B;
{$mode objfpc}{$H+}
uses
    Classes,SysUtils,MyDevice,LibUsbOop,LibUsbUtil;
procedure WHB04B_Device;
const
     WHB04B_VID= $10CE;
     WHB04B_PID= $EB93;
var
   Context   : TLibUsbContext;
   TheDevice : TMyDevice;
function CreateMatch: TLibUsbDeviceMatchVidPid;
   begin
      Result:= TLibUsbDeviceMatchVidPid.Create( Context, WHB04B_VID, WHB04B_PID);
   end;
begin
     Context := TLibUsbContext.Create;
     try
        TheDevice := TMyDevice.Create( Context, CreateMatch, '', CreateMatch);
     except
       on E : Exception do
         Begin
           WriteLn('Couldn''t connect to device: ',E.Message);
           Halt(1);
         End;
     End;
     WriteLn('Successfully connected to USB device ',IntToHex(WHB04B_VID,4),':',IntToHex(WHB04B_PID,4));
     WriteLn('Version:        ',TheDevice.GetVersion);
     WriteLn('Version String: ',TheDevice.GetVersionString);
     WriteLn('Status:         ',TheDevice.GetStatus);
     while true
     do
       Write( TheDevice.ReadString);
     TheDevice.Free;
     Context.Free;
end;
begin
     WHB04B_Device;
End.

When I run it I get:
Running "i:\programming\pas-libusb_test_dll\src\examples\test_open_whb04b.exe " Couldn't connect to device: Access violation

When I try any of the other devices in the list I get: Running "i:\programming\pas-libusb_test_dll\src\examples\test_open.exe " Couldn't connect to device: Open: LIBUSB_ERROR_NO_DEVICE

What am I missing here? Why can't I get this to work?

Any help is greatly appreciated!

James

Reply by email

Johann Glaser
to James Richters

Hi James!

James Richters wrote 24 lines
> > Ah, I see. You declared EP as Plibusb_endpoint_descriptor (i.e., > > the pointer to an endpoint descriptor record), while in the > > original code it is a USBEndpointDescriptor (i.e., the record > > itself). > > Your version is more memory efficient but uses "ugly pointer- > > arithmetic" by taking the address of an array element. However, > > just keep it as you implemented it. Well that wasn’t my idea, I was trying to get it to compile and I saw the existing function: // helper function for method below, this can't be a local function Function MyEndpointMatch(EP:Plibusb_endpoint_descriptor;Data:Pointer):Boolean; Var bEndpointAddress : Byte; Begin bEndpointAddress := (PtrUInt(Data) shr 0) and $FF; Result := (EP^.bEndpointAddress = bEndpointAddress); End; It compiled and had the pointer, so I stuck a pointer in the one I was having a problem with and it compiled.... it was just a guess at how to get it to compile honestly. I figured that the other code had it so maybe something to do with the way things are defined now require it to be a pointer.. without the pointer it gives errors.

Yes, yes, no worries! That was no criticism, just a (hopefully) objective description of what I saw in the code. :-)

Show quoted text 12 lines
> > While reviewing your changes, I found a few small things. > > Could you please keep the indenting and coding style as the > > existing code? This is especially for the constant and type > > declarations around TLibUsbPseudoHIDInterface (IIRC the > > >>keywords Type and Const should start at character 1, therefore > > you also should un-indent the 6+3 constants and the P/THIDReport > > record (except its final "End;" by 2 spaces. Yes, I will keep the indenting and coding style the same, No problem, I adjusted this as you requested. I'll go through later and see if there are any other things I missed.. most of what I've done is cutting and pasting, but I'll keep it consistent.

Great, thanks! And there is no hurry.

Show quoted text 12 lines
> > Secondly, in your improved TLibUsbInterface.FindEndpoint, please > > revert the capitalization and indenting changes (i.e., capital > > "Function", "For", ..., and "do" and "then" in the same line, ... > > IMHO the only changed lines in comparison to the original code > > should be the extra variable EP, its assignment without range > > checks, and its use in MatchFunc and Exit. That was code the Jean sent me to get it to work under windows, but I wend an retrieved the original function and re-did the modifications to match the formatting. It compiles fine without turning off range check, but I think there was some reason why Jean had to put them in there.. I'll leave it out for now unless we figure out why they were needed.

You can just keep in the range checking. I think I should have done this from the beginning, but never used range checking, therefore never thought of it.

Show quoted text 12 lines
> > And thirdly, you introduced a class type > > TLibUsbInterruptInEndpoint, which is IMHO unused. If its so, > > please remove it. I like to avoid clutter. :-) I guess you are talking about line 128: TLibUsbInterruptInEndpoint = class; ? When I copied over { TUSBPseudoHIDInterface } and then renamed everything I needed it to be able to compile Line 211: FIntrEndpoint : TLibUsbInterruptInEndpoint; Without it I was getting libusboop.pas(212,21) Error: Identifier not found "TLibUsbInterruptInEndpoint" So I went back to usb.pas and copied that line over to prevent this error... perhaps I have it in the wrong place??

Let me have a closer look. :-)

Ah, sorry, it was my fault. I should have looked at the complete file, not just the diff. :-)

Please keep the forward declaration in.

Show quoted text 8 lines
> > Apart form these cosmetic things, thank you very much for your > > effort! No problem, please let me know if I missed anything, I'm happy to make it conform to the coding standards. I’m a little confused by the capitalization, for example sometimes it's LibUsb, sometimes it's Libusb.. I'm trying to figure out when the U is capitated and when it is not.... maybe it should always be one way or the other? Please continue to correct me on anything you see.

That's probably my own lazyness. However, at least in libusboop.pas, all declarations use LibUsb (capital 'U') everywhere. And in libusb.pas its "libusb" (all small letters) except the unit name itself.

Show quoted text 19 lines
> > I'm looking forward hearing from you your success when accessing > > a HID device (or call for help :-) ). Well..... since you asked... I'm having a real challenge trying to figure out how I can use all this to access my device... I'm just not familiar with this kind of programming... constructors, destructors, and all this inherited stuff, it's not what I am used to, I never have anything like that.. I know how to program in Turbo Pascal for DOS pretty much and normal in-line console style programming, but very little of anything past that, so a lot of this just goes over my head. On top of that, I really don't understand USB communications at all, I have written programs with all kinds of features, programs that send e-mails, communicate over ethernet and serial connections, Modbus, etc... but this USB stuff is just not making any sense to me... and it seems like the python code I have as an example is so simple... you open the device, send and receive some stuff and close it... but I don't really know python either, so I really don't understand everything going on there...

Regarding USB, I've recommended some EMails ago to read the first chapter of the AN2131 EZ-USB TRM. That really got me into USB.

I still don't really see how to open and close the device or how to send or receive anything from it... I'm struggling to see how the somewhat simple looking functions in HB04.py can be implemented....

It seems that libusb-1.0 as well as pas-libusb (incl. the OOP wrapper) are much nearer to the hardware than the Python stuff.

Show quoted text 27 lines
I'm trying to use one of the examples to just open and close the device, but I am not successful with that, Here is what I am trying to do: I ran Test1library.pas and got the following: Running "i:\programming\pas-libusb_test_dll\src\examples\test1library.exe " Using libusb(x) v1.0.22.11312 Found 14 devices: Bus 1 Device 0: ID 8086:A36D, port: 0, Speed: Unknown Bus 1 Device 5: ID 8087:0AAA, port: 14, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 33: ID 0424:2734, port: 1, port path from HCD: 0->1, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 7: ID 1B1C:0C15, port: 2, port path from HCD: 0->9, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 16: ID 10CE:EB93, port: 4, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 3: ID 05E3:0610, port: 9, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 18: ID 04E8:61F5, port: 19, port path from HCD: 0, Speed: unknown (4) Bus 1 Device 4: ID 1B1C:0C10, port: 10, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 25: ID 0424:274C, port: 5, port path from HCD: 0->1->1, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 34: ID 047D:1020, port: 3, port path from HCD: 0->1->1, Speed: 1.5 Mbit/s (USB LowSpeed) Bus 1 Device 26: ID 1B1C:1B4F, port: 4, port path from HCD: 0->1->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 12: ID 1A40:0101, port: 1, port path from HCD: 0, Speed: 480 Mbit/s (USB HighSpeed) Bus 1 Device 14: ID 0C45:7403, port: 2, port path from HCD: 0->1, Speed: 12 Mbit/s (USB FullSpeed) Bus 1 Device 30: ID 10C4:EA60, port: 5, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) The one I want to try to use is this one: Bus 1 Device 16: ID 10CE:EB93, port: 4, port path from HCD: 0, Speed: 12 Mbit/s (USB FullSpeed) I assume that $10CE and $EB93 are the Vid and Pid??

Exactly!

Show quoted text 16 lines
I tried plugging those into the following test program: program test_open_WHB04B; {$mode objfpc}{$H+} uses Classes,SysUtils,MyDevice,LibUsbOop,LibUsbUtil; procedure WHB04B_Device; const WHB04B_VID= $10CE; WHB04B_PID= $EB93; var Context : TLibUsbContext; TheDevice : TMyDevice;

IMHO you should _not_ use "MyDevice", because thats just a lousy demo of a hypothetical device with a built-in EZ-USB chip (you remember, without ROM or Flash). It downloads the firmware and then talks to that demo firmware.

Show quoted text 40 lines
function CreateMatch: TLibUsbDeviceMatchVidPid; begin Result:= TLibUsbDeviceMatchVidPid.Create( Context, WHB04B_VID, WHB04B_PID); end; begin Context := TLibUsbContext.Create; try TheDevice := TMyDevice.Create( Context, CreateMatch, '', CreateMatch); except on E : Exception do Begin WriteLn('Couldn''t connect to device: ',E.Message); Halt(1); End; End; WriteLn('Successfully connected to USB device ',IntToHex(WHB04B_VID,4),':',IntToHex(WHB04B_PID,4)); WriteLn('Version: ',TheDevice.GetVersion); WriteLn('Version String: ',TheDevice.GetVersionString); WriteLn('Status: ',TheDevice.GetStatus); while true do Write( TheDevice.ReadString); TheDevice.Free; Context.Free; end; begin WHB04B_Device; End. When I run it I get: Running "i:\programming\pas- libusb_test_dll\src\examples\test_open_whb04b.exe " Couldn't connect to device: Access violation

Would be interesting where this is coming from. It seems, Windows doesn't allow you to open that device. It could be, that Windows wants some "driver" (AFAIK just a .ini file). Or it could be that Windows saw that this is a USB HID device and now some Windows default HID driver is hogging that device.

Unfortunately I don't know anything of Windows, so I can't help here.

Show quoted text 6 lines
When I try any of the other devices in the list I get: Running "i:\programming\pas- libusb_test_dll\src\examples\test_open.exe " Couldn't connect to device: Open: LIBUSB_ERROR_NO_DEVICE What am I missing here? Why can't I get this to work?

Please consult my EMail from last Saturday with the attached snapi.pas.

You can basically use the TSNAPIDevice and remove everything you don't need. :-)

The important thing is the constructor, where the PseudoHID interface is allocated.

And then you can use the PseudoHID interface methods like SetReport, ... to communicate with the device.

In the hb04.py code I also see some "normal" read() and write() calls. AFAIK these are not covered by the standard HID. So we would have to find out what that Python easyhid is doing and then use the appropriate pas-libusb functions.

Bye
Hansi

Reply by email

James Richters
to Johann Glaser

I wonder if HID devices will work at all on Windows the same as they do on Linux. I have not been able to get the HID part of the python code to work on windows yet either because the instructions given to install the packages needed only apply to Linux... I also wonder if fundamental differences in operating systems is why FPC doesn't already have built in support for HID devices... maybe it's just not possible to make it cross platform.

I did a little searching... I came across this:
https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/introduction-to-hid-concepts

it seems maybe you are right and even though I did not install a driver into windows for this device, maybe windows just detected it was an HID device and attached it, and what I really need to do is access it through windows, not directly.. I had to do this with parallel ports.. I can't just read and write directly to the parallel port like I used to be able to with DOS, I have to go through windows somehow.. I am using http://www.highrez.co.uk/Downloads/InpOut32/ to work with parallel ports with Windows. I think it's a DLL written in C, so I had to write a unit to get it to work with FPC... but it does work reliably even though windows shows the ports in device manager. Microsoft seems to be completely against users accessing hardware directly as we used to be able to with DOS.

I wonder if the only way to get FPC to work with HID devices on Windows is to do something similar with the windows HID API, and go through windows the only way windows will allow me to access these devices. I've been searching trying to find information on this.. I came across the project at:

https://github.com/signal11/hidapi

it states in the readme:

HIDAPI has four back-ends:
* Windows (using hid.dll)
* Linux/hidraw (using the Kernel's hidraw driver)
* Linux/libusb (using libusb-1.0)
* FreeBSD (using libusb-1.0)
* Mac (using IOHidManager)

This seems to indicate the libusb-1.0 is what you use for Linux and FreeBSD, but not for windows, because if it worked for Windows or Mac, then why bother doing it differently for them. Of course this project is for C, not pascal....

So then I was looking for a Pascal way to use hid.dll, and came across this: https://github.com/prof7bit/HIDAPI.pas/blob/master/hidapi.pas that looked promising because it has functions like Open(), Close(), Write(), Read(), SendFeatureReport() etc... but.... that isn't working under windows... uggggggg.

It seems that using this HID device with FPC under windows is going to be anything but easy... ugggg maybe I can solve it with hardware.. I can get a raspberry pi, teach my self python, hack the python code to interface with the HID device on the Rpi and communicate with my windows 10 FPC program over an ethernet port or something stupid like that and hope it's fast enough... boy is sure seems stupid to use another complete computer to interface this once device to windows... I guess I'll keep trying to come up with a solution.

Anyone have any thoughts on all this?

James

Reply by email

José Mejuto
to James Richters: I wonder if HID devices will work at all on Windows the same as they do on Linux. I…
James Richters wrote
I wonder if HID devices will work at all on Windows the same as they do on Linux. I have not been able to get the HID part of the python code to work on windows yet either because the instructions given to install the packages needed

Hello,

HID devices works in the same way, you need a device driver for the hardware that exposes a HID interface and you can manage that HID interface using native hid.dll or use an abstraction layer like libusb-1.0.

https://github.com/JoshyFun/VUSBRelayPascal

My code to manage HID USB relays uses hid.dll (32 & 64 bits) or libusb-1.0 (32 bits only tested) on Windows, and libusb-1.0 or libusb-0.1 in Linux.

Of course, functions on hid.dll and libusb are no the same, they work in different way, but the libusb-1.0 works the same way in both platforms.

Implementation of hid.dll, libusb, etc, in my code only have relevant functions used in USB relays, so they can not used as a complete implementation.

In the other hand, the hardware you are trying to manage is 10CE:EB93 ? 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.

Reply by email

James Richters
to Jean SUZINEAU: Le 14/08/2019 à 01:41, James Richters a écrit : I'm busy for now, but I'll have a look…
Did you try to change your driver with Zadig (https://zadig.akeo.ie/) for your device 10CE:EB93 ?

No, I didn't try that.. but I'm trying it now.... I downloaded Zadig, and used the pulldown and selected devices until I got the one with the USB ID I want. It filled in as follows:
"USB Input Device"
Driver: HidUSB (v10.0.17763.1)
USB ID: 10CE EB93
WCID has a red X in it

I am not sure what to do from here. It looks like it has a driver for HidUSB and maybe that's what I want because the project at https://github.com/prof7bit/HIDAPI.pas has the same functions as the ones I am looking to duplicate... but then I don't know, maybe I am mixing up terminology

Anyway, before I go changing drivers.. is there some way to un-do this change? I don't see HidUSB in the list of drivers that Zadig can install, so if it turns out hat I really wanted HidUSB driver and I changed it to LibUsb then is there a way to put it back?

James

Reply by email

James Richters
to José Mejuto: HID devices works in the same way, you need a device driver for the hardware that exposes…
My code to manage HID USB relays uses hid.dll (32 & 64 bits) or libusb-1.0 (32 bits only tested) on Windows, and libusb-1.0 or libusb-0.1 in Linux.

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.

Of course, functions on hid.dll and libusb are no the same, they work in different way, but the libusb-1.0 works the same way in both platforms.

The hid.dll way seems to have the functions I am trying to duplicate.

Implementation of hid.dll, libusb, etc, in my code only have relevant functions used in USB relays, so they can not used as a complete implementation.

Maybe it will at least be able to get me started with some basic access.. at this point I would be happy to make it just open and close the device without an error.

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?

Reply by email

José Mejuto
to James Richters
James Richters wrote
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.

Show quoted text 5 lines
> 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)" ?

Reply by email

James Richters
to José Mejuto

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

Earlier message 28 lines
-----Original Message----- From: fpc-pascal On Behalf Of José Mejuto Sent: Thursday, August 15, 2019 8:34 AM To: 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)" ? --

Reply by email

José Mejuto
to James Richters
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?

Hello,

You can find a HID interface for windows at:

https://libstock.mikroe.com/projects/view/528/usb-hid-dll-for-delphi-and-perhaps-other-languages

In the "Basic" package.

Anyway, if possible, the use of libusb-1.0 is recommended as it will give you crossplatform support.

You can check my project to see how devices are enumerated, based in the libusb-1.0 function calls.

Reply by email

Stefan V. Pantazi
to James Richters: Yes, in device manager I see it listed as "HID-compliant vendor-defined device" also…

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.

James Richters wrote 32 lines
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 On Behalf Of José Mejuto Sent: Thursday, August 15, 2019 8:34 AM To: 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)" ?
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi

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

Earlier message 55 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Thursday, August 15, 2019 5:31 PM To: 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 On Behalf > Of José Mejuto > Sent: Thursday, August 15, 2019 8:34 AM > To: > 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)" ? > > --

Reply by email

Stefan V. Pantazi
to James Richters

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!

James Richters wrote 66 lines
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 On Behalf Of Stefan V. Pantazi Sent: Thursday, August 15, 2019 5:31 PM To: 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 On Behalf > Of José Mejuto > Sent: Thursday, August 15, 2019 8:34 AM > To: > 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 - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi

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

Reply by email

Stefan V. Pantazi
to James Richters: DATA!!!!!!!!!!!!!! Running "i:\programming\libusbxhid\libusbhid_test.exe " Found 15…
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:

Show quoted text 5 lines
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!

Reply by email

James Richters
to Stefan V. Pantazi
>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?

Show quoted text 6 lines
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

Reply by email

Stefan V. Pantazi
to James Richters
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

_______________________________________________________

Reply by email

Jean SUZINEAU
to James Richters: Can I even do threads in a console program? Is there another way to do a read that has…

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.

Reply by email

James Richters
to Stefan V. Pantazi: I see I did not finish my sentence. What I had in mind is that you could use a library…

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

Earlier message 30 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Friday, August 16, 2019 1:30 PM To: 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 --

Reply by email

James Richters
to Jean SUZINEAU: Le 16/08/2019 à 17:11, James Richters a écrit : Yes, you can.  I have in production…

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

Earlier message 23 lines
-----Original Message----- From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Friday, August 16, 2019 1:34 PM To: 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.

Reply by email

José Mejuto
to James Richters
James Richters wrote
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 :-(

Reply by email

James Richters

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

Reply by email

Stefan V. Pantazi
to James Richters: I’m trying to figure out why I get an access violation when I try to open my device…

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.

James Richters wrote 160 lines
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 - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

Jean SUZINEAU
to Stefan V. Pantazi

Le 17/08/2019 à 17:10, Stefan V. Pantazi a écrit :

Show quoted text 6 lines
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 ...

Reply by email

Stefan V. Pantazi
to Jean SUZINEAU

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.

Jean SUZINEAU wrote 26 lines
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  -  https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi

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

Earlier message 40 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Saturday, August 17, 2019 12:11 PM To: 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 - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal --

Reply by email

Stefan V. Pantazi
to James Richters

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;
James Richters wrote 63 lines
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 On Behalf Of Stefan V. Pantazi Sent: Saturday, August 17, 2019 12:11 PM To: 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 - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal -- _______________________________________________________ _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

Jean SUZINEAU
to James Richters: I think maybe it is the calling convention... First I tried to change libusboop.pas…

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.

Reply by email

James Richters
to Stefan V. Pantazi: fromt he copy of your github, looks like libusboop.pas has a uses statement for…

Oops, I got mixed up.. it's usb.pas that isn't used anymore... I changed LibUsb to stdcall and not it compiles again.. but I still get he access violation with stdcall.

James

Show quoted text 6 lines
from the 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;

Reply by email

Stefan V. Pantazi
to James Richters

Is the segfault in the same place or has it changed?

To debug further, you have to compare sizes of data structures, field types and function call parameter types between the libusb 1.0 and the old libusb0.1. - any mismatch could result in a segfault.

James Richters wrote 16 lines
Oops, I got mixed up.. it's usb.pas that isn't used anymore... I changed LibUsb to stdcall and not it compiles again.. but I still get he access violation with stdcall. James > from the 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; _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

Johann Glaser
to Jean SUZINEAU:

Hi!

Jean SUZINEAU wrote 25 lines
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.

Thanks Jean for the explanation! The MatchFunc is a so called "callback". I've chosen this pattern to allow to implement flexible filter functions when searching for devices, interfaces, endpoints, ...

As far as I can see, you are using TMyDevice in mydevice.pas. This unit is specifically implemented for the EZ-USB chips (Cypress AN2131), which do not have Flash or ROM, but only SRAM. The driver has to download the firmware before the real communication. This specific behavior is demonstrated in mydevice.pas. Therefore it is only of limited use for your device.

One action of TMyDevice.Create is to open an interface and then two bulk endpoints (see lines 141-145 in your "Hack" branch. The interface can be opened (hence you see an 'e' in your output. Then wants to open the endpoint 2 (line 143) using
TLibUsbInterface.FindEndpoint(bEndpointAddress : Byte) at libusboop.pas:1099. This calls via some detours the function where you've added the WriteLns.

Actually all these functions should reside cleanly in the Pascal world and there are no calls to libusb functions, therefore I wouldn't expect any calling convention troubles here.

Could you please remove the try-except block in
testopendevic_vidpid2.pas and compile with debug line info to get the full exception backtrace incl. line numbers?

Thanks
Hansi

Reply by email

James Richters
to Johann Glaser

I commented out all the try & except stuff and ran it.. I get this output:

Running "i:\programming\pas-libusb_test_dll\src\examples\testopendevic_vidpid2.exe " 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
N
P
L
H1
I
I2
Q
R
K
M
O1
An unhandled exception occurred at $000000010002D0BB: EAccessViolation: Access violation
$000000010002D0BB CREATE, line 1330 of libusboop.pas $000000010002B3AB
$0000000100001942 main, line 75 of ../../pas-libusb_test_dll/src/examples/testopendevic_vidpid2.pas $0000000100001AF6 main, line 96 of ../../pas-libusb_test_dll/src/examples/testopendevic_vidpid2.pas $0000000100010040
$00000001000017F0
$00007FFB66D07E94
$00007FFB675FA251

>Could you please remove the try-except block in testopendevic_vidpid2.pas and compile with debug line info to get the full exception backtrace incl. line numbers?

Reply by email

Johann Glaser
to James Richters

Hi!

James Richters wrote
I commented out all the try & except stuff and ran it.. I get this output:

Could you please "git push" the source code to Github so that the line numbers match the output? At least in line 1330 of libusboop.pas there is no Create. Please ensure that the version on Github is the very same version where you executed the program and got the line numbers.

Thanks
Hansi

Show quoted text 59 lines
Running "i:\programming\pas- libusb_test_dll\src\examples\testopendevic_vidpid2.exe " 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 N P L H1 I I2 Q R K M O1 An unhandled exception occurred at $000000010002D0BB: EAccessViolation: Access violation $000000010002D0BB CREATE, line 1330 of libusboop.pas $000000010002B3AB $0000000100001942 main, line 75 of ../../pas- libusb_test_dll/src/examples/testopendevic_vidpid2.pas $0000000100001AF6 main, line 96 of ../../pas- libusb_test_dll/src/examples/testopendevic_vidpid2.pas $0000000100010040 $00000001000017F0 $00007FFB66D07E94 $00007FFB675FA251 > > Could you please remove the try-except block in > > testopendevic_vidpid2.pas and compile with debug line info to get > > the full exception backtrace incl. line numbers? _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser

I just pushed it.

Could you please "git push" the source code to Github so that the line numbers match the output? At least in line 1330 of libusboop.pas there is no Create. Please ensure that the version on Github is the very same version where you executed the program and got the line numbers.

Thanks
Hansi

Show quoted text 49 lines
Running "i:\programming\pas- libusb_test_dll\src\examples\testopendevic_vidpid2.exe " 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 N P L H1 I I2 Q R K M O1 An unhandled exception occurred at $000000010002D0BB: EAccessViolation: Access violation $000000010002D0BB CREATE, line 1330 of libusboop.pas $000000010002B3AB $0000000100001942 main, line 75 of ../../pas- libusb_test_dll/src/examples/testopendevic_vidpid2.pas $0000000100001AF6 main, line 96 of ../../pas- libusb_test_dll/src/examples/testopendevic_vidpid2.pas $0000000100010040 $00000001000017F0 $00007FFB66D07E94 $00007FFB675FA251

Reply by email

James Richters
to Johann Glaser: Hi! Could you please "git push" the source code to Github so that the line numbers match…

I have a question about USB data transfer.. but it's going to take some explanation...

I've been doing more testing with my device and Libusbxhid. Here's the device: https://www.amazon.com/gp/product/B07M5ZY1P2

I have all the inputs working, still have to figure out how to output to the LCD... I've implemented a test program that shows what button I have pressed, and it also processes the switches and handwheel properly... The hand wheel has 100 indents on it, and if I rotated it clockwise, it gives me a positive count, and if I rotate it counter-clockwise, it gives me two's compliment representation of a negative count, it only sends a single byte, and the number it sends is the number of ticks since the last time it reported.... so it would have to be read at least every 127 ticks.

ok.. so I got that all working but then I discovered an issue... I thought the count on the hand wheel was the number of ticks since the last time I got the report... because if I turn the when very slow, I only get 1 or -1... but if I turn it faster, I get larger numbers... but once I got it reporting the total count... I found that if I start with the wheel at the 0 mark, and turn it really slow, it will count exactly 100 times when it returns to the zero point.. but if I got at even a slow (but not ridiculous) speed, then the count would come up short, and if I turned it fast, it would come up really short...

So I tried a test, and disabled the writeln to the console... and now it is much more accurate.. at slow and medium speeds it is exact but at really fast speeds it is still slightly short. So I thought this would be a great use for a thread! So I looked into it.. and I guess in windows I don't even need a unit to run a thread.. I just need to define a function and do a BeginThread() to run the function in a thread... well I didn't think it would be THAT easy.. but yes it works! Now I'm going to have threads everywhere LOL. I have the thread running the tightest possible loop to just read the data and store it in the fastest way possible so it can get back to reading again... then outside the thread I read the variables once every 5 seconds and just put where it is... well this improved things greatly, and I will probably use the thread method in the final program... but one thing is still bugging me... it's just not 100% exact all the time, even with the thread method, I still miss count here and there...

So back to the in-line code with writeln's of a minute... I tried another test... this time I read the device as normal, then I put a huge delay in.. 5 seconds or so, then I started reading it again.. now if my previous theory was correct, then I should be able to give up to 127 pulses during the delay and it would show the total since the last report... but that's not what happened.. it just forgets about whatever happened during the delay....I was careful to only do 1/2 rotation which would be about 50 pulses so I know I didn't make it overflow.... so this behavior makes me think I am not reading it the correct way.... it's like it sends the report out every so often whether I am reading it or not.. and when I do read it I get whatever count it is since the last OUTPUT, even if I missed the last output... also if I push a button and release it during the delay, I have no indication it was ever pressed.

So my question is.. does this behavior suggest that the device is expecting some other transfer method that would guarantee synchronization? I see in pas-libusb there are test2controlsync and test test3controlasync I'm curious if synchronous transfer would be the way to communicate with the device that would guarantee no data loss. I don't really understand how either of these work, but one is sync and the other is async, so I thought maybe sync was more the method I should be using. My program in libusbxhid is using:

hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}3000);

Maybe it's not either of those.. but some other method where the device pushes data into a buffer whenever it wants that I can then read.. or something like that? Or maybe the interrupt read is the best I can do? Is there any way to give my read thread to have a higher priority or something like that?

Any thoughts?

James

Reply by email

Stefan V. Pantazi
to James Richters

James,

From the looks of it you made good progress reading the hardware and using a dedicated thread for it. Congrats! Seems you're in the thick of it now ready to get the minute details sorted out.

Anyway, just a heads up that concurrent programming (threads, synchronization, etc) has many pitfalls.

My armchair guess is that your program is just not reading fast enough to keep up with the rate of data that the hardware is generated. Having time sensitive code in a separate thread is a good idea but you should also store the report data in an adequately sized and thread safe data structure such as a thread-safe list/queue. FreePascal has something you could use
(https://www.freepascal.org/docs-html/rtl/classes/tthreadlist.html) and although dynamically allocated, it may be fast enough for your purposes. Thread safety is crucial to avoid multiple threads overwriting the data structures they share. The way I see it, your timing sensitive hardware reading thread would fill up the queue and then, every so often, your main thread would consume the data from it. You have to also imagine mechanisms to check that one can keep up with the other and signal errors when that is not the case.

Hope this helps, and good luck!

James Richters wrote 27 lines
I have a question about USB data transfer.. but it's going to take some explanation... I've been doing more testing with my device and Libusbxhid. Here's the device: https://www.amazon.com/gp/product/B07M5ZY1P2 I have all the inputs working, still have to figure out how to output to the LCD... I've implemented a test program that shows what button I have pressed, and it also processes the switches and handwheel properly... The hand wheel has 100 indents on it, and if I rotated it clockwise, it gives me a positive count, and if I rotate it counter-clockwise, it gives me two's compliment representation of a negative count, it only sends a single byte, and the number it sends is the number of ticks since the last time it reported.... so it would have to be read at least every 127 ticks. ok.. so I got that all working but then I discovered an issue... I thought the count on the hand wheel was the number of ticks since the last time I got the report... because if I turn the when very slow, I only get 1 or -1... but if I turn it faster, I get larger numbers... but once I got it reporting the total count... I found that if I start with the wheel at the 0 mark, and turn it really slow, it will count exactly 100 times when it returns to the zero point.. but if I got at even a slow (but not ridiculous) speed, then the count would come up short, and if I turned it fast, it would come up really short... So I tried a test, and disabled the writeln to the console... and now it is much more accurate.. at slow and medium speeds it is exact but at really fast speeds it is still slightly short. So I thought this would be a great use for a thread! So I looked into it.. and I guess in windows I don't even need a unit to run a thread.. I just need to define a function and do a BeginThread() to run the function in a thread... well I didn't think it would be THAT easy.. but yes it works! Now I'm going to have threads everywhere LOL. I have the thread running the tightest possible loop to just read the data and store it in the fastest way possible so it can get back to reading again... then outside the thread I read the variables once every 5 seconds and just put where it is... well this improved things greatly, and I will probably use the thread method in the final program... but one thing is still bugging me... it's just not 100% exact all the time, even with the thread method, I still miss count here and there... So back to the in-line code with writeln's of a minute... I tried another test... this time I read the device as normal, then I put a huge delay in.. 5 seconds or so, then I started reading it again.. now if my previous theory was correct, then I should be able to give up to 127 pulses during the delay and it would show the total since the last report... but that's not what happened.. it just forgets about whatever happened during the delay....I was careful to only do 1/2 rotation which would be about 50 pulses so I know I didn't make it overflow.... so this behavior makes me think I am not reading it the correct way.... it's like it sends the report out every so often whether I am reading it or not.. and when I do read it I get whatever count it is since the last OUTPUT, even if I missed the last output... also if I push a button and release it during the delay, I have no indication it was ever pressed. So my question is.. does this behavior suggest that the device is expecting some other transfer method that would guarantee synchronization? I see in pas-libusb there are test2controlsync and test test3controlasync I'm curious if synchronous transfer would be the way to communicate with the device that would guarantee no data loss. I don't really understand how either of these work, but one is sync and the other is async, so I thought maybe sync was more the method I should be using. My program in libusbxhid is using: hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}3000); Maybe it's not either of those.. but some other method where the device pushes data into a buffer whenever it wants that I can then read.. or something like that? Or maybe the interrupt read is the best I can do? Is there any way to give my read thread to have a higher priority or something like that? Any thoughts? James _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi

As far as reading it goes, things are going pretty well.. I still have yet to write to the display.. I can't get any of my attempts to send data to it to be successful at all.. I get "control transfer to usb device failed!"

Thanks for the advice on a thread safe queue!

For the moment I've been trying to do the math inside thread reading the usb device... it's pretty simple, and that allows me to read the totals at any time.. but I can see what you mean that if I just read the device and dump everything into maybe some kind of ring buffer without bothering to try to process it at all, and increment the buffer position then it could be ready to read again even faster. I could have my other slow process crunch the buffer. I have two of these devices, one is wireless, the other has a USB cable attached to it.. they both work a little differently.. the wireless one only responds to my interrupt read when some data has been generated... the wired version always responds to my request whether any data has been generated or not. For that one I would have to do a compare on the data to see if anything changed before adding to the buffer otherwise the buffer would always be overrun.

Still I can't image my math is taking very long.. here is what I am doing: Read device
If wheel moved then add wheel counts to appropriate variable then read device Else
Update other variables if they changed then read device So when the wheel is moving I have very few instructions between reads.. I don't bother checking for buttons or anything else.. I just keep accumulating the total, and that's all I care about, and then I read again.. I only bother with the buttons if the wheel didn't move.

One thing I'm really not sure how to handle with threads is this.... ok so I have my main fast read thread going in the tightest loop possible... but now I want to write something to the display (assuming I ever figure that out and don't just put a sticker over the display and look at the screen instead :D ) It seems I would have to stop reading to get a chance to write something.. I did a little test and I can do a suspend(Thread_ID) and resume(Thread_ID) but what if it's in the middle of a read.. but only got 6 of the 8 bytes when I do the suspend?? Now I am not really ready to write..... so what method can I use to do a suspend_thread_just_before_the_next_read_happens() ? so that when the thread is suspended, the read is completed and the buffer updated.. etc.. and the USB system and libusb are all ready for me to send my write commands? Resuming would be no problem.. because it was suspended at the correct position.. I can just resume when I am done with the write and everything should be fine.

I also still am hoping to find a method of making the device wait for me to read it... even with threads in my program, the operating system could go off and do something that takes all the processor time for a second and I would just not know about events that happened during that time.

James

Earlier message 17 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Sunday, August 18, 2019 3:12 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices James, From the looks of it you made good progress reading the hardware and using a dedicated thread for it. Congrats! Seems you're in the thick of it now ready to get the minute details sorted out. Anyway, just a heads up that concurrent programming (threads, synchronization, etc) has many pitfalls. My armchair guess is that your program is just not reading fast enough to keep up with the rate of data that the hardware is generated. Having time sensitive code in a separate thread is a good idea but you should also store the report data in an adequately sized and thread safe data structure such as a thread-safe list/queue. FreePascal has something you could use (https://www.freepascal.org/docs-html/rtl/classes/tthreadlist.html) and although dynamically allocated, it may be fast enough for your purposes. Thread safety is crucial to avoid multiple threads overwriting the data structures they share. The way I see it, your timing sensitive hardware reading thread would fill up the queue and then, every so often, your main thread would consume the data from it. You have to also imagine mechanisms to check that one can keep up with the other and signal errors when that is not the case. Hope this helps, and good luck!

Reply by email

Stefan V. Pantazi
to James Richters
James Richters wrote
As far as reading it goes, things are going pretty well.. I still have yet to write to the display.. I can't get any of my attempts to send data to it to be successful at all.. I get "control transfer to usb device failed!"

Assuming there are no other bugs in the libusbxhid library, for writing data you have to guess the reportType (in, out, feature) and reportNum parameter and set the report data buffer correctly (first byte is the report number) for your device. Have a look at similar devices.

One thing I'm really not sure how to handle with threads is this.... ok so I have my main fast read thread going in the tightest loop possible... but now I want to write something to the display (assuming I ever figure that out and don't just put a sticker over the display and look at the screen instead :D ) It seems I would have to stop reading to get a chance to write something.. I did a little test and I can do a suspend(Thread_ID) and resume(Thread_ID) but what if it's in the middle of a read.. but only got 6 of the 8 bytes when I do the suspend?? Now I am not really ready to write..... so what method can I use to do a suspend_thread_just_before_the_next_read_happens() ? so that when the thread is suspended, the read is completed and the buffer updated.. etc.. and the USB system and libusb are all ready for me to send my write commands? Resuming would be no problem.. because it was suspended at the correct position.. I can just resume when I am done with the write and everything should be fine.

My guess is that it would be better to leave the time sensitive read thread to do the fast reads and immediate calculations and leave writing to the device screen in a separate thread (even main thread), with a lower update frequency!

I also still am hoping to find a method of making the device wait for me to read it... even with threads in my program, the operating system could go off and do something that takes all the processor time for a second and I would just not know about events that happened during that time.

If an operating system were realtime that should not happen. This is why LinuxCNC uses the realtime extensions (http://linuxcnc.org/)

Some devices have multiple functional modes that can be selected by writing their appropriate settings/registers. For example, a graphic tablet I used before has a finger input mode (really becomes a trackpad) and a pen mode (uses the stylus, as usual). For more complex devices, guessing such things is less practical, you really need knowledge of the device or similar ones.

Reply by email

James Richters
to Stefan V. Pantazi
>Assuming there are no other bugs in the libusbxhid library, for writing data you have to guess the reportType (in, out, feature) and reportNum parameter and set the report data buffer correctly (first byte is the report number) for your device. Have a look at similar devices.

I don't know if there is a bug or not... but I "Think" I have the information I need. I found this device documented here: https://github.com/rubienr/machinekit/tree/feature-xhc-whb04b-6/src/hal/user_comps/xhc-whb04b-6

it states: "Data transmitted is packed as 7 bytes plus a constant leading byte 0x06 which is the report ID. The data exclusive report ID reads as follows:" this matches the python code I was trying to duplicate... so I send a $06 then 7 bytes of data at a time. It also describes the data structure as well.

The C code at https://github.com/rubienr/machinekit/blob/feature-xhc-whb04b-6/src/hal/user_comps/xhc-whb04b-6/usb.cc Uses libusb... here is the relevant section: It's in C but it's commented pretty well.. and describes the exact parameters passed to libusb_control_transfer

void Usb::sendDisplayData()
{

    outputPackageBuffer.asBlocks.init(&outputPackageData);
    if (mIsSimulationMode)
   {
        *verboseTxOut << "out   0x" << outputPackageBuffer.asBlocks << endl <<
                      std::dec << "out   size " << sizeof(outputPackageBuffer.asBlockArray) << "B " << outputPackageData
                      << endl;
    }
    for (size_t idx = 0; idx < (sizeof(outputPackageBuffer.asBlockArray) / sizeof(UsbOutPackageBlockFields)); idx++)
    {
        UsbOutPackageBlock& block = outputPackageBuffer.asBlockArray[idx];
        size_t blockSize = sizeof(UsbOutPackageBlock);
        // see also
        // http://www.beyondlogic.org/usbnutshell/usb6.shtml
        // http://libusb.sourceforge.net/api-1.0/group__desc.html
        // http://libusb.sourceforge.net/api-1.0/group__misc.html
        int    r         = libusb_control_transfer(deviceHandle,
            // send to hid descriptor: bmRequestType == LIBUSB_DT_HID == 0x21 == (interface | endpoint)
                                                   LIBUSB_DT_HID,
            // bRequest == LIBUSB_REQUEST_SET_CONFIGURATION == 0x09 == set configuration
                                                   LIBUSB_REQUEST_SET_CONFIGURATION,
            // wValue: if bRequest == LIBUSB_REQUEST_SET_CONFIGURATION the configuration value
                                                   0x0306,
            // wIndex, device interface number
                                                   0x00,
            // data to transmit
                                                   block.asBuffer.asBytes,
            // wLength, data length
                                                   blockSize,
            // transfer timeout[ms]
                                                   0);

if (r < 0)
{

            std::cerr << "transmission failed, try to reconnect ..." << endl;
            setDoReconnect(true);
            return;
        }
    }

}

So I tried with libusbxhid:
libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet ) and I get control transfer to usb device failed!

so inside function libusbhid_set_report, I put a bunch of writelns to show what is being passed to libusb_control_transfer:
  Writeln('device handle =');
  Writeln('bmRequestType = $', inttohex(LIBUSB_CONTROL_REQUEST_TYPE_OUT,4));
  Writeln('bRequest      = $', inttohex(HID_SET_REPORT,4)                 );
  Writeln('wValue        = $', inttohex((reportType << 8) or reportNum,4) );
  Writeln('wIndex        = $', 0                                          );
  Writeln('data          = ',  '$'+Inttohex(report_data[0],2),' $'+Inttohex(report_data[1],2),' $'+Inttohex(report_data[2],2),' $'+Inttohex(report_data[3],2),' $'+Inttohex(report_data[4],2),' $'+Inttohex(report_data[5],2),
                              ' $'+Inttohex(report_data[6],2),' $'+Inttohex(report_data[7],2));
  Writeln('wLength       = $', Inttohex(reportLen,2)                      );
  Writeln('timeout       = $', 0                                          );
  Result:=libusb_control_transfer(hid_device_context.usb_device_handle,LIBUSB_CONTROL_REQUEST_TYPE_OUT{????},HID_SET_REPORT,(reportType << 8) or reportNum, 0{interface_num}, @report_data, reportLen{sizeof(data)},0{no timeout});

Suspend
06 FD FE FF 01 02 03 04
device handle =
bmRequestType = $0021
bRequest = $0009
wValue = $0306
wIndex = $0
data = $06 $FD $FE $FF $01 $02 $03 $04
wLength = $08
timeout = $0
control transfer to usb device failed!
-1
It shows I'm getting the same values for everything.... but yet it's still failing. I have this attempt on my fork at https://github.com/Zaaphod/libusbxhid

I'm not sure it's libusbxhid though.. because I also can't get it to work with pas-libusb I can run test3controlasync.pas with my device and it does send a request to the device and retrieves some information from it... so I modified that program (test3controlasync_2.pas) to just pass the same paramaters as above and then it doesn't work anymore... here's the output from test3controlasync_2.pas

Running "i:\programming\pas-libusb_test_dll\src\examples\test3controlasync_2.exe " Submitting control transfer
Finished Transfer, Data = 38, Status = 0, ActualLength = 18 Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor $10CE
idProduct $EB93
bcdDevice 1.00
iManufacturer 1
iProduct 0
iSerialNumber 0
bNumConfigurations 1
Done.
CT.bmRequestType = 21
CT.bRequest = 09
CT.wValue = 306
CT.wIndex = 00
CT.wLength = 07
CT.Timeout = 00
Submitting control transfer
USB Error: Submit: LIBUSB_ERROR_IO: LIBUSB_ERROR_IO

So it worked for the first information request (the default one including with the original test2controlasync.pas) , but not for my attempted request.. this leads me to believe that I have something wrong and it's not a bug... but I'm lost as to what it might be.. my attempt is on my fork here: https://github.com/Zaaphod/pas-libusb/blob/Hack/src/examples/test3controlasync_2.pas

Show quoted text 6 lines
> One thing I'm really not sure how to handle with threads is this.... ok so I have my main fast read thread going in the tightest loop possible... but now I want to write something to the display (assuming I ever figure that out and don't just put a sticker over the display and look at the screen instead :D ) It seems I would have to stop reading to get a chance to write something.. I did a little test and I can do a suspend(Thread_ID) and resume(Thread_ID) but what if it's in the middle of a read.. but only got 6 of the 8 bytes when I do the suspend?? Now I am not really ready to write..... so what method can I use to do a suspend_thread_just_before_the_next_read_happens() ? so that when the thread is suspended, the read is completed and the buffer updated.. etc.. and the USB system and libusb are all ready for me to send my write commands? Resuming would be no problem.. because it was suspended at the correct position.. I can just resume when I am done with the write and everything should be fine. My guess is that it would be better to leave the time sensitive read thread to do the fast reads and immediate calculations and leave writing to the device screen in a separate thread (even main thread), with a lower update frequency!

Yes, that was what I was attempting to describe.. but I can't write to the usb device if the read thread happens to be in the middle of a read... so how do I pause the read thread at the correct time so it's not partially in the middle of reading a packet, and I can't read again until I'm done writing. I figure I can just check for some period of time of idle handwheel input before I stop the read thread and do the write then start the read thread again, because only the handwheel produces such a large stream of data.. but still I’m not sure how to make sure I stop it at the correct time.

James

Reply by email

Marc Santhoff
to James Richters

Hi James,

are you really sure the WHB04B-6 is exactly the same as your WHB04B-4 viewn to the USB API?

If those thingys come with a dll, maybe you can compare the header files? If there is no header file you could ask the manufacturer for it. If they made a programm using that dll, there must be a header file.

HTH somehow...

Marc Santhoff

Reply by email

Stefan V. Pantazi
to James Richters: I don't know if there is a bug or not... but I "Think" I have the information I need. I…
Show quoted text 6 lines
> My guess is that it would be better to leave the time sensitive read > thread to do the fast reads and immediate calculations and leave writing > to the device screen in a separate thread (even main thread), with a > lower update frequency! Yes, that was what I was attempting to describe.. but I can't write to the usb device if the read thread happens to be in the middle of a read... so how do I pause the read thread at the correct time so it's not partially in the middle of reading a packet, and I can't read again until I'm done writing. I figure I can just check for some period of time of idle handwheel input before I stop the read thread and do the write then start the read thread again, because only the handwheel produces such a large stream of data.. but still I’m not sure how to make sure I stop it at the correct time.

I do not get why should you stop the read thread, when that is the actual advantage of having multiple threads. While the read thread is busily reading input in a buffer/queue/what have you, you are free within limits) to do whatever you need to do (e.g., output to LCD display, do calculations) in the other threads, including the main thread, after which, you can get back to consuming and processing the (hopefully only slightly larger now) data from the read thread buffer/queue. After you figured writing to the LCD screen you could try writing random data to it while reading and processing handwheel and button input *at the same time*. Hope this makes sense.

_______________________________________________________

Reply by email

James Richters
to Marc Santhoff: are you really sure the WHB04B-6 is exactly the same as your WHB04B-4 viewn to the USB…

They come with a little CD, but not much really useful on them.. mostly instructions on how to get them to work with Mach3. But the manual does cover both models. The only difference is one has a selection switch for 4 axis and the other has one for 6 axis, but the 4 axis version shows 6 axis on the LCD so I think everything else is identical even the firmware. The manual does have a dll on it called ShuttlePro.dll I have no idea what to do with that... they don't include any program at all, just instructions for mach3. The documentation is very poor and there is no support at all on how to access it.. I'm just going on what everyone else has kind of figured out plus what I could figure out from just pushing the buttons on it.

There's a readme in the same folder as ShuttlePro.dll:

ShuttlePro.dll is the Driver of HB04BX for MACH3 cnc control system. You could externd the IO input with our wireless handle.To do reset,start,stop etc. The handle is just like
ShuttlePRO,you coul do jog mpg and step with the handle. In all,you could control much things if you had our wireless HB04Bx.

installation:
first you must install mach3 and then insert HB04Bx handle usb controller.then  install the
batteries to HB04Bx handle's cell box.
1.You should copy the ShuttlePro.dll to Mach3\plugins\ directroy;
2.M930.m1s is the probez file.You should copy the it to  Mach3\macros\Mach3Mill directroy;
3.M990.m1s is the ref all home file.You should copy the it to  Mach3\macros\Mach3Mill directroy;
4.m933 is go to zero work macro,You should copy the it to  Mach3\macros\Mach3Mill directroy;
5.you  could change the macro file M930.m1s ,M990.m1s, m933 to satisfy your cnc system;

It seems to indicate the designation after the B is not important to the operation.. W is for wireless and they are HB04Bx (either -4 or -6 as far as I know.. maybe there is a -3 as well)

I have no idea what the DLL could possibly be for though

James

Earlier message 17 lines
-----Original Message----- From: fpc-pascal On Behalf Of Marc Santhoff Sent: Sunday, August 18, 2019 9:12 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hi James, are you really sure the WHB04B-6 is exactly the same as your WHB04B-4 viewn to the USB API? If those thingys come with a dll, maybe you can compare the header files? If there is no header file you could ask the manufacturer for it. If they made a programm using that dll, there must be a header file. HTH somehow... -- Marc Santhoff

Reply by email

James Richters
to Stefan V. Pantazi: I do not get why should you stop the read thread, when that is the actual advantage of…

My concern was that I could not read and write at the exact same time....

Earlier message 17 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Sunday, August 18, 2019 9:32 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices >> My guess is that it would be better to leave the time sensitive read >> thread to do the fast reads and immediate calculations and leave >> writing to the device screen in a separate thread (even main thread), >> with a lower update frequency! > > Yes, that was what I was attempting to describe.. but I can't write to the usb device if the read thread happens to be in the middle of a read... so how do I pause the read thread at the correct time so it's not partially in the middle of reading a packet, and I can't read again until I'm done writing. I figure I can just check for some period of time of idle handwheel input before I stop the read thread and do the write then start the read thread again, because only the handwheel produces such a large stream of data.. but still I’m not sure how to make sure I stop it at the correct time. I do not get why should you stop the read thread, when that is the actual advantage of having multiple threads. While the read thread is busily reading input in a buffer/queue/what have you, you are free within limits) to do whatever you need to do (e.g., output to LCD display, do calculations) in the other threads, including the main thread, after which, you can get back to consuming and processing the (hopefully only slightly larger now) data from the read thread buffer/queue. After you figured writing to the LCD screen you could try writing random data to it while reading and processing handwheel and button input *at the same time*. Hope this makes sense.

Reply by email

Marc Santhoff
to Marc Santhoff: are you really sure the WHB04B-6 is exactly the same as your WHB04B-4 viewn to the USB…
Marc Santhoff wrote 8 lines
Hi James, are you really sure the WHB04B-6 is exactly the same as your WHB04B-4 viewn to the USB API? If those thingys come with a dll, maybe you can compare the header files? If there is no header file you could ask the manufacturer for it. If they made a programm using that dll, there must be a header file.

Oh, it's chinese - forget about getting any information.

Did you read there

https://github.com/rubienr/machinekit/tree/feature-xhc-whb04b-6/src/hal/user_comps/xhc-whb04b-6#findings

that the axis dial has to be switched on for the display to be updated?

Show quoted text 7 lines
HTH somehow... -- Marc Santhoff _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Marc Santhoff -- Marc Santhoff

Reply by email

James Richters
to Marc Santhoff

Yes, I did see that... it happens that before I found that page I had it on one of the axis anyway because if you switch it to off the handwheel gets disabled. I'm not sure why I am getting an IO error trying to send data to the device.. I'm not sure if it's Windows, or FPC, or the method I am trying to use.. etc.. I also don't have a lot of devices that even have a way to output anything to them... most are input devices. So I bought some usb-relays... those seem to have more documentation available, maybe I'll learn something when those come in. One thing that just confuses me is the first byte of data being sent as the report number.. I'm not sure I'm understanding that correctly, but it seems to be the only way it will

Oh, it's chinese - forget about getting any information. Did you read there https://github.com/rubienr/machinekit/tree/feature-xhc-whb04b-6/src/hal/user_comps/xhc-whb04b-6#findings that the axis dial has to be switched on for the display to be updated?

Reply by email

James Richters
to James Richters

I've been reading about libusb here:
https://www.cs.unm.edu/~hjelmn/libusb_hotplug_api/group__syncio.html

some things I just don't really understand, I'm hoping someone can explain:

The wValue, wIndex and wLength fields values should be given in host-endian byte order. What does host-endian byte order mean??

wLength
the length field for the setup packet. The data buffer should be at least this size.

What is this length supposed to be? I've been using the length of the data I'm trying to send... so trying to send 8 bytes, I made it 8... but maybe it's wanting some other length?

It seems to me that there would be little point in asking for this value if it was always just the length of the data field because the function could just get len(data) on it's own, so why bother passing something so obvious as a parameter... this leads me to wonder if this length needs to be something else?

James

Reply by email

Marc Santhoff
to James Richters
James Richters wrote
I've been reading about libusb here: https://www.cs.unm.edu/~hjelmn/libusb_hotplug_api/group__syncio.html some things I just don't really understand, I'm hoping someone can explain:

I can't help with the details, but these sites are very informative, especially the first one is nicely readable, the other has lots of details:

http://www.usbmadesimple.co.uk/index.html
https://www.beyondlogic.org/usbnutshell/usb1.shtml

Show quoted text 22 lines
The wValue, wIndex and wLength fields values should be given in host-endian byte order. What does host-endian byte order mean?? wLength the length field for the setup packet. The data buffer should be at least this size. What is this length supposed to be? I've been using the length of the data I'm trying to send... so trying to send 8 bytes, I made it 8... but maybe it's wanting some other length? It seems to me that there would be little point in asking for this value if it was always just the length of the data field because the function could just get len(data) on it's own, so why bother passing something so obvious as a parameter... this leads me to wonder if this length needs to be something else? James _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Marc Santhoff

Reply by email

Unknown author
to James Richters: I've been reading about libusb here: https://www.cs.unm.edu/~hjelmn/libusb_hotplug_api/gro…
James Richters wrote 7 lines
I've been reading about libusb here: https://www.cs.unm.edu/~hjelmn/libusb_hotplug_api/group__syncio.html some things I just don't really understand, I'm hoping someone can explain: The wValue, wIndex and wLength fields values should be given in host-endian byte order. What does host-endian byte order mean??

if your machine is little endian, then you set those values in little endian... if your machine is big endian, then you use that...

intel/amd PC systems are generally little endian...

https://en.wikipedia.org/wiki/Endianness

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list unless* *a signed and pre-paid contract is in effect with us.*

Reply by email

Johann Glaser
to James Richters: I just pushed it. Thanks Hansi

Hi!

James Richters wrote
I just pushed it.

Sorry for the delayed reply.

After comparing the exception stack trace you've sent (see below) and your code, the access violation happens at
https://github.com/Zaaphod/pas-libusb/blob/Hack/src/libusboop.pas#L1330 . The code dereferences the parameter AEndpoint.

Most probably it is however Nil, because the preceding FInterface.FindEndpoint(EP_IN) in
https://github.com/Zaaphod/pas-libusb/blob/Hack/src/examples/mydevice.pas#L143 didn't find that endpoint.

As I've written, TMyDevice is NOT a generic device! It is specific for EZ-USB chips. You really should create your own class descending from TLibUsbDevice (instead of TLibUsbDeviceWithFirmware).

In your constructor, you have to get a reference to the HID interface of your device, e.g., by
TLibUsbPseudoHIDInterface.Create(...)
analogous to
https://github.com/Zaaphod/pas-libusb/blob/Hack/src/examples/mydevice.pas#L141 .

This internally also gets references to the necessary endpoints, therefore you most probably don't need manual FInterface.FindEndpoint() (like TMyDevice).

Please see snapi.pas, which I've sent you on 2019-08-10. This does exactly that. I've sent this file specifically that you use it instead of mydevice.pas.

Bye
Hansi

Show quoted text 61 lines
> Could you please "git push" the source code to Github so that the > line numbers match the output? At least in line 1330 of > libusboop.pas there is no Create. Please ensure that the > version on Github is the very same version where you executed the > program and got the line numbers. Thanks Hansi > Running "i:\programming\pas- > libusb_test_dll\src\examples\testopendevic_vidpid2.exe " > 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 > N > P > L > H1 > I > I2 > Q > R > K > M > O1 > An unhandled exception occurred at $000000010002D0BB: > EAccessViolation: Access violation > $000000010002D0BB CREATE, line 1330 of libusboop.pas > $000000010002B3AB > $0000000100001942 main, line 75 of ../../pas- > libusb_test_dll/src/examples/testopendevic_vidpid2.pas > $0000000100001AF6 main, line 96 of ../../pas- > libusb_test_dll/src/examples/testopendevic_vidpid2.pas > $0000000100010040 > $00000001000017F0 > $00007FFB66D07E94 > $00007FFB675FA251 _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Johann Glaser

Oh, for some reason I wasn't thinking I was replacing mydevice.pas with snapi.pas... Ok.. so if I understand this correctly, make the changes necessary in snapi.pas to use libusboop.pas instead of the old usb.pas, and then use TSNAPIDevice.Create to create a TLIBUSBPseudoHIDInterface to my device? ... and that will allow me a more generic method to access the device?

James

Please see snapi.pas, which I've sent you on 2019-08-10. This does exactly that. I've sent this file specifically that you use it instead of mydevice.pas.

Reply by email

James Richters
to James Richters

I'm trying to get this to work with libusboop.pas but I'm getting a compiler error I don't really know how to fix:

157  Constructor TSNAPIDevice.Create(idVendor, idProduct: LongInt; AConfig, AInterface, AAltInterface: LongInt);
158  Var Intf : Plibusb_interface_descriptor;
159  Begin
160    inherited Create(idVendor,idProduct,AConfig);
161    { create USB interface }
162    Intf := TLibUsbDevice.FindInterface(AInterface,AAltInterface,FDevice); { better: search for iInterface = "SNAPI Command Interface" }
163    FSNAPICommandInterface := TLIBUSBPseudoHIDInterface.Create(Self,Intf);
164    FSNAPICommandInterface.OnIntrReport := @IntrReport;
165  End;
First compilation of i:\programming\pas-libusb_test_dll\src\examples\snapi.pas
snapi.pas(160,28) Error: Incompatible type for arg no. 1: Got "LongInt", expected "TLibUsbContext"
snapi.pas(162,72) Error: Wrong number of parameters specified for call to "FindInterface"
libusboop.pas(911,24) Error: Found declaration: FindInterface(TLibUsbInterfaceMatchMethod):^libusb_interface_descriptor;
libusboop.pas(943,24) Error: Found declaration: FindInterface(TLibUsbInterfaceMatchClass;Boolean=`TRUE`):^libusb_interface_descriptor;
libusboop.pas(958,24) Error: Found declaration: FindInterface(TLibUsbInterfaceMatchFunc;Pointer):^libusb_interface_descriptor;
libusboop.pas(981,24) Error: Found declaration: FindInterface(Byte;Byte):^libusb_interface_descriptor;
libusboop.pas(991,24) Error: Found declaration: FindInterface:^libusb_interface_descriptor;
snapi.pas(432) Fatal: There were 7 errors compiling module, stopping
snapi.pas(0) Fatal: Compilation aborted

I've put my attempt on my repository in the TEST branch here: https://github.com/Zaaphod/pas-libusb/blob/Test/src/examples/snapi.pas

I don't really understand how this inherited stuff and constructors and all that works.. but I figure if I get snapi.pas to compile correctly with libusboop.pas then I will have an example of how to create the TLIBUSBPseudoHIDInterface for my device... but maybe I need to do it completely differently than this? Sorry I'm so confused.

James

Reply by email

James Richters
to James Richters

I FINALLY wrote some data to the LCD!! YAY !!! I was trying to get the python application to work.. without any luck.. but I ended up going ahead and trying Zadig changing the driver to libusb-win32... After I gave up on Python, I went back to FPC and just ran my existing sample program, and I noticed where it used have an error sending to device, it now said 8 bytes sent!! It's very strange I could read it just fine but not write to it without messing with the driver... but it's working now!

I tried suspending the read thread to write to it.. and well it must have ended up suspending in the middle of a read because the whole thing locked up.. so I just tried as suggested and let it keep reading in a tight loop in it's own thread and then just throw in a write every few seconds on the main program.. and that actually worked fine.. I guess libusb takes care of worry about finishing a read before writing.. I think I did see libusb had something to do with threads.

So now it's just a matter of small details. The display is a little odd... in that instead of sending it just a real number, you send it an integer for the numbers before the decimal and another integer for the numbers after the decimal.. but it's 2 bytes for each (4 bytes total) but they are in reverse order.. I need to send LowByte_Integer, High_Byte_Integer, LowByte_decimal, High_Byte_decimal so the bits from a 16 bit integer end up being 76543210,FEDCBA98 I think this is that edian byte order thing that was mentioned. I'm just curious if there is already a function available to reverse these like this.. or if I just need to write my own. It's just some rotates and then split it, so I can do that, but I'm just wondering if there is something already there to do this.. I seem to recall that this kind of thing needs to happen quite a bit.

Also I need to stick a $06 in front of all my packets to send to the device.  I have my data all in arrays,  so I want to do something like this
Device_Array[0]:=$06;
Device_Array[1..7] := LCD_Array[0..6] ;

Ah.. but that doesn't work.. is there a way to do this with syntax or do I just need to make a loop to copy the array elements the way they need to be?

James

Reply by email

Stefan V. Pantazi
to James Richters
James Richters wrote
I FINALLY wrote some data to the LCD!! YAY !!! I was trying to get the python application to work.. without any luck.. but I ended up going ahead and trying Zadig changing the driver to

Persistence pays off. Congrats!

Also I need to stick a $06 in front of all my packets to send to the device. I have my data all in arrays, so I want to do something like this Device_Array[0]:=$06; Device_Array[1..7] := LCD_Array[0..6] ;

Try Move (https://www.freepascal.org/docs-html/rtl/system/move.html)

Move(LCD_Array[0..6],Device_Array[1],7)

Reply by email

James Richters
to James Richters: I FINALLY wrote some data to the LCD!! YAY !!! I was trying to get the python…

Well.. It doesn’t always work just reading constantly and writing in a different thread..

So I have my fast read loop always reading then my LCD write loop sending the 3 packets every 0.3 Seconds.. and it functions ok, and I don’t miss too many counts... but every so often I get this message: libusb: warning [handle_timeout] async cancel failed -5 errno=0

I have a timeout on my read loop of 10ms. I tried setting that to 0 so it would just wait for input in it's thread.. but when I do that I get this as soon as I attempt to write to it: An unhandled exception occurred at $00007FFF189F03C6: EAccessViolation: Access violation
$00007FFF189F03C6
$00007FFF189EDA21
$00007FFF17AAA1A1
$00007FFF17AA9CB5
$000000006B607FFB
$000000006B6081E7
$000000006B60C695
$000000006B605D6F
$000000006B607E40
$000000010001B1CA
$00000001000021BF main, line 445 of whb04b-4_test.pas $00000001000022B6
$000000010000EC20
$0000000100001880
$00007FFF17B47E94
$00007FFF18A4A251

Also if I put in a really long timeout like 1000ms I get that.  Line 445 is
libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet1 );

so I can't write while I'm reading or waiting for a read after all.

So I came up with a scheme to set all the variables in the slow loop then set a Boolean variable when it's done.. then the fast loop checks for the flag if it is idle for a time, meaning it's not trying to keep up with input.. and that does work.. and I don't miss many counts... but it does miss a few... but I STILL get this libusb: warning [handle_timeout] async cancel failed -5 errno=0

even though as far as I can tell, I can't possible be reading and writing at the same time.

I've updated my test project here: https://github.com/Zaaphod/libusbxhid/blob/master/WHB04B-4_test.pas

I don't really know what libusb: warning [handle_timeout] async cancel failed -5 errno=0 is trying to tell me... it is having an issue canceling waiting for data after the time out I guess.. but why is that a problem?

Any Ideas?

James

Earlier message 17 lines
-----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Wednesday, August 21, 2019 8:30 AM To: 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices I FINALLY wrote some data to the LCD!! YAY !!! I was trying to get the python application to work.. without any luck.. but I ended up going ahead and trying Zadig changing the driver to libusb-win32... After I gave up on Python, I went back to FPC and just ran my existing sample program, and I noticed where it used have an error sending to device, it now said 8 bytes sent!! It's very strange I could read it just fine but not write to it without messing with the driver... but it's working now! I tried suspending the read thread to write to it.. and well it must have ended up suspending in the middle of a read because the whole thing locked up.. so I just tried as suggested and let it keep reading in a tight loop in it's own thread and then just throw in a write every few seconds on the main program.. and that actually worked fine.. I guess libusb takes care of worry about finishing a read before writing.. I think I did see libusb had something to do with threads. So now it's just a matter of small details. The display is a little odd... in that instead of sending it just a real number, you send it an integer for the numbers before the decimal and another integer for the numbers after the decimal.. but it's 2 bytes for each (4 bytes total) but they are in reverse order.. I need to send LowByte_Integer, High_Byte_Integer, LowByte_decimal, High_Byte_decimal so the bits from a 16 bit integer end up being 76543210,FEDCBA98 I think this is that edian byte order thing that was mentioned. I'm just curious if there is already a function available to reverse these like this.. or if I just need to write my own. It's just some rotates and then split it, so I can do that, but I'm just wondering if there is something already there to do this.. I seem to recall that this kind of thing needs to happen quite a bit. Also I need to stick a $06 in front of all my packets to send to the device. I have my data all in arrays, so I want to do something like this Device_Array[0]:=$06; Device_Array[1..7] := LCD_Array[0..6] ; Ah.. but that doesn't work.. is there a way to do this with syntax or do I just need to make a loop to copy the array elements the way they need to be? James

Reply by email

Johann Glaser
to James Richters: Oh, for some reason I wasn't thinking I was replacing mydevice.pas with snapi.pas... …

Hi!

James Richters wrote 7 lines
Oh, for some reason I wasn't thinking I was replacing mydevice.pas with snapi.pas... Ok.. so if I understand this correctly, make the changes necessary in snapi.pas to use libusboop.pas instead of the old usb.pas, and then use TSNAPIDevice.Create to create a TLIBUSBPseudoHIDInterface to my device? ... and that will allow me a more generic method to access the device?

Hmm, no. You should make your own unit for your device, from scratch. And then use snapi.pas as a guide how to do that. As I've written in my previous EMail:

--- schnipp ---
You really should create your own class descending from TLibUsbDevice (instead of TLibUsbDeviceWithFirmware).

In your constructor, you have to get a reference to the HID interface of your device, e.g., by
TLibUsbPseudoHIDInterface.Create(...)
analogous to
https://github.com/Zaaphod/pas-libusb/blob/Hack/src/examples/mydevice.pas#L141 .

This internally also gets references to the necessary endpoints, therefore you most probably don't need manual FInterface.FindEndpoint() (like TMyDevice).

--- schnapp ---

But please pay attention to the new methods, parameters, ...

Bye
Hansi

Reply by email

James Richters
to Johann Glaser

Hmm I'll see what I can come up with. The language of all these units is completely foreign to me. I really don't understand how constructors and this inherited stuff or how even the functions and procedures manage to get anything done. I've been programming with Pascal since Turbo Pascal back in the 80's but I can't make any sense of this coding 'll have to do some research to see how this method of programing even 've done some stuff that uses units like this, so I can create and object and manage to use it, but the unit's themselves... well. I just don't get it. I keep going around in circles trying to follow the way things get done and it seems like I go round and round and never find any functions or procedures that really do anything at all.. they just keep calling each other. I was trying to just compile Snapi.pas with libusboop just to figure out the syntax.. then I can copy sections and modify it as needed.

James

Hmm, no. You should make your own unit for your device, from scratch. And then use snapi.pas as a guide how to do that. As I've written in my previous EMail:

Reply by email

Stefan V. Pantazi
to James Richters: Well.. It doesn’t always work just reading constantly and writing in a different…

From your example it looks like you placed the device reading (interrupt read) and writing (set report) into the same read thread. I thought keeping them separate was a good idea: tight loop reads and less frequent writes (LCD updates).

Libusb is supposed to be thread-safe. Not really an issue for your app but if you need to make sure only one thread out of multiple threads is processing libusb events the library has asynchronous API that does offer locking functionality.

James Richters wrote 66 lines
Well.. It doesn’t always work just reading constantly and writing in a different thread.. So I have my fast read loop always reading then my LCD write loop sending the 3 packets every 0.3 Seconds.. and it functions ok, and I don’t miss too many counts... but every so often I get this message: libusb: warning [handle_timeout] async cancel failed -5 errno=0 I have a timeout on my read loop of 10ms. I tried setting that to 0 so it would just wait for input in it's thread.. but when I do that I get this as soon as I attempt to write to it: An unhandled exception occurred at $00007FFF189F03C6: EAccessViolation: Access violation $00007FFF189F03C6 $00007FFF189EDA21 $00007FFF17AAA1A1 $00007FFF17AA9CB5 $000000006B607FFB $000000006B6081E7 $000000006B60C695 $000000006B605D6F $000000006B607E40 $000000010001B1CA $00000001000021BF main, line 445 of whb04b-4_test.pas $00000001000022B6 $000000010000EC20 $0000000100001880 $00007FFF17B47E94 $00007FFF18A4A251 Also if I put in a really long timeout like 1000ms I get that. Line 445 is libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet1 ); so I can't write while I'm reading or waiting for a read after all. So I came up with a scheme to set all the variables in the slow loop then set a Boolean variable when it's done.. then the fast loop checks for the flag if it is idle for a time, meaning it's not trying to keep up with input.. and that does work.. and I don't miss many counts... but it does miss a few... but I STILL get this libusb: warning [handle_timeout] async cancel failed -5 errno=0 even though as far as I can tell, I can't possible be reading and writing at the same time. I've updated my test project here: https://github.com/Zaaphod/libusbxhid/blob/master/WHB04B-4_test.pas I don't really know what libusb: warning [handle_timeout] async cancel failed -5 errno=0 is trying to tell me... it is having an issue canceling waiting for data after the time out I guess.. but why is that a problem? Any Ideas? James -----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Wednesday, August 21, 2019 8:30 AM To: 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices I FINALLY wrote some data to the LCD!! YAY !!! I was trying to get the python application to work.. without any luck.. but I ended up going ahead and trying Zadig changing the driver to libusb-win32... After I gave up on Python, I went back to FPC and just ran my existing sample program, and I noticed where it used have an error sending to device, it now said 8 bytes sent!! It's very strange I could read it just fine but not write to it without messing with the driver... but it's working now! I tried suspending the read thread to write to it.. and well it must have ended up suspending in the middle of a read because the whole thing locked up.. so I just tried as suggested and let it keep reading in a tight loop in it's own thread and then just throw in a write every few seconds on the main program.. and that actually worked fine.. I guess libusb takes care of worry about finishing a read before writing.. I think I did see libusb had something to do with threads. So now it's just a matter of small details. The display is a little odd... in that instead of sending it just a real number, you send it an integer for the numbers before the decimal and another integer for the numbers after the decimal.. but it's 2 bytes for each (4 bytes total) but they are in reverse order.. I need to send LowByte_Integer, High_Byte_Integer, LowByte_decimal, High_Byte_decimal so the bits from a 16 bit integer end up being 76543210,FEDCBA98 I think this is that edian byte order thing that was mentioned. I'm just curious if there is already a function available to reverse these like this.. or if I just need to write my own. It's just some rotates and then split it, so I can do that, but I'm just wondering if there is something already there to do this.. I seem to recall that this kind of thing needs to happen quite a bit. Also I need to stick a $06 in front of all my packets to send to the device. I have my data all in arrays, so I want to do something like this Device_Array[0]:=$06; Device_Array[1..7] := LCD_Array[0..6] ; Ah.. but that doesn't work.. is there a way to do this with syntax or do I just need to make a loop to copy the array elements the way they need to be? James _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi

I had them separated, but whenever it happened that I tried to write while it was waiting to read, I would get the error below. If it was reading all the time it seemed fine.. just if it was idle waiting to read and I did a write that it would fail with EAccessViolation: Access violation

I put them in the same thread but only allow writes when it's been idle for a few timeouts.. the only time I need to read the port like crazy if I spin the hand wheel really fast. I also use the slow main program to only tell the fast read thread that data is available to write at a pretty slow rate. I think this could be improved.. I just don't know how to us this locking system you mention. If I can lock it from reading when I try to write or to properly interrupt the read if it is just sitting there waiting for data that would be better.

The device only answers the read request when it has something to send, so it will sit there for hours just waiting if no one gives it any input.. but I want to update the display all the time... all the time that it's turned on anyway... so that's the issue I'm facing. Whenever I try to write when the device is idle.. it blows up.. probably because I did not finish the read and lock reading. Anyway what I have now can't read and write at the same time.. I am using a timeout to stop trying to read.. and then if I get enough time outs in a row, I figure I'm not too busy reading, so I send out the write.. but if I blast it with data (turn the wheel super fast for a long time) then it never tries to write because I never time out.. so the display doesn't change.. but that's ok.. it corrects itself when I stop the crazy input. 99% of the time. The wheel will be turned slowly.. just once in a while the user might want to move a large distance with it and whirl it around really fast.

I thought I saw something about sending a request to read.. then doing something else for a while and getting a call back when it's got something there.. maybe that's something like asynchronous? I think if I can figure that out it would solve the problem (maybe) of wanting to write something while I wait for input. I'm thinking if I don't use a timeout like I am now, I wouldn't get libusb: warning [handle_timeout] async cancel failed -5 errno=0 ... I wonder if that is a know issue and the reason why the timout was originally set to zero in the interrupt read function...

Still all in all, I'm pretty happy with it! I do still miss like 2 pulses out of 800.. so not a super huge deal, but room for improvement... if I use the library the proper way, it will probably help.

I'm wondering there is something in threads that I can set to make my fast read thread always run faster than the others.. some kind of priority or percentage?? Or do I just have to put enough delays with Sleep() commands to slow everything else down...

James

Earlier message 89 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Wednesday, August 21, 2019 5:31 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices From your example it looks like you placed the device reading (interrupt read) and writing (set report) into the same read thread. I thought keeping them separate was a good idea: tight loop reads and less frequent writes (LCD updates). Libusb is supposed to be thread-safe. Not really an issue for your app but if you need to make sure only one thread out of multiple threads is processing libusb events the library has asynchronous API that does offer locking functionality. On 8/21/19 3:48 PM, James Richters wrote: > Well.. It doesn’t always work just reading constantly and writing in a different thread.. > > So I have my fast read loop always reading then my LCD write loop sending the 3 packets every 0.3 Seconds.. and it functions ok, and I don’t miss too many counts... but every so often I get this message: > libusb: warning [handle_timeout] async cancel failed -5 errno=0 > > I have a timeout on my read loop of 10ms. I tried setting that to 0 so it would just wait for input in it's thread.. but when I do that I get this as soon as I attempt to write to it: > An unhandled exception occurred at $00007FFF189F03C6: > EAccessViolation: Access violation > $00007FFF189F03C6 > $00007FFF189EDA21 > $00007FFF17AAA1A1 > $00007FFF17AA9CB5 > $000000006B607FFB > $000000006B6081E7 > $000000006B60C695 > $000000006B605D6F > $000000006B607E40 > $000000010001B1CA > $00000001000021BF main, line 445 of whb04b-4_test.pas > $00000001000022B6 > $000000010000EC20 > $0000000100001880 > $00007FFF17B47E94 > $00007FFF18A4A251 > > Also if I put in a really long timeout like 1000ms I get that. Line > 445 is libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, > $6 , 8 , WhB04_Packet1 ); > > so I can't write while I'm reading or waiting for a read after all. > > So I came up with a scheme to set all the variables in the slow loop > then set a Boolean variable when it's done.. then the fast loop checks > for the flag if it is idle for a time, meaning it's not trying to keep > up with input.. and that does work.. and I don't miss many counts... > but it does miss a few... but I STILL get this > libusb: warning [handle_timeout] async cancel failed -5 errno=0 > > even though as far as I can tell, I can't possible be reading and writing at the same time. > > I've updated my test project here: > https://github.com/Zaaphod/libusbxhid/blob/master/WHB04B-4_test.pas > > I don't really know what libusb: warning [handle_timeout] async cancel failed -5 errno=0 is trying to tell me... it is having an issue canceling waiting for data after the time out I guess.. but why is that a problem? > > Any Ideas? > > James > > -----Original Message----- > From: fpc-pascal On Behalf > Of James Richters > Sent: Wednesday, August 21, 2019 8:30 AM > To: 'FPC-Pascal users discussions' > Subject: Re: [fpc-pascal] USB Human Interface Devices > > I FINALLY wrote some data to the LCD!! YAY !!! I was trying to get the python application to work.. without any luck.. but I ended up going ahead and trying Zadig changing the driver to libusb-win32... After I gave up on Python, I went back to FPC and just ran my existing sample program, and I noticed where it used have an error sending to device, it now said 8 bytes sent!! It's very strange I could read it just fine but not write to it without messing with the driver... but it's working now! > > I tried suspending the read thread to write to it.. and well it must have ended up suspending in the middle of a read because the whole thing locked up.. so I just tried as suggested and let it keep reading in a tight loop in it's own thread and then just throw in a write every few seconds on the main program.. and that actually worked fine.. I guess libusb takes care of worry about finishing a read before writing.. I think I did see libusb had something to do with threads. > > So now it's just a matter of small details. The display is a little odd... in that instead of sending it just a real number, you send it an integer for the numbers before the decimal and another integer for the numbers after the decimal.. but it's 2 bytes for each (4 bytes total) but they are in reverse order.. I need to send LowByte_Integer, High_Byte_Integer, LowByte_decimal, High_Byte_decimal so the bits from a 16 bit integer end up being 76543210,FEDCBA98 I think this is that edian byte order thing that was mentioned. I'm just curious if there is already a function available to reverse these like this.. or if I just need to write my own. It's just some rotates and then split it, so I can do that, but I'm just wondering if there is something already there to do this.. I seem to recall that this kind of thing needs to happen quite a bit. > > Also I need to stick a $06 in front of all my packets to send to the > device. I have my data all in arrays, so I want to do something like > this Device_Array[0]:=$06; Device_Array[1..7] := LCD_Array[0..6] ; > > Ah.. but that doesn't work.. is there a way to do this with syntax or do I just need to make a loop to copy the array elements the way they need to be? > > James > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > --

Reply by email

Stefan V. Pantazi
to James Richters
James Richters wrote
I had them separated, but whenever it happened that I tried to write while it was waiting to read, I would get the error below. If it was reading all the time it seemed fine.. just if it was idle waiting to read and I did a write that it would fail with EAccessViolation: Access violation

That should not happen - out of curiosity I modified a graphic tablet test program and included:
- a separate read thread with a timeout of 1 second and
- in the main thread, one set feature report call followed by a get feature report call (every 1 second).

This was the behaviour:
1) if there is no input:
- the main thread keeps calling set report +get report every 1 second
- in the read thread, the interrupt read times out every second but generates report data every 5 seconds (tablet generates an interrupt read even if there is no input - a sort of heartbeat);

2) if there is input (pen approaches tablet or writes on tablet) there is a flurry of data from the read thread and of course, no more interrupt read timeouts; the main thread is business as usual, setting and getting feature reports every second; see the attached debug log

Note that the interrupt read report size is specific to the device (10 bytes for the tablet); is the length for your device correct?

Reply by email

James Richters
to Stefan V. Pantazi

That sounds like exactly like what I was trying to do.. would you mind sending me your graphic tablet test? Maybe I can learn something from seeing how you do things.

I just noticed I am always getting :
device attempting go clear halt on ep $81
libusb: error [winusbx_clear_halt] unable to match endpoint to an open interface - cannot clear clear halt failed
it seems to work fine.. but I always get that error.. not sure where that is coming from, or if that might be related to these other issues.

Since it's working for you, I thought I would give it another try.. I made a TEST branch on my repository here: https://github.com/Zaaphod/libusbxhid/blob/Test/WHB04B-4_test.pas

This goes back to having the read thread do the reading, and the writing happening in the main thread much slower. I have come up with three different schemes for writing... all with mixed results... or maybe the same results but they just happened to show up randomly at different times. Most of the time it's failing on the write, but sometimes it's on there read.. and sometimes I get non fatal warnings: libusb: warning [handle_timeout] async cancel failed -5 errno=0. When I got done putting the details below, I tried to go back to the configuration that seemed to work the best.. but now it is failing as well.. I think I just have something fundamentally wrong, or maybe it's something to do with windows? It's just not behaving the way you describe.

Here are the details:

First I tried writing the data like this:
            Sleep(300);
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet1 );
            Sleep(300);
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet2 );
            Sleep(300);
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet3 );
the device doesn't seem to mind the delay between packets... packet 1 has 2 specific bytes that identify it as packet1..

With the timeout set to zero, if I leave it alone for a few seconds, I get An unhandled exception occurred at $00007FFF189F03C6: EAccessViolation: Access violation
$00007FFF189F03C6
.. .. ..
$000000010001B1FA LIBUSBHID_SET_REPORT, line 149 of libusbhid.pas $000000010000222A main, line 421 of whb04b-4_test.pas Which is part of ALL this:
https://pastebin.com/u99f3a0p
line 421 is libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet2 );

with a timeout of any sort... last test was 50, at least it doesn't have a fatal error, but I get messages like this every once in a while: libusb: warning [handle_timeout] async cancel failed -5 errno=0

They don't seem to hurt anything.. but I'm not sure if I am missing a read packet or not...

So I tried writing out the data like this:

               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet1 );
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet2 );
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet3 );
               Sleep(1000);

With a timeout of 0 or timeout of 50 I got this:
An unhandled exception occurred at $00007FFF189F03C6: EAccessViolation: Access violation
$00007FFF189F03C6
.. .. ..
$000000010001B1EA LIBUSBHID_SET_REPORT, line 149 of libusbhid.pas $000000010000222A main, line 421 of whb04b-4_test.pas Which is part of all this (not as much as above but basically the same error): https://pastebin.com/KY6X3xmR

            Sleep(100);
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet1 );
            Sleep(100);
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet2 );
            Sleep(100);
               libusbhid_set_report(device_context, HID_REPORT_TYPE_FEATURE, $6 , 8 , WhB04_Packet3 );
            Sleep(1000);

Now I get this:
An unhandled exception occurred at $00007FFF189F4D1B: EAccessViolation: Access violation
$00007FFF189F4D1B
.. .. ..
$000000010001B366 LIBUSBHID_INTERRUPT_READ, line 170 of libusbhid.pas $00000001000018FB READUSBPORT, line 273 of whb04b-4_test.pas https://pastebin.com/VTqFyAiB

Line 273 is: hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}50);

It seems no matter what I do... even write out dummy data so I'm not even using the same variables I am reading at all.. I either get a fatal error on read, a fatal error on write, or occasional libusb: warning [handle_timeout] async cancel failed -5 errno=0 messages.

James

Earlier message 27 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Wednesday, August 21, 2019 10:20 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices On 8/21/19 6:35 PM, James Richters wrote: > I had them separated, but whenever it happened that I tried to write > while it was waiting to read, I would get the error below. If it was > reading all the time it seemed fine.. just if it was idle waiting to > read and I did a write that it would fail with EAccessViolation: > Access violation That should not happen - out of curiosity I modified a graphic tablet test program and included: - a separate read thread with a timeout of 1 second and - in the main thread, one set feature report call followed by a get feature report call (every 1 second). This was the behaviour: 1) if there is no input: - the main thread keeps calling set report +get report every 1 second - in the read thread, the interrupt read times out every second but generates report data every 5 seconds (tablet generates an interrupt read even if there is no input - a sort of heartbeat); 2) if there is input (pen approaches tablet or writes on tablet) there is a flurry of data from the read thread and of course, no more interrupt read timeouts; the main thread is business as usual, setting and getting feature reports every second; see the attached debug log Note that the interrupt read report size is specific to the device (10 bytes for the tablet); is the length for your device correct?

Reply by email

Stefan V. Pantazi
to James Richters

I added libusbhid_test_with_thread.pp to github. In that test you will notice I also attempted to test sharing across threads a data structure with (hypothetical) pen positions, using critical sections. Seems to work ok, but more testing is needed to make sure there are no problems.

The way I see this working in your particular context, would be that the shared data structure would be written to/updated in the read thread and read less frequently in the main thread in order to update the display.

James Richters wrote
That sounds like exactly like what I was trying to do.. would you mind sending me your graphic tablet test? Maybe I can learn something from seeing how you do things. clear halt failed it seems to work fine.. but I always get that error.. not sure where that is coming from, or if that might be related to these other issues.

That error message is fine. It is an attempt to revive an USB endpoint that has stalled, just in case. If your devices are behaving, then you may even skip that attempt in the open function call.

It seems no matter what I do... even write out dummy data so I'm not even using the same variables I am reading at all.. I either get a fatal error on read, a fatal error on write, or occasional libusb: warning [handle_timeout] async cancel failed -5 errno=0 messages.

-5 is LIBUSB_ERROR_NOT_FOUND - this may give a clue

http://libusb.sourceforge.net/api-1.0/group__asyncio.html#ga685eb7731f9a0593f75beb99727bbe54

As to why your transfers are being canceled, I have no idea. Anyway, keep in mind that I am using Linux and a completely different USB device
- so libusb implementations, OS and device differences may play a role in how the programs behave.

Reply by email

James Richters
to Stefan V. Pantazi
I added libusbhid_test_with_thread.pp to github. In that test you will notice I also attempted to test sharing across threads a data structure with (hypothetical) pen positions, using critical sections. Seems to work ok, but more testing is needed to make sure there are no problems.

Thank you, I'll have a look!

The way I see this working in your particular context, would be that the shared data structure would be written to/updated in the read thread and read less frequently in the main thread in order to update the display.

Yes, that's the way I see it too.. data would be updated every cycle in the read thread, but only accessed by the main thread just before a display update, which would be much slower.

I only ever get that message if timeout is not 0... so it's the timeout's way of stopping things.

I suspect when the timeout time has been reached interrupt_read is calling libusb_cancel_transfer to stop waiting for the transfer. It seems likely that what's happening is that once in a while it tries to cancel the transfer, but before libusb_cancel_transfer has a chance to cancel it, some data comes in real quick and now it's done and there is nothing to cancel.. that would explain why it happens only intermittently.. it just has to happen that some data comes in at almost the exact same time as the timeout time.

Since this error is generated by: LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress, already complete, or already cancelled. And nothing else could have cancelled it except the timeout, and the timeout would not have been issued if the transfer was in progress.. that leaves that the transfer popped in real quick and completed before the timeout was done calling for a cancel transfer.

So the question is... did I end up loosing the packet? If this is what's happening... and interrupt_read timed out.. but then data came in before the timeout was complete.. does interrupt_read discard that data because it timed out so no point in doing anything with it.. or does it store the data if it comes in before LIBUSB_TRANSFER_CANCELLED is received.

Perhaps Linux is faster at getting the transfer finished than windows.. maybe windows has some buffer thing going on or? But yes it could be an OS difference.

Reply by email

Stefan V. Pantazi
to James Richters
I suspect when the timeout time has been reached interrupt_read is calling libusb_cancel_transfer to stop waiting for the transfer. It seems likely that what's happening is that once in a while it tries to cancel the transfer, but before libusb_cancel_transfer has a chance to cancel it, some data comes in real quick and now it's done and there is nothing to cancel.. that would explain why it happens only intermittently.. it just has to happen that some data comes in at almost the exact same time as the timeout time. Since this error is generated by: LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress, already complete, or already cancelled. And nothing else could have cancelled it except the timeout, and the timeout would not have been issued if the transfer was in progress.. that leaves that the transfer popped in real quick and completed before the timeout was done calling for a cancel transfer.

Here is something you can try immediately. How about setting the timeout on interrupt read to some ridiculously larger value, say 20 seconds to see if the error happens less frequently. Of course, when you close the program you may have to wait up to 20 seconds for the read thread to finish.

Reply by email

James Richters
to Stefan V. Pantazi

Yes if I set it to zero so it never times out, it never happens.. but then I have the crash when I try to write. The same thing happened if I set it to 20 seconds... but I can only find out about it if I disable the write... if I put the write in the read loop thread, then I have to have the timeout or I can never write without input. It doesn't happen for EVERY timeout.. just occasionally.. I'm pretty sure it only happens if input happens to come in coincidentally with the between the time the timeout is issued and the time the read is actually stopped. You would think the chances of the timeout happening to start just a few machine cycles before some data came in and completed the read would be unlikely.. but this seems to come quite often. I can solve the timeout error by setting the timeout to 0 and only doing reads in the read loop... but I'll have to solve the crashing when writing while waiting for a read problem to do that.

I'm curious if there is a mode available where I can set it to 'always try to read data and jump to this procedure when there is some' so I don't have to keep starting and stopping a read request... kind of a request to read constantly? Where I get things set up and everytime data comes in, my read thread gets activated and my variables populated... or maybe the best solution is to find out why it's crashing when I try to write while the wait for read is happening.

James

Here is something you can try immediately. How about setting the timeout on interrupt read to some ridiculously larger value, say 20 seconds to see if the error happens less frequently. Of course, when you close the program you may have to wait up to 20 seconds for the read thread to finish.

Reply by email

James Richters
to Stefan V. Pantazi: Here is something you can try immediately. How about setting the timeout on interrupt…

Stefan ,
Do you get the following errors when you exit your program? Is there some way I should shut down the read thread so I don't get this error? I've been using a timeout of 0

libusb: error [do_close] Device handle closed while transfer was still being processed, but the device is still connected as far as we know libusb: error [do_close] A cancellation hasn't even been scheduled on the transfer for which the device is closing libusb: warning [libusb_exit] some libusb_devices were leaked Assertion failed!

Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe File: os/poll_windows.c, Line 145

Expression: fd != NULL
Heap dump by heaptrc unit of i:\programming\gcode\libusbxhid\whb04b-4_test.exe 50 memory blocks allocated : 1782/1968
50 memory blocks freed : 1782/1968
0 unfreed memory blocks : 0
True heap size : 131072 (160 used in System startup) True free heap : 130912

Reply by email

Stefan V. Pantazi
to James Richters

Thanks for pushing on this. I think any pending timeout/transfer must be explicitly canceled before closing the USB device, so that the thread can end gracefully.

The only way I see is to use something like

libusb_handle_events_timeout_completed

http://libusb.sourceforge.net/api-1.0/group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b

before closing the USB device context.

That function is not currently part of the libusbx and has a time_t parameter that appears C-specific but for some reason is not included in ctypes unit. But I am sure Pascal equivalents can be defined. I will do some tests to include the libusb_handle_events_timeout_completed in libusbx and libusbhid and let you know.

James Richters wrote 23 lines
Stefan , Do you get the following errors when you exit your program? Is there some way I should shut down the read thread so I don't get this error? I've been using a timeout of 0 libusb: error [do_close] Device handle closed while transfer was still being processed, but the device is still connected as far as we know libusb: error [do_close] A cancellation hasn't even been scheduled on the transfer for which the device is closing libusb: warning [libusb_exit] some libusb_devices were leaked Assertion failed! Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe File: os/poll_windows.c, Line 145 Expression: fd != NULL Heap dump by heaptrc unit of i:\programming\gcode\libusbxhid\whb04b-4_test.exe 50 memory blocks allocated : 1782/1968 50 memory blocks freed : 1782/1968 0 unfreed memory blocks : 0 True heap size : 131072 (160 used in System startup) True free heap : 130912 _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi

I finally have this working fairly well. I used Stefan's sample program as a guide and used classes to define my thread... and that seemed to solve the crashing issue I was having when trying to write to the LCD from outside the fast read thread. Here is the current version: https://github.com/Zaaphod/libusbxhid/blob/Test/WHB04B-4_test.pas

One thing I wasn't able to duplicate however was the use of EnterCriticalsection(criticalSection); and LeaveCriticalsection(criticalSection); when writing to shared variables. If I try to ever use EnterCriticalsection(criticalSection); in the read thread, My program just instantly locks up and I can't even break out of it. If I try to use it in the main program I instantly get EAccessViolation: Access violation
$00007FFF18A2DF23
$00007FFF189E9BBC
$00007FFF189E9AD0
$000000010000DCDA
$000000010000D54B
$000000010000218B PROCESS_USB_DATA, line 475 of WHB04B-4_test.pas $0000000100002B37 SIMPLETERMINAL, line 641 of WHB04B-4_test.pas $0000000100002DDD USE_MPG_DEVICE, line 675 of WHB04B-4_test.pas $0000000100002F93 main, line 699 of WHB04B-4_test.pas $0000000100002FE6
$0000000100011350
$0000000100001980
$00007FFF17B47E94
$00007FFF18A4A251
Line 475 is EnterCriticalsection(criticalSection); I left where I had the criticalsection stuff in the program but commented out. It does seem to work fine without it though.. since the read, I am curious what I'm doing wrong, or if I need to do something else because I'm on Windows.

Also, there are two versions of this device, once is hard wired to the USB port, the other is wireless. They both have power buttons on them. When I turn off the power button on the wireless version, the transceiver still plugged into the USB port just reports that the device is turned off.. but the hard wired version just basically unplugs it from the USB port. When this happens, my read loop generates:

libusbhid_interrupt_read. failed! return code: -1
0libusb: error [winusbx_submit_bulk_transfer] ReadPipe/WritePipe failed: [2] The system cannot find the file specified.

But I don't really know how I can detect this and exit the process and signal my other program that the device is no longer present. My read command:

      hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}50);

only reports the number of bytes read, and when the device is removed, the result of the libusbhid_interrupt_read seems to be 64. I’m wondering what the proper way to gracefully detect the device has been disconnected is so I can just exit out of the mode the uses the device and return to normal processing without generating any errors.

Any ideas?

James

Earlier message 49 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Friday, August 23, 2019 10:54 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Thanks for pushing on this. I think any pending timeout/transfer must be explicitly canceled before closing the USB device, so that the thread can end gracefully. The only way I see is to use something like libusb_handle_events_timeout_completed http://libusb.sourceforge.net/api-1.0/group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b before closing the USB device context. That function is not currently part of the libusbx and has a time_t parameter that appears C-specific but for some reason is not included in ctypes unit. But I am sure Pascal equivalents can be defined. I will do some tests to include the libusb_handle_events_timeout_completed in libusbx and libusbhid and let you know. On 8/23/19 7:07 AM, James Richters wrote: > Stefan , > Do you get the following errors when you exit your program? Is there some way I should shut down the read thread so I don't get this error? I've been using a timeout of 0 > > > libusb: error [do_close] Device handle closed while transfer was still > being processed, but the device is still connected as far as we know > libusb: error [do_close] A cancellation hasn't even been scheduled on > the transfer for which the device is closing > libusb: warning [libusb_exit] some libusb_devices were leaked > Assertion failed! > > Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe > File: os/poll_windows.c, Line 145 > > Expression: fd != NULL > Heap dump by heaptrc unit of > i:\programming\gcode\libusbxhid\whb04b-4_test.exe > 50 memory blocks allocated : 1782/1968 > 50 memory blocks freed : 1782/1968 > 0 unfreed memory blocks : 0 > True heap size : 131072 (160 used in System startup) True free heap : > 130912 _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > --

Reply by email

Stefan V. Pantazi
to James Richters
Show quoted text 7 lines
libusbhid_interrupt_read. failed! return code: -1 0libusb: error [winusbx_submit_bulk_transfer] ReadPipe/WritePipe failed: [2] The system cannot find the file specified. But I don't really know how I can detect this and exit the process and signal my other program that the device is no longer present. My read command: hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}50); only reports the number of bytes read, and when the device is removed, the result of the libusbhid_interrupt_read seems to be 64. I’m wondering what the proper way to gracefully detect the device has been disconnected is so I can just exit out of the mode the uses the device and return to normal processing without generating any errors.

You can try to handle the error return code by checking that a device that was present before has actually disappeared for the libusb device list.

It also appears that in newer versions of libusb, there are provisions for registering and unregistering a hotplug callback.

http://libusb.sourceforge.net/api-1.0/hotplug.html

It it easy to add the calls to libusbx but they need to be tested that they actually work as expected.

Show quoted text 62 lines
Any ideas? James -----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Friday, August 23, 2019 10:54 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Thanks for pushing on this. I think any pending timeout/transfer must be explicitly canceled before closing the USB device, so that the thread can end gracefully. The only way I see is to use something like libusb_handle_events_timeout_completed http://libusb.sourceforge.net/api-1.0/group__poll.html#ga43e52b912a760b41a0cf8a4a472fbd5b before closing the USB device context. That function is not currently part of the libusbx and has a time_t parameter that appears C-specific but for some reason is not included in ctypes unit. But I am sure Pascal equivalents can be defined. I will do some tests to include the libusb_handle_events_timeout_completed in libusbx and libusbhid and let you know. On 8/23/19 7:07 AM, James Richters wrote: > Stefan , > Do you get the following errors when you exit your program? Is there some way I should shut down the read thread so I don't get this error? I've been using a timeout of 0 > > > libusb: error [do_close] Device handle closed while transfer was still > being processed, but the device is still connected as far as we know > libusb: error [do_close] A cancellation hasn't even been scheduled on > the transfer for which the device is closing > libusb: warning [libusb_exit] some libusb_devices were leaked > Assertion failed! > > Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe > File: os/poll_windows.c, Line 145 > > Expression: fd != NULL > Heap dump by heaptrc unit of > i:\programming\gcode\libusbxhid\whb04b-4_test.exe > 50 memory blocks allocated : 1782/1968 > 50 memory blocks freed : 1782/1968 > 0 unfreed memory blocks : 0 > True heap size : 131072 (160 used in System startup) True free heap : > 130912 _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > -- _______________________________________________________ _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi

Thanks for adding the hotplug functions and the sample program. I will give that a try.

I have come up with another solution before I saw you added the hotplug functions:

My thinking is that the interrupt read is going to know about the missing device before anything because it will be constantly reading as fast is it can and my main thread will be cycling much slower, so detecting the failure of the interrupt read would be the fastest way to know the device was not connected anymore. I noticed that lib_interupt_transfer produces a return code if anything prevents the transfer from being completed. But this information is only used for optional debug reports, and not returned from the libusbhid_interrupt_write and libusbhid_interrupt_read functions, they only return the number of bytes transferred. Since the number of bytes read or sent is irrelevant due to an error, and the error codes seem to always be negative, then there is no ambiguity if we return the error if it is negative or bytes transferred if it is not negative. That way calls to libusbhid_interrupt_write and libusbhid_interrupt_read can quckly get the return code and / or the number of bytes transferred, just by checking if the result is negative or not. Since the interrupt read is happening in a tight loop and running way faster than anything else, it's likely that this will be the fastest way to stop the read thread when the device is unplugged, then I can go back to looking for it in the main program again. The first read that produces an error will stop the thread.

I have tested this on my test branch. I get one negative return code during normal use... and that is if I get a timeout, I get a -7, perhaps because I asked for 8 bytes maybe? This is also useful information to have in my loop as if I get a -7, I don't need to bother checking the data at all since it was not read, it was just a timeout. https://github.com/Zaaphod/libusbxhid/tree/Test

James

Earlier message 91 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Tuesday, August 27, 2019 10:35 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices > > libusbhid_interrupt_read. failed! return code: -1 > 0libusb: error [winusbx_submit_bulk_transfer] ReadPipe/WritePipe failed: [2] The system cannot find the file specified. > > But I don't really know how I can detect this and exit the process and signal my other program that the device is no longer present. My read command: > hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}50); > only reports the number of bytes read, and when the device is removed, the result of the libusbhid_interrupt_read seems to be 64. I’m wondering what the proper way to gracefully detect the device has been disconnected is so I can just exit out of the mode the uses the device and return to normal processing without generating any errors. You can try to handle the error return code by checking that a device that was present before has actually disappeared for the libusb device list. It also appears that in newer versions of libusb, there are provisions for registering and unregistering a hotplug callback. http://libusb.sourceforge.net/api-1.0/hotplug.html It it easy to add the calls to libusbx but they need to be tested that they actually work as expected. > > Any ideas? > > James > > > -----Original Message----- > From: fpc-pascal On Behalf > Of Stefan V. Pantazi > Sent: Friday, August 23, 2019 10:54 AM > To: > Subject: Re: [fpc-pascal] USB Human Interface Devices > > Thanks for pushing on this. I think any pending timeout/transfer must be explicitly canceled before closing the USB device, so that the thread can end gracefully. > > The only way I see is to use something like > > libusb_handle_events_timeout_completed > > http://libusb.sourceforge.net/api-1.0/group__poll.html#ga43e52b912a760 > b41a0cf8a4a472fbd5b > > > before closing the USB device context. > > That function is not currently part of the libusbx and has a time_t parameter that appears C-specific but for some reason is not included in ctypes unit. But I am sure Pascal equivalents can be defined. I will do some tests to include the libusb_handle_events_timeout_completed in libusbx and libusbhid and let you know. > > > > On 8/23/19 7:07 AM, James Richters wrote: >> Stefan , >> Do you get the following errors when you exit your program? Is there some way I should shut down the read thread so I don't get this error? I've been using a timeout of 0 >> >> >> libusb: error [do_close] Device handle closed while transfer was >> still being processed, but the device is still connected as far as we >> know >> libusb: error [do_close] A cancellation hasn't even been scheduled on >> the transfer for which the device is closing >> libusb: warning [libusb_exit] some libusb_devices were leaked >> Assertion failed! >> >> Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe >> File: os/poll_windows.c, Line 145 >> >> Expression: fd != NULL >> Heap dump by heaptrc unit of >> i:\programming\gcode\libusbxhid\whb04b-4_test.exe >> 50 memory blocks allocated : 1782/1968 >> 50 memory blocks freed : 1782/1968 >> 0 unfreed memory blocks : 0 >> True heap size : 131072 (160 used in System startup) True free heap : >> 130912 _______________________________________________ >> fpc-pascal maillist - >> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal >> > > -- > _______________________________________________________ > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > --

Reply by email

James Richters
to James Richters

I tried the hotplug test on Windows with my device, but I am getting a return code of -12 from libusb_hotplug_register_callback I put some extra writeln's the test program: https://github.com/Zaaphod/libusbxhid/blob/Test/libusbx_hotplug_test.pp

Here is the output:

Running "i:\programming\gcode\libusbxhid\libusbx_hotplug_test.exe " Testing With: $10CE $EB93 0
Libusb Initialized
register done, Result:-12
Heap dump by heaptrc unit of i:\programming\gcode\libusbxhid\libusbx_hotplug_test.exe 54 memory blocks allocated : 1913/2120
54 memory blocks freed : 1913/2120
0 unfreed memory blocks : 0
True heap size : 98304 (192 used in System startup) True free heap : 98112

James

Earlier message 108 lines
-----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Wednesday, August 28, 2019 5:03 AM To: 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices Thanks for adding the hotplug functions and the sample program. I will give that a try. I have come up with another solution before I saw you added the hotplug functions: My thinking is that the interrupt read is going to know about the missing device before anything because it will be constantly reading as fast is it can and my main thread will be cycling much slower, so detecting the failure of the interrupt read would be the fastest way to know the device was not connected anymore. I noticed that lib_interupt_transfer produces a return code if anything prevents the transfer from being completed. But this information is only used for optional debug reports, and not returned from the libusbhid_interrupt_write and libusbhid_interrupt_read functions, they only return the number of bytes transferred. Since the number of bytes read or sent is irrelevant due to an error, and the error codes seem to always be negative, then there is no ambiguity if we return the error if it is negative or bytes transferred if it is not negative. That way calls to libusbhid_interrupt_write and libusbhid_interrupt_read can quckly get the return code and / or the number of bytes transferred, just by checking if the result is negative or not. Since the interrupt read is happening in a tight loop and running way faster than anything else, it's likely that this will be the fastest way to stop the read thread when the device is unplugged, then I can go back to looking for it in the main program again. The first read that produces an error will stop the thread. I have tested this on my test branch. I get one negative return code during normal use... and that is if I get a timeout, I get a -7, perhaps because I asked for 8 bytes maybe? This is also useful information to have in my loop as if I get a -7, I don't need to bother checking the data at all since it was not read, it was just a timeout. https://github.com/Zaaphod/libusbxhid/tree/Test James -----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Tuesday, August 27, 2019 10:35 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices > > libusbhid_interrupt_read. failed! return code: -1 > 0libusb: error [winusbx_submit_bulk_transfer] ReadPipe/WritePipe failed: [2] The system cannot find the file specified. > > But I don't really know how I can detect this and exit the process and signal my other program that the device is no longer present. My read command: > hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}50); > only reports the number of bytes read, and when the device is removed, the result of the libusbhid_interrupt_read seems to be 64. I’m wondering what the proper way to gracefully detect the device has been disconnected is so I can just exit out of the mode the uses the device and return to normal processing without generating any errors. You can try to handle the error return code by checking that a device that was present before has actually disappeared for the libusb device list. It also appears that in newer versions of libusb, there are provisions for registering and unregistering a hotplug callback. http://libusb.sourceforge.net/api-1.0/hotplug.html It it easy to add the calls to libusbx but they need to be tested that they actually work as expected. > > Any ideas? > > James > > > -----Original Message----- > From: fpc-pascal On Behalf > Of Stefan V. Pantazi > Sent: Friday, August 23, 2019 10:54 AM > To: > Subject: Re: [fpc-pascal] USB Human Interface Devices > > Thanks for pushing on this. I think any pending timeout/transfer must be explicitly canceled before closing the USB device, so that the thread can end gracefully. > > The only way I see is to use something like > > libusb_handle_events_timeout_completed > > http://libusb.sourceforge.net/api-1.0/group__poll.html#ga43e52b912a760 > b41a0cf8a4a472fbd5b > > > before closing the USB device context. > > That function is not currently part of the libusbx and has a time_t parameter that appears C-specific but for some reason is not included in ctypes unit. But I am sure Pascal equivalents can be defined. I will do some tests to include the libusb_handle_events_timeout_completed in libusbx and libusbhid and let you know. > > > > On 8/23/19 7:07 AM, James Richters wrote: >> Stefan , >> Do you get the following errors when you exit your program? Is there some way I should shut down the read thread so I don't get this error? I've been using a timeout of 0 >> >> >> libusb: error [do_close] Device handle closed while transfer was >> still being processed, but the device is still connected as far as we >> know >> libusb: error [do_close] A cancellation hasn't even been scheduled on >> the transfer for which the device is closing >> libusb: warning [libusb_exit] some libusb_devices were leaked >> Assertion failed! >> >> Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe >> File: os/poll_windows.c, Line 145 >> >> Expression: fd != NULL >> Heap dump by heaptrc unit of >> i:\programming\gcode\libusbxhid\whb04b-4_test.exe >> 50 memory blocks allocated : 1782/1968 >> 50 memory blocks freed : 1782/1968 >> 0 unfreed memory blocks : 0 >> True heap size : 131072 (160 used in System startup) True free heap : >> 130912 _______________________________________________ >> fpc-pascal maillist - >> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal >> > > -- > _______________________________________________________ > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > --

Reply by email

Jean SUZINEAU
to James Richters: I finally have this working fairly well. I used Stefan's sample program as a guide and…

Hello,

It seems you didn't initialized you critical section using InitCriticalSection.
The documentation of EnterCriticalSection :
https://www.freepascal.org/docs-html/rtl/system/entercriticalsection.html The one of InitCriticalSection:
https://www.freepascal.org/docs-html/rtl/system/initcriticalsection.html

At the end, you need to call DoneCriticalSection  to release the associated system resources (
https://www.freepascal.org/docs-html/rtl/system/donecriticalsection.html).

Note: these is related to freepascal implementation of critical sections, in windows API, the function names are slightly different, InitializeCriticalSection/EnterCriticalSection/DeleteCriticalSection (https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-entercriticalsection)

Le 28/08/2019 à 01:50, James Richters a écrit :

Show quoted text 18 lines
One thing I wasn't able to duplicate however was the use of EnterCriticalsection(criticalSection); and LeaveCriticalsection(criticalSection); when writing to shared variables. If I try to ever use EnterCriticalsection(criticalSection); in the read thread, My program just instantly locks up and I can't even break out of it. If I try to use it in the main program I instantly get EAccessViolation: Access violation $00007FFF18A2DF23 $00007FFF189E9BBC $00007FFF189E9AD0 $000000010000DCDA $000000010000D54B $000000010000218B PROCESS_USB_DATA, line 475 of WHB04B-4_test.pas $0000000100002B37 SIMPLETERMINAL, line 641 of WHB04B-4_test.pas $0000000100002DDD USE_MPG_DEVICE, line 675 of WHB04B-4_test.pas $0000000100002F93 main, line 699 of WHB04B-4_test.pas $0000000100002FE6 $0000000100011350 $0000000100001980 $00007FFF17B47E94 $00007FFF18A4A251 Line 475 is EnterCriticalsection(criticalSection); I left where I had the criticalsection stuff in the program but commented out. It does seem to work fine without it though.. since the read, I am curious what I'm doing wrong, or if I need to do something else because I'm on Windows.

Reply by email

James Richters
to Jean SUZINEAU

Thanks for figuring out the critical section needs to be initialized. Stefan's example did not do this: https://github.com/svpantazi/libusbxhid/blob/master/libusbhid_test_with_thread.pp

maybe it's something you can get away with on Linux...

I'll put in the init and done. Should I enter critical section only for writing to shared variables, or also when reading them?

I'm also wondering if there is some way to tell if a thread is currently running or not... I don't want to try to start it again if it's already running. I can make some flag that the threat sets when it starts and clears when it exits, but I am wondering if there already something in place to check to see if a thread exists.

James

Earlier message 40 lines
-----Original Message----- From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Wednesday, August 28, 2019 7:04 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hello, It seems you didn't initialized you critical section using InitCriticalSection. The documentation of EnterCriticalSection : https://www.freepascal.org/docs-html/rtl/system/entercriticalsection.html The one of InitCriticalSection: https://www.freepascal.org/docs-html/rtl/system/initcriticalsection.html At the end, you need to call DoneCriticalSection to release the associated system resources ( https://www.freepascal.org/docs-html/rtl/system/donecriticalsection.html). Note: these is related to freepascal implementation of critical sections, in windows API, the function names are slightly different, InitializeCriticalSection/EnterCriticalSection/DeleteCriticalSection (https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-entercriticalsection) Le 28/08/2019 à 01:50, James Richters a écrit : > One thing I wasn't able to duplicate however was the use of EnterCriticalsection(criticalSection); and LeaveCriticalsection(criticalSection); when writing to shared variables. If I try to ever use EnterCriticalsection(criticalSection); in the read thread, My program just instantly locks up and I can't even break out of it. If I try to use it in the main program I instantly get > EAccessViolation: Access violation > $00007FFF18A2DF23 > $00007FFF189E9BBC > $00007FFF189E9AD0 > $000000010000DCDA > $000000010000D54B > $000000010000218B PROCESS_USB_DATA, line 475 of WHB04B-4_test.pas > $0000000100002B37 SIMPLETERMINAL, line 641 of WHB04B-4_test.pas > $0000000100002DDD USE_MPG_DEVICE, line 675 of WHB04B-4_test.pas > $0000000100002F93 main, line 699 of WHB04B-4_test.pas > $0000000100002FE6 > $0000000100011350 > $0000000100001980 > $00007FFF17B47E94 > $00007FFF18A4A251 > Line 475 is EnterCriticalsection(criticalSection); > I left where I had the criticalsection stuff in the program but commented out. It does seem to work fine without it though.. since the read, I am curious what I'm doing wrong, or if I need to do something else because I'm on Windows.

Reply by email

Jean SUZINEAU
to James Richters

Le 28/08/2019 à 13:26, James Richters a écrit :

Thanks for figuring out the critical section needs to be initialized. Stefan's example did not do this: https://github.com/svpantazi/libusbxhid/blob/master/libusbhid_test_with_thread.pp maybe it's something you can get away with on Linux...

Maybe, it seems EnterCriticalSection is defined by the current thread manager. But if your variable is uninitialized, you can have anything in it, I think EnterCriticalSection cannot do anything reliable with it.

I'll put in the init and done. Should I enter critical section only for writing to shared variables, or also when reading them?

You don't need to enter the Critical section to read the variable.

The critical section is essentially used to prevent the case where your main thread and your read  thread write two different values to the same variable at the same time. In this case without a critical section, you cannot predict the value of the variable. If the variable is always written by the same thread, you don't need the critical section.

I'm also wondering if there is some way to tell if a thread is currently running or not... I don't want to try to start it again if it's already running. I can make some flag that the threat sets when it starts and clears when it exits, but I am wondering if there already something in place to check to see if a thread exists.

You can find whether your thread is running or not with the readThread.Suspended property,

but in your program, your thread is always running, it's nether suspended. It's just blocked in a call (to libusbhid_interrupt_read I guess)

Reply by email

James Richters
to Jean SUZINEAU

Thanks for the information
I'm going to end the thread if the USB device is unplugged, so then I need the main program to also know the thread has ended so it can go back to occasionally checking to see if the device was plugged back in.

You can find whether your thread is running or not with the readThread.Suspended property, but in your program, your thread is always running, it's nether suspended. It's just blocked in a call (to libusbhid_interrupt_read I guess)

Reply by email

Stefan V. Pantazi
to James Richters: Thanks for adding the hotplug functions and the sample program. I will give that a try.…

I agree with you: the libusbhid_interrupt_read and libusb_interrupt_transfer are very close semantically and returning as a result either the length of transferred data or the error code would make a lot of sense. But in rare cases one may still need to check both parameters:

http://libusb.sourceforge.net/api-1.0/group__syncio.html#gac412bda21b7ecf57e4c76877d78e6486 "Also check transferred when dealing with a timeout error code. libusb may have to split your transfer into a number of chunks to satisfy underlying O/S requirements, meaning that the timeout may expire after the first few chunks have completed. libusb is careful not to lose any data that may have been transferred; do not assume that timeout conditions indicate a complete lack of I/O."

At any rate, switching around and returning both: the error code as the result of libusb_interrupt_transfer and the length of data transfer as an out parameter maybe the right thing to do. That would probably make the semantics of libusbhid_interrupt_read and libusb_interrupt_transfer almost identical.

James Richters wrote 11 lines
Thanks for adding the hotplug functions and the sample program. I will give that a try. I have come up with another solution before I saw you added the hotplug functions: My thinking is that the interrupt read is going to know about the missing device before anything because it will be constantly reading as fast is it can and my main thread will be cycling much slower, so detecting the failure of the interrupt read would be the fastest way to know the device was not connected anymore. I noticed that lib_interupt_transfer produces a return code if anything prevents the transfer from being completed. But this information is only used for optional debug reports, and not returned from the libusbhid_interrupt_write and libusbhid_interrupt_read functions, they only return the number of bytes transferred. Since the number of bytes read or sent is irrelevant due to an error, and the error codes seem to always be negative, then there is no ambiguity if we return the error if it is negative or bytes transferred if it is not negative. That way calls to libusbhid_interrupt_write and libusbhid_interrupt_read can quckly get the return code and / or the number of bytes transferred, just by checking if the result is negative or not. Since the interrupt read is happening in a tight loop and running way faster than anything else, it's likely that this will be the fastest way to stop the read thread when the device is unplugged, then I can go back to looking for it in the main program again. The first read that produces an error will stop the thread. I have tested this on my test branch. I get one negative return code during normal use... and that is if I get a timeout, I get a -7, perhaps because I asked for 8 bytes maybe? This is also useful information to have in my loop as if I get a -7, I don't need to bother checking the data at all since it was not read, it was just a timeout. https://github.com/Zaaphod/libusbxhid/tree/Test James

Reply by email

Stefan V. Pantazi
to James Richters: Thanks for figuring out the critical section needs to be initialized. Stefan's example…

Yeah you are right, Windows was less forgiving. Sorry about that and thank you Jean.

For simple data structures written only from one thread, using critical section may be overkill. But if your data structure is a queue or a longer buffer, with length, etc. that is being produced by one thread and consumed by another (i.e., modified by more than one thread) then you should use some form of synchronization such as a critical section.

James Richters wrote 58 lines
Thanks for figuring out the critical section needs to be initialized. Stefan's example did not do this: https://github.com/svpantazi/libusbxhid/blob/master/libusbhid_test_with_thread.pp maybe it's something you can get away with on Linux... I'll put in the init and done. Should I enter critical section only for writing to shared variables, or also when reading them? I'm also wondering if there is some way to tell if a thread is currently running or not... I don't want to try to start it again if it's already running. I can make some flag that the threat sets when it starts and clears when it exits, but I am wondering if there already something in place to check to see if a thread exists. James -----Original Message----- From: fpc-pascal On Behalf Of Jean SUZINEAU Sent: Wednesday, August 28, 2019 7:04 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Hello, It seems you didn't initialized you critical section using InitCriticalSection. The documentation of EnterCriticalSection : https://www.freepascal.org/docs-html/rtl/system/entercriticalsection.html The one of InitCriticalSection: https://www.freepascal.org/docs-html/rtl/system/initcriticalsection.html At the end, you need to call DoneCriticalSection to release the associated system resources ( https://www.freepascal.org/docs-html/rtl/system/donecriticalsection.html). Note: these is related to freepascal implementation of critical sections, in windows API, the function names are slightly different, InitializeCriticalSection/EnterCriticalSection/DeleteCriticalSection (https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-entercriticalsection) Le 28/08/2019 à 01:50, James Richters a écrit : > One thing I wasn't able to duplicate however was the use of EnterCriticalsection(criticalSection); and LeaveCriticalsection(criticalSection); when writing to shared variables. If I try to ever use EnterCriticalsection(criticalSection); in the read thread, My program just instantly locks up and I can't even break out of it. If I try to use it in the main program I instantly get > EAccessViolation: Access violation > $00007FFF18A2DF23 > $00007FFF189E9BBC > $00007FFF189E9AD0 > $000000010000DCDA > $000000010000D54B > $000000010000218B PROCESS_USB_DATA, line 475 of WHB04B-4_test.pas > $0000000100002B37 SIMPLETERMINAL, line 641 of WHB04B-4_test.pas > $0000000100002DDD USE_MPG_DEVICE, line 675 of WHB04B-4_test.pas > $0000000100002F93 main, line 699 of WHB04B-4_test.pas > $0000000100002FE6 > $0000000100011350 > $0000000100001980 > $00007FFF17B47E94 > $00007FFF18A4A251 > Line 475 is EnterCriticalsection(criticalSection); > I left where I had the criticalsection stuff in the program but commented out. It does seem to work fine without it though.. since the read, I am curious what I'm doing wrong, or if I need to do something else because I'm on Windows. _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

Stefan V. Pantazi
to James Richters: I tried the hotplug test on Windows with my device, but I am getting a return code of -12…

I was wondering whether it works on Windows - I only had time to test on Linux. It looks like bad news. Error code -12 is

LIBUSB_ERROR_NOT_SUPPORTED
Operation not supported or unimplemented on this platform.

James Richters wrote 134 lines
I tried the hotplug test on Windows with my device, but I am getting a return code of -12 from libusb_hotplug_register_callback I put some extra writeln's the test program: https://github.com/Zaaphod/libusbxhid/blob/Test/libusbx_hotplug_test.pp Here is the output: Running "i:\programming\gcode\libusbxhid\libusbx_hotplug_test.exe " Testing With: $10CE $EB93 0 Libusb Initialized register done, Result:-12 Heap dump by heaptrc unit of i:\programming\gcode\libusbxhid\libusbx_hotplug_test.exe 54 memory blocks allocated : 1913/2120 54 memory blocks freed : 1913/2120 0 unfreed memory blocks : 0 True heap size : 98304 (192 used in System startup) True free heap : 98112 James -----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Wednesday, August 28, 2019 5:03 AM To: 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices Thanks for adding the hotplug functions and the sample program. I will give that a try. I have come up with another solution before I saw you added the hotplug functions: My thinking is that the interrupt read is going to know about the missing device before anything because it will be constantly reading as fast is it can and my main thread will be cycling much slower, so detecting the failure of the interrupt read would be the fastest way to know the device was not connected anymore. I noticed that lib_interupt_transfer produces a return code if anything prevents the transfer from being completed. But this information is only used for optional debug reports, and not returned from the libusbhid_interrupt_write and libusbhid_interrupt_read functions, they only return the number of bytes transferred. Since the number of bytes read or sent is irrelevant due to an error, and the error codes seem to always be negative, then there is no ambiguity if we return the error if it is negative or bytes transferred if it is not negative. That way calls to libusbhid_interrupt_write and libusbhid_interrupt_read can quckly get the return code and / or the number of bytes transferred, just by checking if the result is negative or not. Since the interrupt read is happening in a tight loop and running way faster than anything else, it's likely that this will be the fastest way to stop the read thread when the device is unplugged, then I can go back to looking for it in the main program again. The first read that produces an error will stop the thread. I have tested this on my test branch. I get one negative return code during normal use... and that is if I get a timeout, I get a -7, perhaps because I asked for 8 bytes maybe? This is also useful information to have in my loop as if I get a -7, I don't need to bother checking the data at all since it was not read, it was just a timeout. https://github.com/Zaaphod/libusbxhid/tree/Test James -----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Tuesday, August 27, 2019 10:35 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices > > libusbhid_interrupt_read. failed! return code: -1 > 0libusb: error [winusbx_submit_bulk_transfer] ReadPipe/WritePipe failed: [2] The system cannot find the file specified. > > But I don't really know how I can detect this and exit the process and signal my other program that the device is no longer present. My read command: > hidReportData[reportIdx].dataLen:=libusbhid_interrupt_read(device_context,$81{endpoint},{out}hidReportData[reportIdx].hid_data,64{report length, varies by device}, {timeout=}50); > only reports the number of bytes read, and when the device is removed, the result of the libusbhid_interrupt_read seems to be 64. I’m wondering what the proper way to gracefully detect the device has been disconnected is so I can just exit out of the mode the uses the device and return to normal processing without generating any errors. You can try to handle the error return code by checking that a device that was present before has actually disappeared for the libusb device list. It also appears that in newer versions of libusb, there are provisions for registering and unregistering a hotplug callback. http://libusb.sourceforge.net/api-1.0/hotplug.html It it easy to add the calls to libusbx but they need to be tested that they actually work as expected. > > Any ideas? > > James > > > -----Original Message----- > From: fpc-pascal On Behalf > Of Stefan V. Pantazi > Sent: Friday, August 23, 2019 10:54 AM > To: > Subject: Re: [fpc-pascal] USB Human Interface Devices > > Thanks for pushing on this. I think any pending timeout/transfer must be explicitly canceled before closing the USB device, so that the thread can end gracefully. > > The only way I see is to use something like > > libusb_handle_events_timeout_completed > > http://libusb.sourceforge.net/api-1.0/group__poll.html#ga43e52b912a760 > b41a0cf8a4a472fbd5b > > > before closing the USB device context. > > That function is not currently part of the libusbx and has a time_t parameter that appears C-specific but for some reason is not included in ctypes unit. But I am sure Pascal equivalents can be defined. I will do some tests to include the libusb_handle_events_timeout_completed in libusbx and libusbhid and let you know. > > > > On 8/23/19 7:07 AM, James Richters wrote: >> Stefan , >> Do you get the following errors when you exit your program? Is there some way I should shut down the read thread so I don't get this error? I've been using a timeout of 0 >> >> >> libusb: error [do_close] Device handle closed while transfer was >> still being processed, but the device is still connected as far as we >> know >> libusb: error [do_close] A cancellation hasn't even been scheduled on >> the transfer for which the device is closing >> libusb: warning [libusb_exit] some libusb_devices were leaked >> Assertion failed! >> >> Program: i:\programming\gcode\libusbxhid\whb04b-4_test.exe >> File: os/poll_windows.c, Line 145 >> >> Expression: fd != NULL >> Heap dump by heaptrc unit of >> i:\programming\gcode\libusbxhid\whb04b-4_test.exe >> 50 memory blocks allocated : 1782/1968 >> 50 memory blocks freed : 1782/1968 >> 0 unfreed memory blocks : 0 >> True heap size : 131072 (160 used in System startup) True free heap : >> 130912 _______________________________________________ >> fpc-pascal maillist - >> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal >> > > -- > _______________________________________________________ > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > -- _______________________________________________________ _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________________

Reply by email

James Richters
to Stefan V. Pantazi: Yeah you are right, Windows was less forgiving. Sorry about that and thank you Jean. For…

I have the critical section working now with init and done. Thanks for the information! For my test program I don't think I need it, but when I integrate it into the real project I will need to write to the same variables at different times, so I'll make sure to define the writes in critical sections.

James

Earlier message 80 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Wednesday, August 28, 2019 5:46 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Yeah you are right, Windows was less forgiving. Sorry about that and thank you Jean. For simple data structures written only from one thread, using critical section may be overkill. But if your data structure is a queue or a longer buffer, with length, etc. that is being produced by one thread and consumed by another (i.e., modified by more than one thread) then you should use some form of synchronization such as a critical section. On 8/28/19 7:26 AM, James Richters wrote: > Thanks for figuring out the critical section needs to be initialized. Stefan's example did not do this: > https://github.com/svpantazi/libusbxhid/blob/master/libusbhid_test_wit > h_thread.pp > > maybe it's something you can get away with on Linux... > > I'll put in the init and done. Should I enter critical section only for writing to shared variables, or also when reading them? > > I'm also wondering if there is some way to tell if a thread is currently running or not... I don't want to try to start it again if it's already running. I can make some flag that the threat sets when it starts and clears when it exits, but I am wondering if there already something in place to check to see if a thread exists. > > James > > > -----Original Message----- > From: fpc-pascal On Behalf > Of Jean SUZINEAU > Sent: Wednesday, August 28, 2019 7:04 AM > To: > Subject: Re: [fpc-pascal] USB Human Interface Devices > > Hello, > > It seems you didn't initialized you critical section using InitCriticalSection. > The documentation of EnterCriticalSection : > https://www.freepascal.org/docs-html/rtl/system/entercriticalsection.h > tml > The one of InitCriticalSection: > https://www.freepascal.org/docs-html/rtl/system/initcriticalsection.ht > ml > > At the end, you need to call DoneCriticalSection to release the associated system resources ( https://www.freepascal.org/docs-html/rtl/system/donecriticalsection.html). > > Note: these is related to freepascal implementation of critical > sections, in windows API, the function names are slightly different, > InitializeCriticalSection/EnterCriticalSection/DeleteCriticalSection > (https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-syncha > pi-entercriticalsection) > > > Le 28/08/2019 à 01:50, James Richters a écrit : >> One thing I wasn't able to duplicate however was the use of EnterCriticalsection(criticalSection); and LeaveCriticalsection(criticalSection); when writing to shared variables. If I try to ever use EnterCriticalsection(criticalSection); in the read thread, My program just instantly locks up and I can't even break out of it. If I try to use it in the main program I instantly get >> EAccessViolation: Access violation >> $00007FFF18A2DF23 >> $00007FFF189E9BBC >> $00007FFF189E9AD0 >> $000000010000DCDA >> $000000010000D54B >> $000000010000218B PROCESS_USB_DATA, line 475 of WHB04B-4_test.pas >> $0000000100002B37 SIMPLETERMINAL, line 641 of WHB04B-4_test.pas >> $0000000100002DDD USE_MPG_DEVICE, line 675 of WHB04B-4_test.pas >> $0000000100002F93 main, line 699 of WHB04B-4_test.pas >> $0000000100002FE6 >> $0000000100011350 >> $0000000100001980 >> $00007FFF17B47E94 >> $00007FFF18A4A251 >> Line 475 is EnterCriticalsection(criticalSection); >> I left where I had the criticalsection stuff in the program but commented out. It does seem to work fine without it though.. since the read, I am curious what I'm doing wrong, or if I need to do something else because I'm on Windows. > > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal > --

Reply by email

James Richters
to Stefan V. Pantazi: I was wondering whether it works on Windows - I only had time to test on Linux. It looks…

I have a system working by just checking error codes and shutting down the thread and starting it as needed and using a few flags to know when thread is running or not.

James

Earlier message 10 lines
-----Original Message----- From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Wednesday, August 28, 2019 5:50 PM To: Subject: Re: [fpc-pascal] USB Human Interface Devices I was wondering whether it works on Windows - I only had time to test on Linux. It looks like bad news. Error code -12 is LIBUSB_ERROR_NOT_SUPPORTED Operation not supported or unimplemented on this platform.

Reply by email

Brian
to James Richters

A few general thoughts. Having been in similar situations when dealing with hardware interfaces .. the hardware is what it is .. and annoying as it is you have to work around it , as the hardware isn't going to change.

It seems you have two problems 1) the USB hardware and 2) your program , in which you are not certain if it is doing something wrong .. been there many times.

Sometimes it helps to make a simulator program which simulates (how you think the hardware is supposed to work) , and use that to shake out the bugs in your software. It is a lot of extra work but sometime there is no alternative. For example use a 2nd PC and an Ethernet UDP connection to test your software concept.

Also rather than using critical sections , use syncobs to ensure that you are not trying to read and write to the same USB address or your data memory.

https://www.freepascal.org/docs-html/current/fcl/syncobjs/teventobject.html

Most guys/gals when writing interrupt handlers tend to use as simple a mechanism as possible .. from previous bad experiences.

Try testing on Linux as you can run your program in graphics mode ( if that is what it does) while viewing events by writing write() messages to a terminal. This occurs if you launch your program from a terminal , then all writeln() messages go to the text terminal.

Reply by email

Brian
to James Richters: I have a system working by just checking error codes and shutting down the thread and…

A bit of clarification ..

Also rather than using critical sections , use syncobs to ensure that you are not trying to /SIMULTANEOUSLY/ read and write to the same USB address or your data memory.

Try using an Ethernet UDP connection to simulate the USB connection as it may illuminate an issue in your program.

The Synapse UDP function works well

Reply by email

James Richters
to Brian

Thanks for the Sybcobs suggestion, I didn't know there was such a thing but it seems like a great way to prevent simultaneous data/hardware events.

James

Earlier message 18 lines
-----Original Message----- From: fpc-pascal On Behalf Of Brian Sent: Thursday, August 29, 2019 10:50 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices A bit of clarification .. Also rather than using critical sections , use syncobs to ensure that you are not trying to /SIMULTANEOUSLY/ read and write to the same USB address or your data memory. Try using an Ethernet UDP connection to simulate the USB connection as it may illuminate an issue in your program. The Synapse UDP function works well -- Sent from: http://free-pascal-general.1045716.n5.nabble.com/

Reply by email

Brian
to James Richters

Yes , and it works well on Linux.

I use it on a circular (ring) buffer where the main program reads data from the circular buffer and increments the read index while a totally random thread reads data from an incoming Ethernet UDP , serial port or a custom hardware port , writes to the circular buffer and increments the write index.

The functions used are :
procedure ResetEvent;
procedure SetEvent;
function WaitFor();  // one of the events in your program READ or WRITE must
wait until the other event finishes.

The condition for a read of the circular buffer is WriteIndex ReadIndex which is in the main loop (not a thread) which is continuously polled in the main loop.

Hope this helps. I can send a code clip but not until next week (out of the office) , showing how it is configured.

Reply by email

James Richters
to James Richters: I have a system working by just checking error codes and shutting down the thread and…

Now I have a new strange issue. I've been working with my sample program here: https://github.com/Zaaphod/libusbxhid/blob/WHB04B-4/whb04b.pas

And it's been working just fine for me.. just some minor little tweaks and adding new functionality.. etc.. I was just about to start to merge this into my large project when I sent the sample program to my dad... on his system he just gets a screen full of errors... but on mine, it's nice and clean. I don't understand what is happening.. I reduced my test program down to the most basic sample that demonstrates the issue here: https://github.com/Zaaphod/libusbxhid/blob/System_Specific_Bug/bugtest.pas

All this program does is checks to see if a specific device exists.. this program works perfectly on 4 computers and has no issue, but on one of my dad's computers I get the following errors:

libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected!

I don't know why Libusb is reporting this, no one tried to open anything so who cares if some devices are not connected, and how does it know they were connected at one time... this is not even an error.. if it's not connected, just ignore it, nobody cares about that device anyway. So I have two questions:
1. any idea why these errors are being generated and how to fix it?
2. Is there a way to turn off libusb errors, info and warnings?

All systems are windows 10 Pro 64 bit, program was compiled for windows 64bit as well.

Here is the complete output with debug info:

K:\ProAuto>bugtest.exe
libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! Looking for $10CE, $EB93: DEBUG Found 20 devices attached DEBUG 1038:1310, bus: 7, address: 6
DEBUG 1002:4399, bus: 10, address: 0
DEBUG 1B21:1142, bus: 3, address: 0
DEBUG 046D:C31C, bus: 7, address: 3
DEBUG 1B21:1142, bus: 1, address: 0
DEBUG 2109:0812, bus: 1, address: 1
DEBUG 2109:2812, bus: 7, address: 2
DEBUG 1002:4397, bus: 6, address: 0
DEBUG 1002:4397, bus: 5, address: 0
DEBUG 0A12:0001, bus: 5, address: 1
DEBUG 2109:2811, bus: 7, address: 9
DEBUG 1002:4397, bus: 9, address: 0
DEBUG 0C45:7403, bus: 7, address: 4
DEBUG 1002:4396, bus: 8, address: 0
DEBUG 1002:4396, bus: 7, address: 0
DEBUG 0E50:0002, bus: 7, address: 7
DEBUG 1B21:1142, bus: 2, address: 0
DEBUG 1002:4396, bus: 4, address: 0
DEBUG 1A40:0101, bus: 7, address: 1
DEBUG 2109:2812, bus: 7, address: 5
DEBUG Index of device 4302:60307=-1
DEBUG Freeing device list with 20 devices
DEBUG USB device list freed. good boy!
FALSE
libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! Looking for $10CE, $EB93: DEBUG Found 20 devices attached DEBUG 1038:1310, bus: 7, address: 6
DEBUG 1002:4399, bus: 10, address: 0
DEBUG 1B21:1142, bus: 3, address: 0
DEBUG 046D:C31C, bus: 7, address: 3
DEBUG 1B21:1142, bus: 1, address: 0
DEBUG 2109:0812, bus: 1, address: 1
DEBUG 2109:2812, bus: 7, address: 2
DEBUG 1002:4397, bus: 6, address: 0
DEBUG 1002:4397, bus: 5, address: 0
DEBUG 0A12:0001, bus: 5, address: 1
DEBUG 2109:2811, bus: 7, address: 9
DEBUG 1002:4397, bus: 9, address: 0
DEBUG 0C45:7403, bus: 7, address: 4
DEBUG 1002:4396, bus: 8, address: 0
DEBUG 1002:4396, bus: 7, address: 0
DEBUG 0E50:0002, bus: 7, address: 7
DEBUG 1B21:1142, bus: 2, address: 0
DEBUG 1002:4396, bus: 4, address: 0
DEBUG 1A40:0101, bus: 7, address: 1
DEBUG 2109:2812, bus: 7, address: 5
DEBUG Index of device 4302:60307=-1
DEBUG Freeing device list with 20 devices
DEBUG USB device list freed. good boy!
FALSE
libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! Looking for $10CE, $EB93: DEBUG Found 20 devices attached DEBUG 1038:1310, bus: 7, address: 6
DEBUG 1002:4399, bus: 10, address: 0
DEBUG 1B21:1142, bus: 3, address: 0
DEBUG 046D:C31C, bus: 7, address: 3
DEBUG 1B21:1142, bus: 1, address: 0
DEBUG 2109:0812, bus: 1, address: 1
DEBUG 2109:2812, bus: 7, address: 2
DEBUG 1002:4397, bus: 6, address: 0
DEBUG 1002:4397, bus: 5, address: 0
DEBUG 0A12:0001, bus: 5, address: 1
DEBUG 2109:2811, bus: 7, address: 9
DEBUG 1002:4397, bus: 9, address: 0
DEBUG 0C45:7403, bus: 7, address: 4
DEBUG 1002:4396, bus: 8, address: 0
DEBUG 1002:4396, bus: 7, address: 0
DEBUG 0E50:0002, bus: 7, address: 7
DEBUG 1B21:1142, bus: 2, address: 0
DEBUG 1002:4396, bus: 4, address: 0
DEBUG 1A40:0101, bus: 7, address: 1
DEBUG 2109:2812, bus: 7, address: 5
DEBUG Index of device 4302:60307=-1
DEBUG Freeing device list with 20 devices
DEBUG USB device list freed. good boy!
FALSE
Heap dump by heaptrc unit of K:\ProAuto\bugtest.exe 685 memory blocks allocated : 33042/37272
685 memory blocks freed : 33042/37272
0 unfreed memory blocks : 0
True heap size : 163840 (128 used in System startup) True free heap : 163712

When I run it on any other computer I get:
I:\Programming\Gcode\bug>bugtest.exe
Looking for $10CE, $EB93: DEBUG Found 17 devices attached DEBUG 8086:A36D, bus: 1, address: 0
DEBUG 8087:0AAA, bus: 1, address: 8
DEBUG 05E3:0612, bus: 1, address: 18
DEBUG 0424:2734, bus: 1, address: 42
DEBUG 1D50:6015, bus: 1, address: 14
DEBUG 05E3:0743, bus: 1, address: 22
DEBUG 1B1C:0C15, bus: 1, address: 9
DEBUG 05E3:0610, bus: 1, address: 21
DEBUG 05E3:0610, bus: 1, address: 6
DEBUG 04E8:61F5, bus: 1, address: 1
DEBUG 1B1C:0C10, bus: 1, address: 7
DEBUG 0424:274C, bus: 1, address: 43
DEBUG 1B1C:1B4F, bus: 1, address: 41
DEBUG 1A40:0101, bus: 1, address: 2
DEBUG 0C45:7403, bus: 1, address: 26
DEBUG 0E50:0002, bus: 1, address: 60
DEBUG 10C4:EA60, bus: 1, address: 4
DEBUG Index of device 4302:60307=-1
DEBUG Freeing device list with 17 devices
DEBUG USB device list freed. good boy!
FALSE
Looking for $10CE, $EB93: DEBUG Found 17 devices attached DEBUG 8086:A36D, bus: 1, address: 0
DEBUG 8087:0AAA, bus: 1, address: 8
DEBUG 05E3:0612, bus: 1, address: 18
DEBUG 0424:2734, bus: 1, address: 42
DEBUG 1D50:6015, bus: 1, address: 14
DEBUG 05E3:0743, bus: 1, address: 22
DEBUG 1B1C:0C15, bus: 1, address: 9
DEBUG 05E3:0610, bus: 1, address: 21
DEBUG 05E3:0610, bus: 1, address: 6
DEBUG 04E8:61F5, bus: 1, address: 1
DEBUG 1B1C:0C10, bus: 1, address: 7
DEBUG 0424:274C, bus: 1, address: 43
DEBUG 1B1C:1B4F, bus: 1, address: 41
DEBUG 1A40:0101, bus: 1, address: 2
DEBUG 0C45:7403, bus: 1, address: 26
DEBUG 0E50:0002, bus: 1, address: 60
DEBUG 10C4:EA60, bus: 1, address: 4
DEBUG Index of device 4302:60307=-1
DEBUG Freeing device list with 17 devices
DEBUG USB device list freed. good boy!
FALSE
Looking for $10CE, $EB93: DEBUG Found 17 devices attached DEBUG 8086:A36D, bus: 1, address: 0
DEBUG 8087:0AAA, bus: 1, address: 8
DEBUG 05E3:0612, bus: 1, address: 18
DEBUG 0424:2734, bus: 1, address: 42
DEBUG 1D50:6015, bus: 1, address: 14
DEBUG 05E3:0743, bus: 1, address: 22
DEBUG 1B1C:0C15, bus: 1, address: 9
DEBUG 05E3:0610, bus: 1, address: 21
DEBUG 05E3:0610, bus: 1, address: 6
DEBUG 04E8:61F5, bus: 1, address: 1
DEBUG 1B1C:0C10, bus: 1, address: 7
DEBUG 0424:274C, bus: 1, address: 43
DEBUG 1B1C:1B4F, bus: 1, address: 41
DEBUG 1A40:0101, bus: 1, address: 2
DEBUG 0C45:7403, bus: 1, address: 26
DEBUG 0E50:0002, bus: 1, address: 60
DEBUG 10C4:EA60, bus: 1, address: 4
DEBUG Index of device 4302:60307=-1
DEBUG Freeing device list with 17 devices
DEBUG USB device list freed. good boy!
FALSE
Heap dump by heaptrc unit of I:\Programming\Gcode\bug\bugtest.exe 595 memory blocks allocated : 28731/32376
595 memory blocks freed : 28731/32376
0 unfreed memory blocks : 0
True heap size : 163840 (160 used in System startup) True free heap : 163680

James

Reply by email

James Richters
to Brian: Yes , and it works well on Linux. I use it on a circular (ring) buffer where the main…

I use circular buffers for another project as well, but I made my own.. and the program doesn't use threads... it's buffering data being sent to a serial port in a really complicated way with a series of loops and timers to manage to function in a single thread... I'm thinking of overhauling it to work with threads as it will greatly simplify things and probably perform better as well. It sounds like there is already circular buffer functions available in FPC? I would really like to see your code sample if you don't mind, it all sounds very useful!

James

Earlier message 20 lines
-----Original Message----- From: fpc-pascal On Behalf Of Brian Sent: Thursday, August 29, 2019 11:57 AM To: Subject: Re: [fpc-pascal] USB Human Interface Devices Yes , and it works well on Linux. I use it on a circular (ring) buffer where the main program reads data from the circular buffer and increments the read index while a totally random thread reads data from an incoming Ethernet UDP , serial port or a custom hardware port , writes to the circular buffer and increments the write index. The functions used are : procedure ResetEvent; procedure SetEvent; function WaitFor(); // one of the events in your program READ or WRITE must wait until the other event finishes. The condition for a read of the circular buffer is WriteIndex ReadIndex which is in the main loop (not a thread) which is continuously polled in the main loop. Hope this helps. I can send a code clip but not until next week (out of the office) , showing how it is configured.

Reply by email

Stefan V. Pantazi
to James Richters: Now I have a new strange issue. I've been working with my sample program here:…

libusb has a debug verbosity level which currently is set to 3 (i.e., very verbose) in the device open function.
There is a define in libusbx.pas that you can change to shut off debug messages.

On Thu, Aug 29, 2019 at 12:03 PM James Richters <

Show quoted text 231 lines
wrote: Now I have a new strange issue. I've been working with my sample program here: https://github.com/Zaaphod/libusbxhid/blob/WHB04B-4/whb04b.pas And it's been working just fine for me.. just some minor little tweaks and adding new functionality.. etc.. I was just about to start to merge this into my large project when I sent the sample program to my dad... on his system he just gets a screen full of errors... but on mine, it's nice and clean. I don't understand what is happening.. I reduced my test program down to the most basic sample that demonstrates the issue here: https://github.com/Zaaphod/libusbxhid/blob/System_Specific_Bug/bugtest.pas All this program does is checks to see if a specific device exists.. this program works perfectly on 4 computers and has no issue, but on one of my dad's computers I get the following errors: libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! I don't know why Libusb is reporting this, no one tried to open anything so who cares if some devices are not connected, and how does it know they were connected at one time... this is not even an error.. if it's not connected, just ignore it, nobody cares about that device anyway. So I have two questions: 1. any idea why these errors are being generated and how to fix it? 2. Is there a way to turn off libusb errors, info and warnings? All systems are windows 10 Pro 64 bit, program was compiled for windows 64bit as well. Here is the complete output with debug info: K:\ProAuto>bugtest.exe libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! Looking for $10CE, $EB93: DEBUG Found 20 devices attached DEBUG 1038:1310, bus: 7, address: 6 DEBUG 1002:4399, bus: 10, address: 0 DEBUG 1B21:1142, bus: 3, address: 0 DEBUG 046D:C31C, bus: 7, address: 3 DEBUG 1B21:1142, bus: 1, address: 0 DEBUG 2109:0812, bus: 1, address: 1 DEBUG 2109:2812, bus: 7, address: 2 DEBUG 1002:4397, bus: 6, address: 0 DEBUG 1002:4397, bus: 5, address: 0 DEBUG 0A12:0001, bus: 5, address: 1 DEBUG 2109:2811, bus: 7, address: 9 DEBUG 1002:4397, bus: 9, address: 0 DEBUG 0C45:7403, bus: 7, address: 4 DEBUG 1002:4396, bus: 8, address: 0 DEBUG 1002:4396, bus: 7, address: 0 DEBUG 0E50:0002, bus: 7, address: 7 DEBUG 1B21:1142, bus: 2, address: 0 DEBUG 1002:4396, bus: 4, address: 0 DEBUG 1A40:0101, bus: 7, address: 1 DEBUG 2109:2812, bus: 7, address: 5 DEBUG Index of device 4302:60307=-1 DEBUG Freeing device list with 20 devices DEBUG USB device list freed. good boy! FALSE libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! Looking for $10CE, $EB93: DEBUG Found 20 devices attached DEBUG 1038:1310, bus: 7, address: 6 DEBUG 1002:4399, bus: 10, address: 0 DEBUG 1B21:1142, bus: 3, address: 0 DEBUG 046D:C31C, bus: 7, address: 3 DEBUG 1B21:1142, bus: 1, address: 0 DEBUG 2109:0812, bus: 1, address: 1 DEBUG 2109:2812, bus: 7, address: 2 DEBUG 1002:4397, bus: 6, address: 0 DEBUG 1002:4397, bus: 5, address: 0 DEBUG 0A12:0001, bus: 5, address: 1 DEBUG 2109:2811, bus: 7, address: 9 DEBUG 1002:4397, bus: 9, address: 0 DEBUG 0C45:7403, bus: 7, address: 4 DEBUG 1002:4396, bus: 8, address: 0 DEBUG 1002:4396, bus: 7, address: 0 DEBUG 0E50:0002, bus: 7, address: 7 DEBUG 1B21:1142, bus: 2, address: 0 DEBUG 1002:4396, bus: 4, address: 0 DEBUG 1A40:0101, bus: 7, address: 1 DEBUG 2109:2812, bus: 7, address: 5 DEBUG Index of device 4302:60307=-1 DEBUG Freeing device list with 20 devices DEBUG USB device list freed. good boy! FALSE libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! Looking for $10CE, $EB93: DEBUG Found 20 devices attached DEBUG 1038:1310, bus: 7, address: 6 DEBUG 1002:4399, bus: 10, address: 0 DEBUG 1B21:1142, bus: 3, address: 0 DEBUG 046D:C31C, bus: 7, address: 3 DEBUG 1B21:1142, bus: 1, address: 0 DEBUG 2109:0812, bus: 1, address: 1 DEBUG 2109:2812, bus: 7, address: 2 DEBUG 1002:4397, bus: 6, address: 0 DEBUG 1002:4397, bus: 5, address: 0 DEBUG 0A12:0001, bus: 5, address: 1 DEBUG 2109:2811, bus: 7, address: 9 DEBUG 1002:4397, bus: 9, address: 0 DEBUG 0C45:7403, bus: 7, address: 4 DEBUG 1002:4396, bus: 8, address: 0 DEBUG 1002:4396, bus: 7, address: 0 DEBUG 0E50:0002, bus: 7, address: 7 DEBUG 1B21:1142, bus: 2, address: 0 DEBUG 1002:4396, bus: 4, address: 0 DEBUG 1A40:0101, bus: 7, address: 1 DEBUG 2109:2812, bus: 7, address: 5 DEBUG Index of device 4302:60307=-1 DEBUG Freeing device list with 20 devices DEBUG USB device list freed. good boy! FALSE Heap dump by heaptrc unit of K:\ProAuto\bugtest.exe 685 memory blocks allocated : 33042/37272 685 memory blocks freed : 33042/37272 0 unfreed memory blocks : 0 True heap size : 163840 (128 used in System startup) True free heap : 163712 When I run it on any other computer I get: I:\Programming\Gcode\bug>bugtest.exe Looking for $10CE, $EB93: DEBUG Found 17 devices attached DEBUG 8086:A36D, bus: 1, address: 0 DEBUG 8087:0AAA, bus: 1, address: 8 DEBUG 05E3:0612, bus: 1, address: 18 DEBUG 0424:2734, bus: 1, address: 42 DEBUG 1D50:6015, bus: 1, address: 14 DEBUG 05E3:0743, bus: 1, address: 22 DEBUG 1B1C:0C15, bus: 1, address: 9 DEBUG 05E3:0610, bus: 1, address: 21 DEBUG 05E3:0610, bus: 1, address: 6 DEBUG 04E8:61F5, bus: 1, address: 1 DEBUG 1B1C:0C10, bus: 1, address: 7 DEBUG 0424:274C, bus: 1, address: 43 DEBUG 1B1C:1B4F, bus: 1, address: 41 DEBUG 1A40:0101, bus: 1, address: 2 DEBUG 0C45:7403, bus: 1, address: 26 DEBUG 0E50:0002, bus: 1, address: 60 DEBUG 10C4:EA60, bus: 1, address: 4 DEBUG Index of device 4302:60307=-1 DEBUG Freeing device list with 17 devices DEBUG USB device list freed. good boy! FALSE Looking for $10CE, $EB93: DEBUG Found 17 devices attached DEBUG 8086:A36D, bus: 1, address: 0 DEBUG 8087:0AAA, bus: 1, address: 8 DEBUG 05E3:0612, bus: 1, address: 18 DEBUG 0424:2734, bus: 1, address: 42 DEBUG 1D50:6015, bus: 1, address: 14 DEBUG 05E3:0743, bus: 1, address: 22 DEBUG 1B1C:0C15, bus: 1, address: 9 DEBUG 05E3:0610, bus: 1, address: 21 DEBUG 05E3:0610, bus: 1, address: 6 DEBUG 04E8:61F5, bus: 1, address: 1 DEBUG 1B1C:0C10, bus: 1, address: 7 DEBUG 0424:274C, bus: 1, address: 43 DEBUG 1B1C:1B4F, bus: 1, address: 41 DEBUG 1A40:0101, bus: 1, address: 2 DEBUG 0C45:7403, bus: 1, address: 26 DEBUG 0E50:0002, bus: 1, address: 60 DEBUG 10C4:EA60, bus: 1, address: 4 DEBUG Index of device 4302:60307=-1 DEBUG Freeing device list with 17 devices DEBUG USB device list freed. good boy! FALSE Looking for $10CE, $EB93: DEBUG Found 17 devices attached DEBUG 8086:A36D, bus: 1, address: 0 DEBUG 8087:0AAA, bus: 1, address: 8 DEBUG 05E3:0612, bus: 1, address: 18 DEBUG 0424:2734, bus: 1, address: 42 DEBUG 1D50:6015, bus: 1, address: 14 DEBUG 05E3:0743, bus: 1, address: 22 DEBUG 1B1C:0C15, bus: 1, address: 9 DEBUG 05E3:0610, bus: 1, address: 21 DEBUG 05E3:0610, bus: 1, address: 6 DEBUG 04E8:61F5, bus: 1, address: 1 DEBUG 1B1C:0C10, bus: 1, address: 7 DEBUG 0424:274C, bus: 1, address: 43 DEBUG 1B1C:1B4F, bus: 1, address: 41 DEBUG 1A40:0101, bus: 1, address: 2 DEBUG 0C45:7403, bus: 1, address: 26 DEBUG 0E50:0002, bus: 1, address: 60 DEBUG 10C4:EA60, bus: 1, address: 4 DEBUG Index of device 4302:60307=-1 DEBUG Freeing device list with 17 devices DEBUG USB device list freed. good boy! FALSE Heap dump by heaptrc unit of I:\Programming\Gcode\bug\bugtest.exe 595 memory blocks allocated : 28731/32376 595 memory blocks freed : 28731/32376 0 unfreed memory blocks : 0 True heap size : 163840 (160 used in System startup) True free heap : 163680 James _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to James Richters: Now I have a new strange issue. I've been working with my sample program here:…

Looks like email removed all my linefeeds...
Here is the output with errors on just the one sytem: https://pastebin.com/axtH3hvn

Here is typical output on all other sytems:
https://pastebin.com/ZaJYU3ak

James

Earlier message 27 lines
-----Original Message----- From: fpc-pascal On Behalf Of James Richters Sent: Thursday, August 29, 2019 12:03 PM To: 'FPC-Pascal users discussions' Subject: Re: [fpc-pascal] USB Human Interface Devices Now I have a new strange issue. I've been working with my sample program here: https://github.com/Zaaphod/libusbxhid/blob/WHB04B-4/whb04b.pas And it's been working just fine for me.. just some minor little tweaks and adding new functionality.. etc.. I was just about to start to merge this into my large project when I sent the sample program to my dad... on his system he just gets a screen full of errors... but on mine, it's nice and clean. I don't understand what is happening.. I reduced my test program down to the most basic sample that demonstrates the issue here: https://github.com/Zaaphod/libusbxhid/blob/System_Specific_Bug/bugtest.pas All this program does is checks to see if a specific device exists.. this program works perfectly on 4 computers and has no issue, but on one of my dad's computers I get the following errors: libusb: error [init_device] device 'USB\VID_2109&PID_2812&ASMEDIAUSBD_HUB\00000830' is no longer connected! libusb: error [init_device] device 'USB\VID_1778&PID_0224\40000030' is no longer connected! libusb: info [cache_config_descriptors] could not access configuration descriptor 0 (dummy) for 'USB\VID_2109&PID_2811\5&34472DFD&0&4': [31] A device attached to the system is not functioning. libusb: error [init_device] device 'USB\VID_1058&PID_10B8\57583631413934354E345939' is no longer connected! I don't know why Libusb is reporting this, no one tried to open anything so who cares if some devices are not connected, and how does it know they were connected at one time... this is not even an error.. if it's not connected, just ignore it, nobody cares about that device anyway. So I have two questions: 1. any idea why these errors are being generated and how to fix it? 2. Is there a way to turn off libusb errors, info and warnings? All systems are windows 10 Pro 64 bit, program was compiled for windows 64bit as well. Here is the complete output with debug info: <snip>

Reply by email

James Richters
to Stefan V. Pantazi: libusb has a debug verbosity level which currently is set to 3 (i.e., very verbose) in…

At least I can shut off the messages with that.. but any idea what these messages actually mean? It’s an init_device error but no one was tying to do anything but get the list of devices from the system.

Is there a description of the verbosity level anywhere?

Is this a variable I can change during program execution without re-compiling it? It would be helpful if I was having an issue to turn on debug info, then turn it back off without exiting my program or needing to compile.

James

libusb has a debug verbosity level which currently is set to 3 (i.e., very verbose) in the device open function. There is a define in libusbx.pas that you can change to shut off debug messages.

Reply by email

Stefan V. Pantazi
to James Richters

I would chalk this up to differences between OS versions, configurations, devices, etc and move on. I see all memory is released. At least it does not crash and burn badly.

The function call you want to play with is:
libusb_set_debug
http://libusb.sourceforge.net/api-1.0/group__lib.html#ga5f8376b7a863a5a8d5b8824feb8a427a

Of course, you can set the level dynamically, from your program.

On Thu, Aug 29, 2019 at 12:34 PM James Richters <

Show quoted text 34 lines
wrote: At least I can shut off the messages with that.. but any idea what these messages actually mean? It’s an init_device error but no one was tying to do anything but get the list of devices from the system. Is there a description of the verbosity level anywhere? Is this a variable I can change during program execution without re-compiling it? It would be helpful if I was having an issue to turn on debug info, then turn it back off without exiting my program or needing to compile. James >libusb has a debug verbosity level which currently is set to 3 (i.e., very verbose) in the device open function. >There is a define in libusbx.pas that you can change to shut off debug messages. _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Stefan V. Pantazi

Yes, and besides the errors, everything else seems to work properly. I did notice that the one machine uses an AMD processor and all the others are Intel, not sure what that would have to do with anything, but it is a major system configuration difference.

Thanks for the debug level information. I will probably just shut off all messages but it would be nice to have a way to turn them on if I need to debug something on a remote system.

How about the libusbxhid debug messages? Since they are controlled with {$ifdef DEBUG_MSG} you can’t really turn them on and off without re-compiling. Could another variable be used to make libusbxhid messages optional but only if {$ifdef DEBUG_MSG} is used? It would be helpful to be able to hide them most of the time but show them if trying to debug without re-compiling.

James

Earlier message 51 lines
From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Thursday, August 29, 2019 1:11 PM To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] USB Human Interface Devices I would chalk this up to differences between OS versions, configurations, devices, etc and move on. I see all memory is released. At least it does not crash and burn badly. The function call you want to play with is: libusb_set_debug http://libusb.sourceforge.net/api-1.0/group__lib.html#ga5f8376b7a863a5a8d5b8824feb8a427a Of course, you can set the level dynamically, from your program. On Thu, Aug 29, 2019 at 12:34 PM James Richters < > wrote: At least I can shut off the messages with that.. but any idea what these messages actually mean? It’s an init_device error but no one was tying to do anything but get the list of devices from the system. Is there a description of the verbosity level anywhere? Is this a variable I can change during program execution without re-compiling it? It would be helpful if I was having an issue to turn on debug info, then turn it back off without exiting my program or needing to compile. James >libusb has a debug verbosity level which currently is set to 3 (i.e., very verbose) in the device open function. >There is a define in libusbx.pas that you can change to shut off debug messages.

Reply by email

Stefan V. Pantazi
to James Richters

I see your point. But since libusbhid is mostly a wrapper library, its messages are going to be a higher level of debugging anyway - mostly related to how you handle a particular device. So once you are confident that things are working for your device, turning debug off completely seems the way to go, programs will be smaller and faster (no continuous checking for debug messages are to be displayed). If bugs or problems resurface, the underlying libusb is going to yell at you anyway. Alternatively, you can just compile one release and one debug version of your executable.

On Thu, Aug 29, 2019 at 1:21 PM James Richters <

Show quoted text 99 lines
wrote: Yes, and besides the errors, everything else seems to work properly. I did notice that the one machine uses an AMD processor and all the others are Intel, not sure what that would have to do with anything, but it is a major system configuration difference. Thanks for the debug level information. I will probably just shut off all messages but it would be nice to have a way to turn them on if I need to debug something on a remote system. How about the libusbxhid debug messages? Since they are controlled with {$ifdef DEBUG_MSG} you can’t really turn them on and off without re-compiling. Could another variable be used to make libusbxhid messages optional but only if {$ifdef DEBUG_MSG} is used? It would be helpful to be able to hide them most of the time but show them if trying to debug without re-compiling. James *From:* fpc-pascal *On Behalf Of *Stefan V. Pantazi *Sent:* Thursday, August 29, 2019 1:11 PM *To:* FPC-Pascal users discussions *Subject:* Re: [fpc-pascal] USB Human Interface Devices I would chalk this up to differences between OS versions, configurations, devices, etc and move on. I see all memory is released. At least it does not crash and burn badly. The function call you want to play with is: libusb_set_debug http://libusb.sourceforge.net/api-1.0/group__lib.html#ga5f8376b7a863a5a8d5b8824feb8a427a Of course, you can set the level dynamically, from your program. On Thu, Aug 29, 2019 at 12:34 PM James Richters < > wrote: At least I can shut off the messages with that.. but any idea what these messages actually mean? It’s an init_device error but no one was tying to do anything but get the list of devices from the system. Is there a description of the verbosity level anywhere? Is this a variable I can change during program execution without re-compiling it? It would be helpful if I was having an issue to turn on debug info, then turn it back off without exiting my program or needing to compile. James >libusb has a debug verbosity level which currently is set to 3 (i.e., very verbose) in the device open function. >There is a define in libusbx.pas that you can change to shut off debug messages. _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

James Richters
to Stefan V. Pantazi

Yes, that makes sense.. probably best not to over complicate it.

James

Earlier message 80 lines
From: fpc-pascal On Behalf Of Stefan V. Pantazi Sent: Thursday, August 29, 2019 2:18 PM To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] USB Human Interface Devices I see your point. But since libusbhid is mostly a wrapper library, its messages are going to be a higher level of debugging anyway - mostly related to how you handle a particular device. So once you are confident that things are working for your device, turning debug off completely seems the way to go, programs will be smaller and faster (no continuous checking for debug messages are to be displayed). If bugs or problems resurface, the underlying libusb is going to yell at you anyway. Alternatively, you can just compile one release and one debug version of your executable. On Thu, Aug 29, 2019 at 1:21 PM James Richters < > wrote: Yes, and besides the errors, everything else seems to work properly. I did notice that the one machine uses an AMD processor and all the others are Intel, not sure what that would have to do with anything, but it is a major system configuration difference. Thanks for the debug level information. I will probably just shut off all messages but it would be nice to have a way to turn them on if I need to debug something on a remote system. How about the libusbxhid debug messages? Since they are controlled with {$ifdef DEBUG_MSG} you can’t really turn them on and off without re-compiling. Could another variable be used to make libusbxhid messages optional but only if {$ifdef DEBUG_MSG} is used? It would be helpful to be able to hide them most of the time but show them if trying to debug without re-compiling. James From: fpc-pascal < > On Behalf Of Stefan V. Pantazi Sent: Thursday, August 29, 2019 1:11 PM To: FPC-Pascal users discussions < > Subject: Re: [fpc-pascal] USB Human Interface Devices I would chalk this up to differences between OS versions, configurations, devices, etc and move on. I see all memory is released. At least it does not crash and burn badly. The function call you want to play with is: libusb_set_debug http://libusb.sourceforge.net/api-1.0/group__lib.html#ga5f8376b7a863a5a8d5b8824feb8a427a Of course, you can set the level dynamically, from your program. On Thu, Aug 29, 2019 at 12:34 PM James Richters < > wrote: At least I can shut off the messages with that.. but any idea what these messages actually mean? It’s an init_device error but no one was tying to do anything but get the list of devices from the system. Is there a description of the verbosity level anywhere? Is this a variable I can change during program execution without re-compiling it? It would be helpful if I was having an issue to turn on debug info, then turn it back off without exiting my program or needing to compile. James >libusb has a debug verbosity level which currently is set to 3 (i.e., very verbose) in the device open function. >There is a define in libusbx.pas that you can change to shut off debug messages.

Reply by email