USBHost - Tablet/Digitizers (Wacom, Huion, etc)

mjs513

Senior Member+
Recently there has been a flurry of activity on improving the support for Pen Tablets/Digitizers:

1. USB host Teensy 4.1. with Wacom Intuos5

and

2. USBHost not identify Device PID/VID but Rather a USB VID/PID on T4.x's.

@KurtE did the heavy lifting to revamp the current digitizer class in USBHost_t36 which was very limited.

This thread is meant to kind of consolidate questions on support tablets/digitizers in USBHost.

At least for me I still have some questions on things like Feature reports, Descriptor strings (not hid descriptors), translating between Wireshark type info and USBHost, etc. Detailed questions to follow.
 
As I have been spending a lot of time on Huion H640P pen tablet I am finding out about all sorts of things associated with HID devices etc - and some of it is more confusing. :)

For instance with HID Devices such as the Huion tablet you can query for string descriptors that provide information like:
Manufacturer
Pen/Tablet resolution,
Firmware version

For instance with the H640P if I run the Huion Python driver in post #92 of the Wacom thread I would see
Code:
--------------------------------------------------------------------------------
 c8 |        Params block #2: ??N?????
    |                          Max X: 32000
    |                          Max Y: 20000
    |                   Max pressure: 8191
    |                     Resolution: 5080
    |
 c9 |       Firmware version: HUION_T173_190326
 ca |  Internal manufacturer: HUION Animation Technology Co.,ltd
--------------------------------------------------------------------------------
and the equivalent dump from say wireshark on a windows machine would show the request as:
Capture.PNG

So now the question becomes how can I send the appropriate packet and retrieve it using USBHost_t36?
 
Continuation from post #2

@KurtE's deviceInfo sketch shows the following using a T3.6 since on a T4.1 it fails to get past the builtin hub:
Code:
USB HID Device Info Program

This Sketch shows information about plugged in HID devices

*** You can control the output by simple character input to Serial ***
R - Turns on or off showing the raw data
C - Toggles showing changed data only on or off
<anything else> - toggles showing the Hid formatted breakdown of the data

sizeof Device = 36
sizeof Pipe = 96
sizeof Transfer = 64
power up USBHS PHY
 reset waited 5
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 1FFFA000
periodictable = 1FFFA000
port change: 10001803
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 10 01 00 00 00 40 16 04 00 3F 00 00 01 02 00 01 
    VendorID = 0416, ProductID = 3F00, Version = 0000
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Manufacturer: Nuvoton
enumeration:
Product: WPM USB
enumeration:
Config data length = 41
enumeration:
Configuration Descriptor:
  09 02 29 00 01 01 00 80 32 
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 02 03 00 00 00 
    Interface = 0
    Number of endpoints = 2
    Class/Subclass/Protocol = 3(HID) / 0 / 0
  09 21 10 01 00 01 22 1B 00 
    HID, 1 report descriptor
  07 05 81 03 40 00 01 
    Endpoint = 1 IN
    Type = Interrupt
    Max Size = 64
    Polling Interval = 1
  07 05 02 03 40 00 01 
    Endpoint = 2 OUT
    Type = Interrupt
    Max Size = 64
    Polling Interval = 1
enumeration:
USBHub memory usage = 960
USBHub claim_device this=1FFF5CC0
USBHub memory usage = 960
USBHub claim_device this=1FFF6080

USBDeviceInfo claim this=1FFF55E8

****************************************
** Device Level **
  vid=416
  pid=3F00
  bDeviceClass = 0
  bDeviceSubClass = 0
  bDeviceProtocol = 0
09 04 00 00 02 03 00 00 00 09 21 10 01 00 01 22 1B 00 07 05 81 03 40 00 01 07 05 02 03 40 00 01 
HIDParser claim this=1FFF4860
HIDParser claim this=1FFF4F20
HIDParser claim this=1FFF96A0
HIDParser claim this=1FFF30E0
HIDParser claim this=1FFF5600
Descriptor 4 = INTERFACE

USBDeviceInfo claim this=1FFF55E8

****************************************
** Interface Level **
09 04 00 00 02 03 00 00 00 09 21 10 01 00 01 22 1B 00 07 05 81 03 40 00 01 07 05 02 03 40 00 01 
 bInterfaceNumber = 0
 number end points = 2
 bInterfaceClass =    3
 bInterfaceSubClass = 0
    HID
 bInterfaceProtocol = 0
report descriptor size = 27
  endpoint = 81
    attributes = 3 Interrupt
    size = 64
    interval = 1
  endpoint = 2
    attributes = 3 Interrupt
    size = 64
    interval = 1
HIDParser claim this=1FFF4860
 bInterfaceNumber =   0
 bInterfaceClass =    3
 bInterfaceSubClass = 0
 bInterfaceProtocol = 0
HID Parser Claim: 09 04 00 00 02 03 00 00 00 09 21 10 01 00 01 22 1B 00 07 05 81 03 40 00 01 07 05 02 03 40 00 01 
report descriptor size = 27
Two endpoint HID:
  endpoint = 81
   size = 64
   interval = 1
  endpoint = 2
   size = 64
   interval = 1
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 5, at offset = 0, shift= 0
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 7, at offset = 0, shift= 1
Descriptor 33 = HID
Descriptor 5 = ENDPOINT
Descriptor 5 = ENDPOINT
*** Device HID1 416: 3f00 - connected ***
  manufacturer: Nuvoton
  product: WPM USB
control callback (hid)
05 01 09 00 A1 01 15 00 25 FF 19 00 29 FF 95 40 75 08 81 02 19 00 29 FF 91 02 C0 
  mesg = 22000681
  got report descriptor
Found top level collection 10000
find_driver
  driver 1FFF7520
HIDDumpController Claim: 416:3f00 usage: 10000 - Yes

HID Report Descriptor (0x1fff4890) size: 27
  05 01	// Usage Page(1) - Generic Desktop
  09 00	// Usage(0) -(?)
  A1 01	// Collection(1) top Usage(10000)
    15 00	// Logical Minimum(0)
    25 FF	// Logical maximum(ff)
    19 00	// Usage Minimum(0) - (?)
    29 FF	// Usage Maximum(ff) - (?)
    95 40	// Report Count(40)
    75 08	// Report Size(8)
    81 02	// Input(2)
    19 00	// Usage Minimum(0) - (?)
    29 FF	// Usage Maximum(ff) - (?)
    91 02	// Output(2)
    C0	// End Collection
*** HID Device hdc1 416: 3f00 - connected ***
  manufacturer: Nuvoton
  product: WPM USB
port change: 1C00100A
    disconnect
