Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 22 of 22

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

  1. #1
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538

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

    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.

  2. #2
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    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:
    Click image for larger version. 

Name:	Capture.PNG 
Views:	11 
Size:	38.5 KB 
ID:	29175

    So now the question becomes how can I send the appropriate packet and retrieve it using USBHost_t36?

  3. #3
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    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

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    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,,,

    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.
    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:
    Click image for larger version. 

Name:	Screenshot2.jpg 
Views:	12 
Size:	66.3 KB 
ID:	29179

    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

  5. #5
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    Quote Originally Posted by KurtE View Post
    ....

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

  6. #6
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    @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...vers/issues/77

    In order to configure the device https://github.com/DIGImend/digimend...ent-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
    aaa.zip

    So hopefully someone can help

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

    aaa.zip
    Attached Files Attached Files

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    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...

  8. #8
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    Quote Originally Posted by KurtE View Post
    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...
    The one I have is relatively inexpensive, its 40 now but amazon has a 15% discount: https://www.amazon.com/dp/B075T6MTJX...roduct_details

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    wonder how it compares to
    https://www.amazon.com/dp/B07NZ4DQP8

    if same issues

    gluten for punishment ordered one < $30
    Last edited by KurtE; 08-21-2022 at 06:20 PM.

  10. #10
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    @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 = uclogic_params_get_str_desc(&buf, hdev, 100, len);
    
    where  that function calls
    
    	rc = usb_control_msg(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.

  11. #11
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    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...

  12. #12
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    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.

  13. #13
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    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
    Firmware version: HUION_T173_190326
    >>> 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
    Internal Manufacture: HUION Animation Technology Co.,ltd
    >>> 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
    Special report: 
    Max X: 32000
    Max Y: 20000
    Max pressure: 8191
    Resolution: 5080
    As usual the changes were pushed to: https://github.com/KurtE/WacomController

  14. #14
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    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?

  15. #15
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    @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.

  16. #16
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    @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?

  17. #17
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    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!

  18. #18
    Senior Member
    Join Date
    Feb 2018
    Posts
    210
    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..

  19. #19
    Senior Member
    Join Date
    Feb 2018
    Posts
    210
    on the intuos4 both, the pen and eraser end report as button0, can you differentiate the two sides on your bamboo pen?

  20. #20
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    Quote Originally Posted by lokki View Post
    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

  21. #21
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,371
    On My Bambo, the eraser shows up as Button 4

  22. #22
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,538
    Quote Originally Posted by KurtE View Post
    On My Bambo, the eraser shows up as Button 4
    Ok just hooked up my Wacom:
    Pen = 1, lower button on pen = 3, upper = 5
    Eraser = 9, button closest to pen = 11, and button closest to eraser = 13

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •