USB Human Interface Devices

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

Re: USB Human Interface Devices

Johann Glaser
Hi!

Am Sonntag, den 18.08.2019, 10:43 -0400 schrieb James Richters:
> 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


> > 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  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

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

Re: USB Human Interface Devices

Zaaphod
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.

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

Re: USB Human Interface Devices

Zaaphod
I'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

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

Re: USB Human Interface Devices

Zaaphod
I 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  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi


On 8/21/19 8:30 AM, 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)



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

Re: USB Human Interface Devices

Zaaphod
In reply to this post by Zaaphod
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 <[hidden email]> On Behalf Of James Richters
Sent: Wednesday, August 21, 2019 8:30 AM
To: 'FPC-Pascal users discussions' <[hidden email]>
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  -  [hidden email] https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
In reply to this post by Stefan V. Pantazi
Thanks for the suggestion!

James

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

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

Re: USB Human Interface Devices

Johann Glaser
In reply to this post by Zaaphod
Hi!

Am Montag, den 19.08.2019, 18:22 -0400 schrieb James Richters:
> 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


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

Re: USB Human Interface Devices

Zaaphod
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 style at all.   I'll have to do some research to see how this method of programing even works at all.  I'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:
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi
In reply to this post by Zaaphod
 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 <[hidden email]> On Behalf Of James Richters
> Sent: Wednesday, August 21, 2019 8:30 AM
> To: 'FPC-Pascal users discussions' <[hidden email]>
> 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  -  [hidden email] https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

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

Re: USB Human Interface Devices

Zaaphod
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

-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Stefan V. Pantazi
Sent: Wednesday, August 21, 2019 5:31 PM
To: [hidden email]
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 <[hidden email]> On Behalf
> Of James Richters
> Sent: Wednesday, August 21, 2019 8:30 AM
> To: 'FPC-Pascal users discussions' <[hidden email]>
> 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  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

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

Re: USB Human Interface Devices

Stefan V. Pantazi

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?


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

debug_log_thread_read.txt (32K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Zaaphod
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

-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Stefan V. Pantazi
Sent: Wednesday, August 21, 2019 10:20 PM
To: [hidden email]
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?

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

Re: USB Human Interface Devices

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

On 8/22/19 11:21 AM, 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.

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

Re: USB Human Interface Devices

Zaaphod
>I 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.

>-5 is LIBUSB_ERROR_NOT_FOUND - this may give a clue
>http://libusb.sourceforge.net/api-1.0/group__asyncio.html#ga685eb7731f9a0593f75beb99727bbe54

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.

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

Re: USB Human Interface Devices

Stefan V. Pantazi


> 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.

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

Re: USB Human Interface Devices

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

Re: USB Human Interface Devices

Zaaphod
In reply to this post by Stefan V. Pantazi
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  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: USB Human Interface Devices

Stefan V. Pantazi
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  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

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

Re: USB Human Interface Devices

Zaaphod
I 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


-----Original Message-----
From: fpc-pascal <[hidden email]> On Behalf Of Stefan V. Pantazi
Sent: Friday, August 23, 2019 10:54 AM
To: [hidden email]
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  -  [hidden email]
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

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