disconnect_Device:
USBDriver (available_drivers) list: 1FFF5CC0 -> 1FFF6080 -> 1FFF55E8 -> 1FFF4F20 -> 1FFF96A0 -> 1FFF30E0 -> 1FFF5600
USBDriver (dev->drivers) list: 1FFF4860
disconnect driver 1FFF4860
USBDriver (available_drivers) list: 1FFF4860 -> 1FFF5CC0 -> 1FFF6080 -> 1FFF55E8 -> 1FFF4F20 -> 1FFF96A0 -> 1FFF30E0 -> 1FFF5600
delete_Pipe 1FFF5AA0
  Free transfers
    * 536849152 * remove * free
    * 536817824 * remove * defer free until QH
  Free transfers attached to QH
    * 536817824
    * 536835296
* Delete Pipe completed
delete_Pipe 1FFF5A40
  Free transfers
  Free transfers attached to QH
    * 536849088
* Delete Pipe completed
delete_Pipe 1FFFAA00
  shut down async schedule
  Free transfers
  Free transfers attached to QH
    * 536849216
* Delete Pipe completed
removed Device_t from devlist
  disable
*** HID Device hdc1 - disconnected ***
*** Device HID1 - disconnected ***
port change: 10001803
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 10 01 00 00 00 08 6C 25 6D 00 00 00 05 06 00 01 
    VendorID = 256C, ProductID = 006D, Version = 0000
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
ERROR Followup
    remove from followup list
    remove from followup list
    stray halted 1FFFAAC0
  qtd: 1FFFAAC0, token=80008080, next=1FFFAB40
  dummy halt: 1FFFAB40
enumeration:
Manufacturer: Љ
ERROR Followup
    remove from followup list
    remove from followup list
    stray halted 1FFFAB00
  qtd: 1FFFAB00, token=80008080, next=1FFF74E0
  dummy halt: 1FFF74E0
enumeration:
Product: Љ
enumeration:
Config data length = 59
enumeration:
Configuration Descriptor:
  09 02 3B 00 02 01 00 A0 32 
    NumInterfaces = 2
    ConfigurationValue = 1
  09 04 00 00 01 03 01 02 00 
    Interface = 0
    Number of endpoints = 1
    Class/Subclass/Protocol = 3(HID) / 1(Boot) / 2(Mouse)
  09 21 11 01 00 01 22 12 00 
    HID, 1 report descriptor
  07 05 81 03 40 00 02 
    Endpoint = 1 IN
    Type = Interrupt
    Max Size = 64
    Polling Interval = 2
  09 04 01 00 01 03 01 02 00 
    Interface = 1
    Number of endpoints = 1
    Class/Subclass/Protocol = 3(HID) / 1(Boot) / 2(Mouse)
  09 21 11 01 00 01 22 5D 00 
    HID, 1 report descriptor
  07 05 82 03 10 00 02 
    Endpoint = 2 IN
    Type = Interrupt
    Max Size = 16
    Polling Interval = 2
enumeration:
HIDParser claim this=1FFF4860
USBHub memory usage = 960
USBHub claim_device this=1FFF5CC0
USBHub memory usage = 960
USBHub claim_device this=1FFF6080

USBDeviceInfo claim this=1FFF55E8

****************************************
** Device Level **
  vid=256C
  pid=6D
  bDeviceClass = 0
  bDeviceSubClass = 0
  bDeviceProtocol = 0
09 04 00 00 01 03 01 02 00 09 21 11 01 00 01 22 12 00 07 05 81 03 40 00 02 09 04 01 00 01 03 01
02 00 09 21 11 01 00 01 22 5D 00 07 05 82 03 10 00 02 
HIDParser claim this=1FFF4F20
HIDParser claim this=1FFF96A0
HIDParser claim this=1FFF30E0
HIDParser claim this=1FFF5600
Descriptor 4 = INTERFACE
HIDParser claim this=1FFF4860
 bInterfaceNumber =   0
 bInterfaceClass =    3
 bInterfaceSubClass = 1
 bInterfaceProtocol = 2
HID Parser Claim: 09 04 00 00 01 03 01 02 00 09 21 11 01 00 01 22 12 00 07 05 81 03 40 00 02 09 04 01 00 01 03 01 02 00 09 21 11 01 00 01 22 5D 00 07 05 82 03 10 00 02 
report descriptor size = 18
Single endpoint HID:
  endpoint = 81
   size = 64
   interval = 2
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 5, at offset = 0, shift= 0
Descriptor 33 = HID
Descriptor 5 = ENDPOINT
Descriptor 4 = INTERFACE

USBDeviceInfo claim this=1FFF55E8

****************************************
** Interface Level **
09 04 01 00 01 03 01 02 00 09 21 11 01 00 01 22 5D 00 07 05 82 03 10 00 02 
 bInterfaceNumber = 1
 number end points = 1
 bInterfaceClass =    3
 bInterfaceSubClass = 1
    HID (BOOT)
 bInterfaceProtocol = 2
report descriptor size = 93
  endpoint = 82
    attributes = 3 Interrupt
    size = 16
    interval = 2
HIDParser claim this=1FFF4F20
 bInterfaceNumber =   1
 bInterfaceClass =    3
 bInterfaceSubClass = 1
 bInterfaceProtocol = 2
HID Parser Claim: 09 04 01 00 01 03 01 02 00 09 21 11 01 00 01 22 5D 00 07 05 82 03 10 00 02 
report descriptor size = 93
Single endpoint HID:
  endpoint = 82
   size = 16
   interval = 2
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 3, at offset = 1, shift= 0
Descriptor 33 = HID
Descriptor 5 = ENDPOINT
*** Device HID1 256c: 6d - connected ***
  manufacturer: 	
  product: 	
*** Device HID2 256c: 6d - connected ***
  manufacturer: 	
  product: 	
control callback (hid)
06 00 FF 09 01 A1 01 85 08 75 58 95 01 09 01 81 02 C0 
  mesg = 22000681
  got report descriptor
Found top level collection FF000001
find_driver
  driver 1FFF7520
HIDDumpController Claim: 256c:6d usage: ff000001 - Yes

HID Report Descriptor (0x1fff4890) size: 18
  06 00 FF	// Usage Page(ff00) - Vendor Defined
  09 01	// Usage(1) -
  A1 01	// Collection(1) top Usage(ff000000)
    85 08	// Report ID(8)
    75 58	// Report Size(58)
    95 01	// Report Count(1)
    09 01	// Usage(1) -
    81 02	// Input(2)
    C0	// End Collection
*** HID Device hdc1 256c: 6d - connected ***
  manufacturer: 	
  product: 	
