[fpc-pascal] USB Human Interface Devices

James Richters james at productionautomation.net
Thu Aug 22 17:21:08 CEST 2019


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 <fpc-pascal-bounces at lists.freepascal.org> On Behalf Of Stefan V. Pantazi
Sent: Wednesday, August 21, 2019 10:20 PM
To: fpc-pascal at lists.freepascal.org
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?



More information about the fpc-pascal mailing list