control callback (hid)
05 0D 09 02 A1 01 85 0A 09 20 A1 00 09 42 09 44 09 45 09 3C 15 00 25 01 75 01 95 06 81 02 09 32 75 01 95 01 81 02 81 03 05 01 09 30 09 31 55 0D 65 33 26 FF 7F 35 00 46 00 08 75 10 95 02 81 02 05 0D 09 30 26 FF 1F 75 10 95 01 81 02 09 3D 09 3E 15 81 25 7F 75 08 95 02 81 02 C0 C0 
  mesg = 22000681
  got report descriptor
Found top level collection D0002
find_driver
  driver 1FFF7520
HIDDumpController Claim: 256c:6d usage: d0002 - NO (Usage: 1fffad28)
  driver 1FFF85E0
HIDDumpController Claim: 256c:6d usage: d0002 - Yes

HID Report Descriptor (0x1fff4f50) size: 93
  05 0D	// Usage Page(d) - Digitizer
  09 02	// Usage(2) -
  A1 01	// Collection(1) top Usage(d0000)
    85 0A	// Report ID(a)
    09 20	// Usage(20) -
    A1 00	// Collection(0)
    09 42	// Usage(42) -
    09 44	// Usage(44) -
    09 45	// Usage(45) -
    09 3C	// Usage(3c) -
    15 00	// Logical Minimum(0)
    25 01	// Logical maximum(1)
    75 01	// Report Size(1)
    95 06	// Report Count(6)
    81 02	// Input(2)
    09 32	// Usage(32) -
    75 01	// Report Size(1)
    95 01	// Report Count(1)
    81 02	// Input(2)
    81 03	// Input(3)
    05 01	// Usage Page(1) - Generic Desktop
    09 30	// Usage(30) -(X)
    09 31	// Usage(31) -(Y)
    55 0D	// Unit Exponent(d)
    65 33	// Unit(33)
    26 FF 7F	// Logical maximum(7fff)
    35 00	// Physical Minimum(0)
    46 00 08	// Physical Maximum(800)
    75 10	// Report Size(10)
    95 02	// Report Count(2)
    81 02	// Input(2)
    05 0D	// Usage Page(d) - Digitizer
    09 30	// Usage(30) -
    26 FF 1F	// Logical maximum(1fff)
    75 10	// Report Size(10)
    95 01	// Report Count(1)
    81 02	// Input(2)
    09 3D	// Usage(3d) -
    09 3E	// Usage(3e) -
    15 81	// Logical Minimum(81)
    25 7F	// Logical maximum(7f)
    75 08	// Report Size(8)
    95 02	// Report Count(2)
    81 02	// Input(2)
    C0	// End Collection
  C0	// End Collection
*** HID Device hdc2 256c: 6d - connected ***
  manufacturer: 	
  product:

The only thing I am currently seeing is that I would need to:
Code:
bool USBHIDParser::sendControlPacket(uint32_t bmRequestType, uint32_t bRequest,
			uint32_t wValue, uint32_t wIndex, uint32_t wLength, void *buf)

If that is the case then what should I be sending to the Tablet and how to read the info back.

Some I can guess at but I am terrible at guessing
 
Sometimes I have the best luck with checking how windows and linux processes the different usb devices.

I am still novice going through wireshark output. So, i mostly use my own stuff... Mostly with Saleae LA,,,

View attachment 29177
So most of my own boards I usually add easy location to hook up LA as my rough arrow shows. On pc and like I have old hub where I removed cover...

The released USB Low Level LA does not support HLA. So I made a version of it that does... https://github.com/KurtE/usb-analyzer

The readme has instructions on how to build. Have built on W10 and 11 plus ubuntu 22.04
If you build it, you then let the analyzer program know where to find it. (Logic2)

User Preferences, scroll down to custom... : Mine is set to: D:\github\usb-analyzer\build\Analyzers\Debug
Currently configured capture for 50mhz and I am using channels 0, 1

I then use it as well with my HLA, which is at: https://github.com/KurtE/Saleae_USB_Data_Packets_HLA
To install a custom unreleased HLA, you can download the source. Once they are someplace you
open the extensions on right hand side of window. You click on the three dots ... toward top right and choose, load existing extension...

Then in the analyzers pane I add both of them, I select packet output in LLA.
View attachment 29178

Note I will often turn off streaming to terminal and output to tables on the LLA as to only see the filtered data from HLA.
When I do a capture, I often have to then tell the LLA to restart in this case. Sometimes I have to switch from Full speed to Low speed.

Example when I did a startup of a dell keyboard.
Showing Data table output:
Screenshot2.jpg

Report output is nice:
Code:
4.9175997 , SETUP , 0x0 , 0x0 , <GET_DESCRIPTOR - DEVICE #:0 I:0x0 L:0x8> ,  0x80 0x6 0x0 0x1 0x0 0x0 0x8 0x0
4.91790898 , IN , 0x0 , 0x0 ,  ,  0x12 0x1 0x10 0x1 0x0 0x0 0x0 0x8
4.91867734 , SETUP , 0x0 , 0x0 , <SET_ADDRESS I:0x0 L:0x0> ,  0x0 0x5 0x1 0x0 0x0 0x0 0x0 0x0
4.91967736 , SETUP , 0x0 , 0x1 , <GET_DESCRIPTOR - DEVICE #:0 I:0x0 L:0x12> ,  0x80 0x6 0x0 0x1 0x0 0x0 0x12 0x0
4.91998648 , IN , 0x0 , 0x1 ,  ,  0x12 0x1 0x10 0x1 0x0 0x0 0x0 0x8
4.92021352 , IN , 0x0 , 0x1 ,  ,  0x3c 0x41 0x13 0x21 0x10 0x1 0x0 0x2
4.92040048 , IN , 0x0 , 0x1 ,  ,  0x0 0x1
4.92167736 , SETUP , 0x0 , 0x1 , <GET_DESCRIPTOR - STRING #:0 I:0x0 L:0x7fc> ,  0x80 0x6 0x0 0x3 0x0 0x0 0xfc 0x7
4.9219868 , IN , 0x0 , 0x1 ,  ,  0x4 0x3 0x9 0x4
4.92267738 , SETUP , 0x0 , 0x1 , <GET_DESCRIPTOR - STRING #:2 I:0x409 L:0x7fc> ,  0x80 0x6 0x2 0x3 0x9 0x4 0xfc 0x7
4.92302714 , IN , 0x0 , 0x1 ,  ,  0x34 0x3 0x44 0x0 0x65 0x0 0x6c 0x0
4.92325416 , IN , 0x0 , 0x1 ,  ,  0x6c 0x0 0x20 0x0 0x4b 0x0 0x42 0x0
4.92359974 , IN , 0x0 , 0x1 ,  ,  0x32 0x0 0x31 0x0 0x36 0x0 0x20 0x0
4.92382768 , IN , 0x0 , 0x1 ,  ,  0x57 0x0 0x69 0x0 0x72 0x0 0x65 0x0
4.92405538 , IN , 0x0 , 0x1 ,  ,  0x64 0x0 0x20 0x0 0x4b 0x0 0x65 0x0
4.9242824 , IN , 0x0 , 0x1 ,  ,  0x79 0x0 0x62 0x0 0x6f 0x0 0x61 0x0
4.92459974 , IN , 0x0 , 0x1 ,  ,  0x72 0x0 0x64 0x0
4.92567738 , SETUP , 0x0 , 0x1 , <GET_DESCRIPTOR - CONFIG #:0 I:0x0 L:0x9> ,  0x80 0x6 0x0 0x2 0x0 0x0 0x9 0x0
4.92598636 , IN , 0x0 , 0x1 ,  ,  0x9 0x2 0x3b 0x0 0x2 0x1 0x0 0xa0
4.92613326 , IN , 0x0 , 0x1 ,  ,  0x32
4.9266774 , SETUP , 0x0 , 0x1 , <GET_DESCRIPTOR - CONFIG #:0 I:0x0 L:0x3b> ,  0x80 0x6 0x0 0x2 0x0 0x0 0x3b 0x0
4.92698616 , IN , 0x0 , 0x1 ,  ,  0x9 0x2 0x3b 0x0 0x2 0x1 0x0 0xa0
4.9272132 , IN , 0x0 , 0x1 ,  ,  0x32 0x9 0x4 0x0 0x0 0x1 0x3 0x1
4.92744026 , IN , 0x0 , 0x1 ,  ,  0x1 0x0 0x9 0x21 0x11 0x1 0x0 0x1
4.9276399 , IN , 0x0 , 0x1 ,  ,  0x22 0x41 0x0 0x7 0x5 0x81 0x3 0x8
4.92786692 , IN , 0x0 , 0x1 ,  ,  0x0 0x18 0x9 0x4 0x1 0x0 0x1 0x3
4.92809396 , IN , 0x0 , 0x1 ,  ,  0x0 0x0 0x0 0x9 0x21 0x11 0x1 0x0
4.928321 , IN , 0x0 , 0x1 ,  ,  0x1 0x22 0x6d 0x0 0x7 0x5 0x82 0x3
4.92859978 , IN , 0x0 , 0x1 ,  ,  0x8 0x0 0x30
4.9296774 , SETUP , 0x0 , 0x1 , <SET_CONFIGURATION I:0x0 L:0x0> ,  0x0 0x9 0x1 0x0 0x0 0x0 0x0 0x0
4.93067742 , SETUP , 0x0 , 0x1 , <HID SET_IDLE I:0x0 L:0x0> ,  0x21 0xa 0x0 0x0 0x0 0x0 0x0 0x0
4.93092934 , SETUP , 0x0 , 0x1 , <GET_DESCRIPTOR - HID REPORT I:0x1 L:0x6d> ,  0x81 0x6 0x0 0x22 0x1 0x0 0x6d 0x0
4.93127802 , IN , 0x0 , 0x1 ,  ,  0x5 0x1 0x9 0x80 0xa1 0x1 0x85 0x1
4.93159978 , IN , 0x0 , 0x1 ,  ,  0x19 0x81 0x29 0x83 0x15 0x0 0x25 0x1
4.93182746 , IN , 0x0 , 0x1 ,  ,  0x75 0x1 0x95 0x3 0x81 0x2 0x75 0x5
4.93205448 , IN , 0x0 , 0x1 ,  ,  0x95 0x1 0x81 0x1 0xc0 0x5 0xc 0x9
4.93228152 , IN , 0x0 , 0x1 ,  ,  0x1 0xa1 0x1 0x85 0x2 0xa 0xb5 0x0
4.9325998 , IN , 0x0 , 0x1 ,  ,  0xa 0xb6 0x0 0xa 0xb7 0x0 0xa 0x83
4.932826960000001 , IN , 0x0 , 0x1 ,  ,  0x1 0xa 0xcd 0x0 0xa 0xe9 0x0 0xa
4.933054 , IN , 0x0 , 0x1 ,  ,  0xea 0x0 0xa 0xe2 0x0 0xa 0x24 0x2
4.933281020000001 , IN , 0x0 , 0x1 ,  ,  0xa 0x8a 0x1 0xa 0x25 0x2 0xa 0x23
4.9336403 , IN , 0x0 , 0x1 ,  ,  0x2 0xa 0x21 0x2 0xa 0x26 0x2 0xa
4.9338672 , IN , 0x0 , 0x1 ,  ,  0x27 0x2 0xa 0x2a 0x2 0xa 0x92 0x1
4.93409424 , IN , 0x0 , 0x1 ,  ,  0xa 0x94 0x1 0x9 0xb8 0xa 0xa7 0x1
4.9343226 , IN , 0x0 , 0x1 ,  ,  0x75 0x1 0x95 0x14 0x81 0x2 0x75 0x1
4.9345998 , IN , 0x0 , 0x1 ,  ,  0x95 0x4 0x81 0x1 0xc0
Where I often will simply paste into Excel... Used to think I needed to save t file and then import from text/csv, but recently found I could simply paste it in, and then in Data tab use the Text to columns button...

Sorry I know off subject, but still wonder in your case why that tablet works differently with VID/PID and then if there is something they do to choose report.

Like the Bamboo tablet does:
Code:
30.1782191	 SETUP 	 0x0 	 0xb 	 <HID SET_REPORT I:0x0 L:0x2> 	  0x21 0x9 0x2 0x3 0x0 0x0 0x2 0x0
30.17824402	 OUT 	 0x0 	 0xb 	  	  0x2 0x2
30.17828818	 OUT 	 0x0 	 0xb 	  	  0x2 0x2
 
....

Sorry I know off subject, but still wonder in your case why that tablet works differently with VID/PID and then if there is something they do to choose report.

Like the Bamboo tablet does:
Code:
30.1782191	 SETUP 	 0x0 	 0xb 	 <HID SET_REPORT I:0x0 L:0x2> 	  0x21 0x9 0x2 0x3 0x0 0x0 0x2 0x0
30.17824402	 OUT 	 0x0 	 0xb 	  	  0x2 0x2
30.17828818	 OUT 	 0x0 	 0xb 	  	  0x2 0x2

The Salae HLA you developed is really neat and you know I am going to have to give it a try soon except getting access to the pins might be a challenge - maybe. :)

Anyway back to what I am seeing. The Wacom CTH480 tablet I have shows the same way as your Bamboo (as can be expected since they are both wacom. However with the Huion tablet I have been jumping back and forth between the PI4 and windows and Teensy to see differences.

On both the PI4 and winodows both Wireshark dumps look similar, at least to me, and I am not seeing anything like a set report command. On the PI4 if i do dump the journal what I do see is that it set the Huion up as a Pen and a Pad as highlighted in RED:
Code:
Aug 14 08:25:16 merlin-desktop kernel: usb 1-1.4: New USB device found, idVendor=0416, idProduct=3f00, bcdDevice= 0.00
Aug 14 08:25:16 merlin-desktop kernel: usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Aug 14 08:25:16 merlin-desktop kernel: usb 1-1.4: Product: WPM USB
Aug 14 08:25:16 merlin-desktop kernel: usb 1-1.4: Manufacturer: Nuvoton
Aug 14 08:25:16 merlin-desktop kernel: input: Nuvoton WPM USB as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.4/1-1.4:1.0/0>
Aug 14 08:25:16 merlin-desktop kernel: hid-generic 0003:0416:3F00.0008: input,hidraw0: USB HID v1.10 Device [Nuvoton WPM USB] on usb-0000:01:00.0-1.4/input0
Aug 14 08:25:16 merlin-desktop mtp-probe[3117]: checking bus 1, device 7: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1>
Aug 14 08:25:16 merlin-desktop mtp-probe[3117]: bus: 1, device: 7 was not an MTP device
Aug 14 08:25:16 merlin-desktop systemd-logind[771]: Watching system buttons on /dev/input/event1 (Nuvoton WPM USB)
Aug 14 08:25:16 merlin-desktop mtp-probe[3129]: checking bus 1, device 7: "/sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1>
Aug 14 08:25:16 merlin-desktop mtp-probe[3129]: bus: 1, device: 7 was not an MTP device
Aug 14 08:25:18 merlin-desktop kernel: usb 1-1.4: USB disconnect, device number 7
Aug 14 08:25:18 merlin-desktop kernel: usb 1-1.4: new full-speed USB device number 8 using xhci_hcd
Aug 14 08:25:18 merlin-desktop kernel: usb 1-1.4: New USB device found, idVendor=256c, idProduct=006d, bcdDevice= 0.00
Aug 14 08:25:18 merlin-desktop kernel: usb 1-1.4: New USB device strings: Mfr=5, Product=6, SerialNumber=0
[COLOR="#FF0000"]Aug 14 08:25:18 merlin-desktop kernel: input: HID 256c:006d Pen as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.4/1-1.4:1.0>
Aug 14 08:25:18 merlin-desktop kernel: input: HID 256c:006d Pad as /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.4/1-1.4:1.0>[/COLOR]
Aug 14 08:25:18 merlin-desktop kernel: uclogic 0003:256C:006D.0009: input,hidraw0: USB HID v1.11 Keypad [HID 256c:006d] on usb-0000:01:00.0-1.4/input0
Aug 14 08:25:18 merlin-desktop kernel: uclogic 0003:256C:006D.000A: No inputs registered, leaving
Aug 14 08:25:18 merlin-desktop kernel: uclogic 0003:256C:006D.000A: hidraw2: USB HID v1.11 Device [HID 256c:006d] on usb-0000:01:00.0-1.4/input1

and if I do sudo usbhid-dump -es -m 256c:006d I can see whats coming out of the tablet - and its using report 8 vs report 10:
Code:
Starting dumping interrupt transfer stream
with 1 minute timeout.

001:004:000:STREAM             1661028011.860855
 08 E0 01 01 01 00 00 00 00 00 00 00

001:004:000:STREAM             1661028012.074882
 08 E0 01 01 01 00 00 00 00 00 00 00

001:004:000:STREAM             1661028012.122906
 08 E0 01 01 00 00 00 00 00 00 00 00
In this case I just pressed a button on the tablet.

As for the HID dump itself the only thing I am seeing is what I mentioned. From the PI4:
Code:
0x05, 0x0D,        // Usage Page (Digitizer)
0x09, 0x02,        // Usage (Pen)
0xA1, 0x01,        // Collection (Application)
0x85, 0x0A,        //   Report ID (10)
0x09, 0x20,        //   Usage (Stylus)
0xA1, 0x00,        //   Collection (Physical)
0x09, 0x42,        //     Usage (Tip Switch)
0x09, 0x44,        //     Usage (Barrel Switch)
0x09, 0x45,        //     Usage (Eraser)
0x09, 0x3C,        //     Usage (Invert)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x06,        //     Report Count (6)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x32,        //     Usage (In Range)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x55, 0x0D,        //     Unit Exponent (-3)
0x65, 0x33,        //     Unit (System: English Linear, Length: Inch)
0x26, 0xFF, 0x7F,  //     Logical Maximum (32767)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0x00, 0x08,  //     Physical Maximum (2048)
0x75, 0x10,        //     Report Size (16)
0x95, 0x02,        //     Report Count (2)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0D,        //     Usage Page (Digitizer)
0x09, 0x30,        //     Usage (Tip Pressure)
0x26, 0xFF, 0x1F,  //     Logical Maximum (8191)
0x75, 0x10,        //     Report Size (16)
0x95, 0x01,        //     Report Count (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x3D,        //     Usage (X Tilt)
0x09, 0x3E,        //     Usage (Y Tilt)
0x15, 0x81,        //     Logical Minimum (-127)
0x25, 0x7F,        //     Logical Maximum (127)
0x75, 0x08,        //     Report Size (8)
0x95, 0x02,        //     Report Count (2)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0xC0,              // End Collection

// 93 bytes

// best guess: USB HID Report Descriptor

--------------------

0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
0x09, 0x01,        // Usage (0x01)
0xA1, 0x01,        // Collection (Application)
0x85, 0x08,        //   Report ID (8)
0x75, 0x58,        //   Report Size (88)
0x95, 0x01,        //   Report Count (1)
0x09, 0x01,        //   Usage (0x01)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              // End Collection

which is what I am seeing in Windows as well as on the Teensy with the exception that the Teensy 3.6 (does not work on the T4.x) only grabs the data from the report 0x0A.

I have tried to change reports with no luck.
 
@KurtE
It appears I may have found out what the issue with the Huion tablets which is based on UC-logic chipsets. In rummaging around the Digimend Linux drivers for the tablets (supports all kinds of ones) I came across a issue (old one) associated with the Huion 1060 PLUS: https://github.com/DIGImend/digimend-kernel-drivers/issues/77

In order to configure the device https://github.com/DIGImend/digimend-kernel-drivers/issues/77#issuecomment-350797737:
No matter how weird, that's exactly what's happening: Those Huion tablets (and others supposedly based on similar or the same UC-Logic chipsets) are configured by requesting string descriptors. It was one string descriptor for a while, now those new tablets seem to be using another. When you request this string descriptor, you get response with tablet parameters, and you also enable the fully-functional mode. Check out the driver source for the old way, and uclogic-tools source for both the old and (supposedly) the new way.

So it looks like the question I asked previously in post #2 is even more critical. Unfortunately not sure its currently supported.

EDIT:
Just in case anyone is interested here is a text file of wireshark data that shows numerous calls GET Descriptor String and GET Descriptor Configuration
View attachment aaa.zip

So hopefully someone can help :)

EDIT2: Oops that aaa.zip is the linux wireshark dump. Here is the Windows version:

View attachment aaa.zip
 

Attachments

  • HuionWireshark data.zip
    14.5 KB · Views: 24
That is strange stuff!

Looking at some of the sources mentioned it looked like at least in one version read in String Report 100 which then unlocked the tablet?

It is getting almost strange enough to get one...
 
@KurtE and other interested parties.

Was doing some digging with how the Digimend Tablet driver works for linux. @KurtE found that:
Code:
	/*
	 * Read string descriptor containing pen input parameters.
	 * The specific string descriptor and data were discovered by sniffing
	 * the Windows driver traffic.
	 * NOTE: This enables fully-functional tablet mode.
	 */
	rc = [URL="https://github.com/Huion-Linux/DIGImend-kernel-drivers-for-Huion/blob/8b228a755e44106c11f9baaadb30ce668eede5d4/hid-uclogic-params.c#L160"]uclogic_params_get_str_desc[/URL](&buf, hdev, 100, len);

where  that function calls

	rc = [URL="https://github.com/Huion-Linux/DIGImend-kernel-drivers-for-Huion/blob/8b228a755e44106c11f9baaadb30ce668eede5d4/hid-uclogic-params.c#L85"]usb_control_msg[/URL](udev, usb_rcvctrlpipe(udev, 0),
				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
				(USB_DT_STRING << 8) + idx,
				0x0409, buf, len,
				USB_CTRL_GET_TIMEOUT);

In my crude attempt to get the tablet working I did the following based in the wacom driver. Since usb_control_msg is defined as (in linux):
Code:
int usb_control_msg(struct usb_device * dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void * data, __u16 size, int timeout);

which is similar to our sendControlPacket:
Code:
	  bool USBHIDParser::sendControlPacket(uint32_t bmRequestType, uint32_t bRequest,
	  		uint32_t wValue, uint32_t wIndex, uint32_t wLength, void *buf)

we should be able to convert what linux is doing to what we need to send:

Code:
bmRequestType = USB_DIR_IN (0) = 0x80 (i think)
bRequest = 0x06 for Get descriptor string
wValue = (3 << 8) + 100  Note: this @KurtE previously identified as for getting a different report from a wacom tablet:
                        wValue=0x0302 Report type=Feature, Report ID=0x02
wIndex = 0x0409 (according to windows this is set for english, in wacom interface is set to 0????

wLength and buf are defined as:
Code:
	  uint8_t buf[18];
	  int len = 18;


so in the maybeSendSetupControlPackets function I added this code for the Huion tablet:

Code:
         Serial.printf("$$$ Setup tablet Index: %d\n", tablet_info_index_);
	  uint8_t buf[36];
	  int len = 36;
	  driver_->sendControlPacket(0x80, 6,  (3 << 8) + 100, 0x0409, len, buf);
		for(int i = 0; i < len; i++){
			Serial.printf("%x, ", buf[i]);
		} Serial.println();

Just a kludge for now. Still got the same results without implementing it. Did try several variations on a theme though with no luck. But just for reference this is what I got back:
Code:
$$$ Setup tablet Index: 3
>>> SendControlPacket: 80 6 364 409 18 return: 1
c4, 59, ff, 1f, 6d, 0, 0, 0, 1c, 20, ff, 1f, 20, 28, ff, 1f, e7, 48,

Out of curiosity I did try to use 0xC9 to the tablet name by the output doesn't contain the name so not sure what I am doing wrong or if there is something else missing.
 
Good morning @mjs513 @PaulStoffregen and all, (at least in my time zone)

The sending of control messages getting data back and when we can safely do it are all very interesting questions and things to figure out especially with HID based stuff like we are doing.

Yesterday found, we could send the first one, at the end of the claim_collection code, but again need to make sure the object does not send more than one...

Also need to know that sendControlPacket and getting results is not an atomic operation. That is the sendControlPacket returns as soon as it queues up request, and then we need to wait for a return message.
Which implies any buffer used must survive between these two:

In our code I added in so for just for test:
Code:
// Added callback in case we wish to send messages and look at results
// currently unused, but same as using the default interface implementation.
bool WacomController::hid_process_control(const Transfer_t *transfer) {
  Serial.printf("$$$ hid_process_control msg: %x %x buff:%p len:%u : ", transfer->setup.word1, transfer->setup.word2, transfer->buffer, transfer->length);
  uint8_t *buffer = (uint8_t *)transfer->buffer;
  uint16_t len = transfer->length;
  if (buffer) {
    while (len--) Serial.printf(" %02X", *buffer++);
    Serial.println();
  }

  return false;
}

HID will only call this after the object claims a report.

Soon may experiment adding wrappers for this to try to read features and see if we get results. Also see what happens if device NAKs the request

...

need to experiment.

In some cases, will need to setup state machine, snd see if result is x then send y...
 
Good morning @KurtE @PaulStoffregen and all

The sending of control messages getting data back and when we can safely do it are all very interesting questions and things to figure out especially with HID based stuff like we are doing.

Yesterday found, we could send the first one, at the end of the claim_collection code, but again need to make sure the object does not send more than one...

Also need to know that sendControlPacket and getting results is not an atomic operation. That is the sendControlPacket returns as soon as it queues up request, and then we need to wait for a return message.
Which implies any buffer used must survive between these two

After experimenting with the code yesterday found that if we send a control packet to get say the "Internal Manufacture" and add a delay (i used a delay of 250 but probably could be shorter) we would get back the string returned by the WacomController::hid_process_control. So by creating an additional function getDescString to return the actual string it works. Including enabling the tablet to give us report 0x08. In maybeSendSetupControlPackets
Code:
	// required for Huion tablets
	if (s_tablets_info[tablet_info_index_].idVendor== 0x256c) {  
	  if (debugPrint_) Serial.printf("$$$ Setup tablet Index: %d\n", tablet_info_index_);
	  
		desc_len = getDescString(0x80, 6, (3 << 8) + 201, 0x0409, 50, ret_buffer);
		Serial.print("Firmware version: ");
		for(uint8_t i=0; i < desc_len; i++) {
			Serial.printf("%c",ret_buffer[i]);
		} Serial.println();
		
		desc_len = getDescString(0x80, 6, (3 << 8) + 202, 0x0409, 100, ret_buffer);
	    Serial.print("Internal Manufacture: ");
		for(uint8_t i=0; i < desc_len; i++) {
			Serial.printf("%c",ret_buffer[i]);
		} Serial.println();
				
		//Mandatory to report ID 0x08, calls parameters
		//try 100 for older tablets first - if 0 len then try 200
		desc_len = getDescString(0x80, 6, (3 << 8) + 200, 0x0409, 18, ret_buffer);
		if(desc_len == 0)
			desc_len = getDescString(0x80, 6, (3 << 8) + 200, 0x0409, 18, ret_buffer);

	}
and
Code:
uint8_t WacomController::getDescString(uint32_t bmRequestType, uint32_t bRequest, uint32_t wValue, 
	uint32_t wIndex, uint16_t length, uint8_t *buffer ) {
	uint8_t buf[length];
	//uint8_t buffer[WACOM_STRING_BUF_SIZE]; 
	bool rc;
	uint8_t buf_index = 0;
	
	rc = driver_->sendControlPacket(bmRequestType, bRequest,  wValue, wIndex, length, buf);
	delay(250);	// needed to give sendControlpacket time to fill buffer.
	
	// Try to verify - The first byte should be length and the 2nd byte should be 0x3
	if ((buf[1] != 0x3)) {
		return rc;	// No string so can simply return
	}

	uint8_t count_bytes_returned = buf[0];
	//Serial.printf("Bytes returned: %d\n", count_bytes_returned);
	if ((buf_index + count_bytes_returned/2) >= WACOM_STRING_BUF_SIZE)
		count_bytes_returned = (WACOM_STRING_BUF_SIZE - buf_index) * 2;	

	// Now copy into our storage buffer. 
	for (uint8_t i = 2; (i < count_bytes_returned) && (buf_index < (WACOM_STRING_BUF_SIZE -1)); i += 2) {
		buffer[buf_index++] = buf[i];
	} 
	buffer[buf_index] = 0;	// null terminate.

	return buf_index;
}
we managed to get the Huion tablet supported at least on the T3.6 including the frame buttons.
Code:
Digitizer: Pen_Btn0:1 Pen_Btn1:0 Pen_Btn2:0  Pen: (14913, 6050) Pressure: 36 Distance: 0 TiltX: 0 TiltY: 0
Digitizer: Pen_Btn0:1 Pen_Btn1:0 Pen_Btn2:0  Pen: (14973, 6041) Pressure: 5 Distance: 0 TiltX: 0 TiltY: 0
Press:1 
Digitizer: Pen_Btn0:0 Pen_Btn1:0 Pen_Btn2:0  W hl: 0  WhlBtn: 0 Btn0: T:0 P:1 Btn1: T:0 P:0 Btn2: T:0 P:0 Btn3: T:0 P:0 Btn4: T:0 P:0 Btn5: T:0 P:0 Btn6: T:0 P:0 Btn7: T:0 P:0 
Press:0 
Digitizer: Pen_Btn0:0 Pen_Btn1:0 Pen_Btn2:0  W hl: 0  WhlBtn: 0 Btn0: T:0 P:0 Btn1: T:0 P:0 Btn2: T:0 P:0 Btn3: T:0 P:0 Btn4: T:0 P:0 Btn5: T:0 P:0 Btn6: T:0 P:0 Btn7: T:0 P:0 
Press:1 
Digitizer: Pen_Btn0:0 Pen_Btn1:0 Pen_Btn2:0  W hl: 0  WhlBtn: 0 Btn0: T:0 P:1 Btn1: T:0 P:0 Btn2: T:0 P:0 Btn3: T:0 P:0 Btn4: T:0 P:0 Btn5: T:0 P:0 Btn6: T:0 P:0 Btn7: T:0 P:0 
Press:0

On the T4.x still have the issue that the tablet isn't recognized.
 
Good morning @KurtE @PaulStoffregen and all

We did some more cleaning up of the Wacom Lib to add support for the Huion H640P and the H64 tablets. @KurtE converted the getDescription string stuff into a state type machine and put it into the hid_process_control callback to avoid the delay(250) and make it cleaner, we also added a way to get the table info, example:
Code:
$$$ Setup tablet Index: 3
>>> SendControlPacket: 80 6 3c9 409 100 return: 1
$$$ hid_process_control msg: 3c90680 640409 buff:0x1fff2058 len:100 :  24 03 48 00 55 00 49 00 4F 00 4E 00 5F 00 54 00 31 00 37 00 33 00 5F 00 31 00 39 00 30 00 33 00 32 00 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[B]Firmware version: HUION_T173_190326[/B]
>>> SendControlPacket: 80 6 3ca 409 100 return: 1
$$$ hid_process_control msg: 3ca0680 640409 buff:0x1fff2058 len:100 :  46 03 48 00 55 00 49 00 4F 00 4E 00 20 00 41 00 6E 00 69 00 6D 00 61 00 74 00 69 00 6F 00 6E 00 20 00 54 00 65 00 63 00 68 00 6E 00 6F 00 6C 00 6F 00 67 00 79 00 20 00 43 00 6F 00 2E 00 2C 00 6C 00 74 00 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[B]Internal Manufacture: HUION Animation Technology Co.,ltd[/B]
>>> SendControlPacket: 80 6 3c8 409 100 return: 1
$$$ hid_process_control msg: 3c80680 640409 buff:0x1fff2058 len:100 :  13 03 00 7D 00 20 4E 00 FF 1F D8 13 03 06 00 00 04 00 40 68 6E 6F 6C 6F 67 79 20 43 6F 2E 2C 6C 74 64 00 00 65 00 63 00 68 00 6E 00 6F 00 6C 00 6F 00 67 00 79 00 20 00 43 00 6F 00 2E 00 2C 00 6C 00 74 00 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[B]Special report: 
Max X: 32000
Max Y: 20000
Max pressure: 8191
Resolution: 5080[/B]

As usual the changes were pushed to: https://github.com/KurtE/WacomController
 
Good afternoon @lokki @mjs513 @PaullStoffregen and all,

Been taking a pass through the code and maybe trying to clean up some of the methods and a more consistent usage with the different tablets that we have been playing with.

Still unclear if we will want to merge this into USBHost_t36 or not. Sometimes I think it is fine to have that library be the kitchen sink and have everything in it. Other times I think it would make more sense to have at least some parts of it be independent. For example, if all you all you are using this for is to maybe hook up a keyboard or mouse, it will currently pull in other things like SDFat into the build. Oops sorry digression.

But going through this, I am wondering about some of the method names as well as maybe some of the other names.

For example, in the current code we have more or less 3 event types:

a) PEN - user did something with a pen... Makes sense.

b) TOUCH - user touched the tablet (for those that support this)

c)And now SIDE_CTRL which is used for some (hopefully soon all) for clicking on the buttons or other controls on edge of tablet.
I am not sure about this name. I have heard a suggestion of: SIDE_CTRL -> FRAME which I like better.
Sound Reasonable?

Methods about Buttons:

Currently we have a few different methods
a) getButtons - I believe this motly applies now to pen buttons (including that the pen is touching the tablet and eraser)
Although unclear with Finger touch tablets if I press a frame button while dragging finger which events this should give.
I believe if fingers are on tablet it does read in button state and maybe puts these in where getButtons is. But maybe should
be in the FRAME type area.

With Pen we have several other pen methods like:
uint16_t getPenPressure() { return pen_pressure_; }
uint16_t getPenDistance() { return pen_distance_; }
int16_t getTiltX() { return pen_tilt_x_; }
int16_t getTiltY() { return pen_tilt_y_; }

So, wondering if getButtons() should be getPenButtons() ?
Also, should getTiltX*( be getPenTiltX() ?

b) with Frame buttons/controls there are now several:
uint16_t getIntuosWheel() { return side_wheel_; }
bool getIntuosWheelButton() { return side_wheel_button_;}
uint16_t getIntuosButtonTouch() { return side_touch_buttons_; }
uint16_t getIntuosButtonPress() { return side_press_buttons_; }

Unclear from this what is the difference between: getIntuosButtonTouch and getIntuosButtonPress

Assuming that getIntuosButtonPress is for most of these tablets the pressing of a frame button, wondering if it
should be named: getFrameButtons()?

Not sure about other one.
Also wondering if getIntuosWheelButton should be part of getFrameButtons?
It returns an uint16_t and is built using one uint8_t, so the wheel one could be high byte of it?

Probably enough for this post.
Thoughts?
 
@KurtE
Not sure what pressed and touched means very confusing. Would prefer to rename the side controls to something like Frame_buttons, Frame_wheel etx. Frame seems standard nomenclature for anything on the tablet itself in other libraries I looked at.
 
@mjs513 - Will make the changes.
I could leave in stubs for old names if needed.


Another thing that we may want to know about the current Tablet are things like:
a) How Many buttons does it have? For example, with the Bamboo tablet.
The pen has 4 stated (on tablet, button 1, button 2, and eraser (using other end of pen)
b) My frames all have 4 buttons but one of yours might have 8.
c) Max touch? (0 if no touch)
d) Supports pen tilt?

Not sure if this all needs to be built into table or if there are Features that tell this?
 
As mentioned in the previous post, @mjs513 and me have been playing around and updating the library.

This included the name changes and the like mentioned a few posts ago.
Things like SIDE_CTRL went to Frame. And the names of methods associated with it used frame in the name. Likewise for Pen.

Example some of the Pen methods:
Code:
  uint32_t getPenButtons();
  uint16_t getPenPressure() { return pen_pressure_;  }  
  uint16_t getPenDistance() { return pen_distance_; }
  int16_t getPenTiltX() { return pen_tilt_x_; }
  int16_t getPenTiltY() { return pen_tilt_y_; }

Frame methods:
Code:
  uint16_t getFrameWheel() { return side_wheel_; }
  bool getFrameWheelButton() { return side_wheel_button_;}
  uint16_t getFrameTouchButtons() { return frame_touch_buttons_; }
  uint16_t getFrameButtons() { return frame_buttons_; }

Updated the data in our table about which tablets we have tested/supported and added some query functions like:
Code:
  int getMaxTouchCount() {return (tablet_info_index_ != 0xff)? s_tablets_info[tablet_info_index_].touch_max : -1; }
  int getCntPenButtons() {return (tablet_info_index_ != 0xff)? s_tablets_info[tablet_info_index_].pen_buttons : -1; }
  int getCntFrameButtons() {return (tablet_info_index_ != 0xff)? s_tablets_info[tablet_info_index_].frame_buttons : -1; }
  bool getPenSupportsTilt() {return (tablet_info_index_ != 0xff)? s_tablets_info[tablet_info_index_].pen_supports_tilt : false; }
  int width() {return tablet_width_; }
  int height() {return tablet_height_; }
  int touchWidth() {return (tablet_info_index_ != 0xff)? s_tablets_info[tablet_info_index_].touch_tablet_width : -1; }
  int touchHeight() {return (tablet_info_index_ != 0xff)? s_tablets_info[tablet_info_index_].touch_tablet_height : -1; }

The original Test example sketch was updated to work with these.

In addition to this, we added a second example sketch that uses an ILI9341 display to show tablet events as they happen.
There are two views in this sketch:
The default one shows, textual output, like which buttons are pressed, coordinates of pen presses, or touch presses, etc.

A second display (Toggle by entering anything in Serial monitor), shows a quck and dirty crude graphical representation of some
of this information. like rectangles for the frame buttons and likewise Pen buttons that are filled in when buttons are pressed.

Likewise, an area that sort of represents the tablet area and maps the input coordinates into relative positions within that area. We will probably play some more with it to extend some information, plus speed it up. But it did help to discover inconsistencies between the decoding of data between the different tablets, and also finding out that you want at least one more event to tell you that the fingers or pen were removed.

Just having some fun!
 
great, as i wrote in the other thread, works fine with intuos4, will check out intuos5 later.

next move will be to have a go at the intuos4 OLED displays, interesting beast..
 
on the intuos4 both, the pen and eraser end report as button0, can you differentiate the two sides on your bamboo pen?
 
on the intuos4 both, the pen and eraser end report as button0, can you differentiate the two sides on your bamboo pen?

On my on Wacom tablet I was able to differentiate between the eraser and pen side by the button values, I am saying the button values since the buttons on the pen also change depending on if you are using the eraser or pen. Can't remember off the top of my head what they are though - sorry
 
Back
Top