eaphone
eaphone

Reputation: 9

stm32 simulate multi-touch device is not working

I'm using a stm32f103 board to simulate multi-touch hid device. currently the board is recognized as touch screen device correctly, however, touch action is not executed at the host when touch event is sent. (it works with 1 finger before adding the contract id to support multi-touch)

This is bushound snapshot the 0x40.. IN data is response to tell 2 fingers touch is supported:

enter image description here

the partial report descriptor:

0x05, 0x0d,       // USAGE_PAGE (Digitizers)
0x09, 0x04,       // USAGE (Touch Screen)
0xa1, 0x01,       // COLLECTION (Application)
0x85, 0x04,       // 报告ID (4)
0x09, 0x22,       //   USAGE (Finger)
0xa1, 0x00,       //   COLLECTION (Physical)
0x09, 0x42,       //     USAGE (Tip Switch)
0x75, 0x01,       //     REPORT_SIZE (1)
0x95, 0x01,       //     REPORT_COUNT (1)
0x81, 0x02,       //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)   0x09, 0x32,       //     Usage (In Range)
0x09, 0x47,       //     Usage (Confidence)
0x75, 0x01,       //     REPORT_SIZE (1)
0x95, 0x02,       //     REPORT_COUNT (2)
0x81, 0x02,   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x09, 0x51,   //     Usage (Contact Identifier)
0x75, 0x05,   //     Report Size (5)
0x95, 0x01,   //     Report Count (1)
0x81, 0x02,       //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)
0x05, 0x01,       //     USAGE_PAGE (Generic Desktop)
0x09, 0x30,       //     USAGE (X)
0x09, 0x31,       //     USAGE (Y)
0x15, 0x00,       //     LOGICAL_MINIMUM (0)
0x26, 0xff, 0x0f, //     LOGICAL_MAXIMUM (4095)
0x35, 0x00,       //     PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x0f, //     PHYSICAL_MAXIMUM (4095)
0x75, 0x10,       //     REPORT_SIZE (16)
0x95, 0x02,       //     REPORT_COUNT (2)
0x81, 0x02,       //     INPUT (Data,Var,Abs)
0xc0,             //   END_COLLECTION

0x05, 0x0D,        //   Usage Page (Digitizer)     
0x09, 0x22,       //   USAGE (Finger)     
0xa1, 0x00,       //   COLLECTION (Physical)     
0x09, 0x42,       //     USAGE (Tip Switch)     
0x75, 0x01,       //     REPORT_SIZE (1)     
0x95, 0x01,       //     REPORT_COUNT (1) 
0x81, 0x02,       //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)    0x09, 0x32,      //     Usage (In Range) 
0x09, 0x47,       //     Usage (Confidence) 
0x75, 0x01,       //     REPORT_SIZE (1)     
0x95, 0x02,       //     REPORT_COUNT (2) 
0x81, 0x02,   //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 
0x09, 0x51,   //     Usage (Contact Identifier) 
0x75, 0x05,   //     Report Size (5) 
0x95, 0x01,   //     Report Count (1) 
0x81, 0x02,       //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 
0x05, 0x01,       //     USAGE_PAGE (Generic Desktop)     
0x09, 0x30,       //     USAGE (X)     
0x09, 0x31,       //     USAGE (Y)     
0x15, 0x00,       //     LOGICAL_MINIMUM (0)     
0x26, 0xff, 0x0f, //     LOGICAL_MAXIMUM (4095)     
0x35, 0x00,       //     PHYSICAL_MINIMUM (0)     
0x46, 0xff, 0x0f, //     PHYSICAL_MAXIMUM (4095)     
0x75, 0x10,       //     REPORT_SIZE (16)     
0x95, 0x02,       //     REPORT_COUNT (2)     
0x81, 0x02,       //     INPUT (Data,Var,Abs)     
0xc0,             //   END_COLLECTION            

0x05, 0x0d,   // USAGE_PAGE (Digitizers) 
0x09, 0x54,   // USAGE (Actual count) 
0x95, 0x01,   // REPORT_COUNT (1) 
0x75, 0x08,   // REPORT_SIZE (8) 
0x81, 0x02,   // INPUT (Data,Var,Abs)            
0x05, 0x0D,       //   Usage Page (Digitizer) 
0x85, 0x02,       //   Report ID (2) 
0x09, 0x55,       //   Usage (0x55) 
0x95, 0x01,   // REPORT_COUNT (1) 
0x75, 0x08,   // REPORT_SIZE (8) 
0xB1, 0x02,       //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)

The event data structure:

enter image description here


The last 2 lines of bushound above is stm 32 sent touch event data.

Not sure if I'm missing something.

Upvotes: 0

Views: 39

Answers (1)

aja
aja

Reputation: 1720

I processed your HID report descriptor with the free hidrdd report descriptor decoder and it showed a few errors - the main one being that 16-bit fields need to be aligned on a 16-bit boundary so you need add some padding bytes. I've marked all the things I have changed to fix it with "TODO:" in the following:

0x05, 0x0d,       // USAGE_PAGE (Digitizers)
0x09, 0x04,       // USAGE (Touch Screen)
0xa1, 0x01,       // COLLECTION (Application)
0x85, 0x04,       // REPORT ID (4)
0x09, 0x22,       //   USAGE (Finger)
0xa1, 0x02,       //   COLLECTION (Logical)   TODO: Change to logical from physical
0x09, 0x42,       //     USAGE (Tip Switch)
0x15, 0x00,       //     LOGICAL_MINIMUM (0)  TODO: Insert
0x25, 0x01,       //     LOGICAL_MAXIMUM (1)  TODO: Insert
0x75, 0x01,       //     REPORT_SIZE (1)
0x95, 0x01,       //     REPORT_COUNT (1)
0x81, 0x02,       //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)   

0x09, 0x32,       //     Usage (In Range)
0x09, 0x47,       //     Usage (Confidence)
// 0x75, 0x01,       //     REPORT_SIZE (1)   TODO: Remove (already 1)
0x95, 0x02,       //     REPORT_COUNT (2)
0x81, 0x02,       //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)

0x09, 0x51,       //     Usage (Contact Identifier)
0x75, 0x05,       //     Report Size (5)
0x95, 0x01,       //     Report Count (1)
0x81, 0x02,       //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit)

0x75, 0x08,       //     ReportSize(8)   TODO: Insert (8 bits of padding)
0x81, 0x03,       //     Input (Const)   TODO: Insert (padding)

0x05, 0x01,       //     USAGE_PAGE (Generic Desktop)
0x09, 0x30,       //     USAGE (X)
0x09, 0x31,       //     USAGE (Y)
// 0x15, 0x00,       //     LOGICAL_MINIMUM (0) TODO: Remove (already 0)
0x26, 0xff, 0x0f, //     LOGICAL_MAXIMUM (4095)
// 0x35, 0x00,       //     PHYSICAL_MINIMUM (0) TODO: Remove (not needed - no physical units)
// 0x46, 0xff, 0x0f, //     PHYSICAL_MAXIMUM (4095) TODO: Remove (not needed - no physcal units)
0x75, 0x10,       //     REPORT_SIZE (16)
0x95, 0x02,       //     REPORT_COUNT (2)
0x81, 0x02,       //     INPUT (Data,Var,Abs)

0xc0,             //   END_COLLECTION

0x05, 0x0D,        //   Usage Page (Digitizer)
0x09, 0x22,       //   USAGE (Finger)     
0xa1, 0x02,       //   COLLECTION (Logical)   TODO: Change to logical from physical
0x09, 0x42,       //     USAGE (Tip Switch)     
0x25, 0x01,       //     LOGICAL_MAXIMUM (1)  TODO: Insert
0x75, 0x01,       //     REPORT_SIZE (1)     
0x95, 0x01,       //     REPORT_COUNT (1) 
0x81, 0x02,       //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)    

0x09, 0x32,       //     Usage (In Range) 
0x09, 0x47,       //     Usage (Confidence) 
// 0x75, 0x01,       //     REPORT_SIZE (1)   TODO: Remove (already 1)
0x95, 0x02,       //     REPORT_COUNT (2) 
0x81, 0x02,       //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 

0x09, 0x51,       //     Usage (Contact Identifier) 
0x75, 0x05,       //     Report Size (5) 
0x95, 0x01,       //     Report Count (1) 
0x81, 0x02,       //     Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 

0x75, 0x08,       //         ReportSize(8)   TODO: Insert (8 bits of padding)
0x81, 0x03,       //         Input (Const)   TODO: Insert (padding)

0x05, 0x01,       //     USAGE_PAGE (Generic Desktop)     
0x09, 0x30,       //     USAGE (X)     
0x09, 0x31,       //     USAGE (Y)     
// 0x15, 0x00,       //     LOGICAL_MINIMUM (0)     TODO: Remove (already 0)
// 0x26, 0xff, 0x0f, //     LOGICAL_MAXIMUM (4095)  TODO: Remove (already 4095)
//0x35, 0x00,       //     PHYSICAL_MINIMUM (0)     TODO: Remove (not needed - no physical units)
//0x46, 0xff, 0x0f, //     PHYSICAL_MAXIMUM (4095)  TODO: Remove (not needed - no physical units)
0x75, 0x10,       //     REPORT_SIZE (16)     
0x95, 0x02,       //     REPORT_COUNT (2)     
0x81, 0x02,       //     INPUT (Data,Var,Abs)     
0xc0,             //   END_COLLECTION            

0x05, 0x0d,   // USAGE_PAGE (Digitizers)   
0x09, 0x54,   // USAGE (Actual count) 
0x95, 0x01,   // REPORT_COUNT (1) 
0x75, 0x08,   // REPORT_SIZE (8) 
0x81, 0x02,   // INPUT (Data,Var,Abs)            
// 0x05, 0x0D,   //   Usage Page (Digitizer)   TODO: Remove (already on Digitizer page)
0x85, 0x02,   //   Report ID (2) 
0x09, 0x55,   //   Usage (0x55) 
// 0x95, 0x01,   // REPORT_COUNT (1)      TODO: Remove (already 1)
// 0x75, 0x08,   // REPORT_SIZE (8)       TODO: Remove (already 8)
0xB1, 0x02,       //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xc0,             //   END_COLLECTION     TODO: Insert (terminates application collection)

Running hidrdd against the fixed report descriptor reports no errors now - but whether it actually works is another thing:

//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------

/*
05 0D        (GLOBAL) USAGE_PAGE         0x000D Digitizer Page 
09 04        (LOCAL)  USAGE              0x000D0004 Touch Screen (Application Collection)  
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0x000D0004: Page=Digitizer Page, Usage=Touch Screen, Type=Application Collection)
85 04          (GLOBAL) REPORT_ID          0x04 (4)  
09 22          (LOCAL)  USAGE              0x000D0022 Finger (Logical Collection)  
A1 02          (MAIN)   COLLECTION         0x02 Logical (Usage=0x000D0022: Page=Digitizer Page, Usage=Finger, Type=Logical Collection)
09 42            (LOCAL)  USAGE              0x000D0042 Tip Switch (Momentary Control)  
15 00            (GLOBAL) LOGICAL_MINIMUM    0x00 (0)  <-- Info: Consider replacing 15 00 with 14
25 01            (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)  
75 01            (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (1 field x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 32            (LOCAL)  USAGE              0x000D0032 In Range (Momentary Control)  
09 47            (LOCAL)  USAGE              0x000D0047 Touch Valid (Momentary Control)  
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 51            (LOCAL)  USAGE              0x000D0051 Contact Identifier (Dynamic Value)  
75 05            (GLOBAL) REPORT_SIZE        0x05 (5) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (1 field x 5 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
81 03            (MAIN)   INPUT              0x00000003 (1 field x 8 bits) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
05 01            (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
09 30            (LOCAL)  USAGE              0x00010030 X (Dynamic Value)  
09 31            (LOCAL)  USAGE              0x00010031 Y (Dynamic Value)  
26 FF0F          (GLOBAL) LOGICAL_MAXIMUM    0x0FFF (4095)  
75 10            (GLOBAL) REPORT_SIZE        0x10 (16) Number of bits per field  
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0             (MAIN)   END_COLLECTION     Logical 
05 0D          (GLOBAL) USAGE_PAGE         0x000D Digitizer Page 
09 22          (LOCAL)  USAGE              0x000D0022 Finger (Logical Collection)  
A1 02          (MAIN)   COLLECTION         0x02 Logical (Usage=0x000D0022: Page=Digitizer Page, Usage=Finger, Type=Logical Collection)
09 42            (LOCAL)  USAGE              0x000D0042 Tip Switch (Momentary Control)  
25 01            (GLOBAL) LOGICAL_MAXIMUM    0x01 (1)  
75 01            (GLOBAL) REPORT_SIZE        0x01 (1) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (1 field x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 32            (LOCAL)  USAGE              0x000D0032 In Range (Momentary Control)  
09 47            (LOCAL)  USAGE              0x000D0047 Touch Valid (Momentary Control)  
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 51            (LOCAL)  USAGE              0x000D0051 Contact Identifier (Dynamic Value)  
75 05            (GLOBAL) REPORT_SIZE        0x05 (5) Number of bits per field  
95 01            (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (1 field x 5 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
75 08            (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
81 03            (MAIN)   INPUT              0x00000003 (1 field x 8 bits) 1=Constant 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
05 01            (GLOBAL) USAGE_PAGE         0x0001 Generic Desktop Page 
09 30            (LOCAL)  USAGE              0x00010030 X (Dynamic Value)  
09 31            (LOCAL)  USAGE              0x00010031 Y (Dynamic Value)  
75 10            (GLOBAL) REPORT_SIZE        0x10 (16) Number of bits per field  
95 02            (GLOBAL) REPORT_COUNT       0x02 (2) Number of fields  
81 02            (MAIN)   INPUT              0x00000002 (2 fields x 16 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0             (MAIN)   END_COLLECTION     Logical 
05 0D          (GLOBAL) USAGE_PAGE         0x000D Digitizer Page 
09 54          (LOCAL)  USAGE              0x000D0054 Contact Count (Dynamic Value)  
95 01          (GLOBAL) REPORT_COUNT       0x01 (1) Number of fields  
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field  
81 02          (MAIN)   INPUT              0x00000002 (1 field x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
85 02          (GLOBAL) REPORT_ID          0x02 (2)  
09 55          (LOCAL)  USAGE              0x000D0055 Contact Count Maximum (Static Value)  
B1 02          (MAIN)   FEATURE            0x00000002 (1 field x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0           (MAIN)   END_COLLECTION     Application 
*/

// All structure fields should be byte-aligned...
#pragma pack(push,1)

//--------------------------------------------------------------------------------
// Digitizer Page featureReport 02 (Device <-> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x02 (2)
                                                     // Collection: CA:TouchScreen
  uint8_t  DIG_TouchScreenContactCountMaximum;       // Usage 0x000D0055: Contact Count Maximum, Value = 0 to 1
} featureReport02_t;


//--------------------------------------------------------------------------------
// Digitizer Page inputReport 04 (Device --> Host)
//--------------------------------------------------------------------------------

typedef struct
{
  uint8_t  reportId;                                 // Report ID = 0x04 (4)
                                                     // Collection: CA:TouchScreen CL:Finger
  uint8_t  DIG_TouchScreenFingerTipSwitch : 1;       // Usage 0x000D0042: Tip Switch, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerInRange : 1;         // Usage 0x000D0032: In Range, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerTouchValid : 1;      // Usage 0x000D0047: Touch Valid, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerContactIdentifier : 5; // Usage 0x000D0051: Contact Identifier, Value = 0 to 1
  uint8_t  pad_4;                                    // Pad
  uint16_t GD_TouchScreenFingerX;                    // Usage 0x00010030: X, Value = 0 to 4095
  uint16_t GD_TouchScreenFingerY;                    // Usage 0x00010031: Y, Value = 0 to 4095
  uint8_t  DIG_TouchScreenFingerTipSwitch_1 : 1;     // Usage 0x000D0042: Tip Switch, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerInRange_1 : 1;       // Usage 0x000D0032: In Range, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerTouchValid_1 : 1;    // Usage 0x000D0047: Touch Valid, Value = 0 to 1
  uint8_t  DIG_TouchScreenFingerContactIdentifier_1 : 5; // Usage 0x000D0051: Contact Identifier, Value = 0 to 1
  uint8_t  pad_9;                                    // Pad
  uint16_t GD_TouchScreenFingerX_1;                  // Usage 0x00010030: X, Value = 0 to 1
  uint16_t GD_TouchScreenFingerY_1;                  // Usage 0x00010031: Y, Value = 0 to 1
                                                     // Collection: CA:TouchScreen
  uint8_t  DIG_TouchScreenContactCount;              // Usage 0x000D0054: Contact Count, Value = 0 to 1
} inputReport04_t;

#pragma pack(pop)

Upvotes: 1

Related Questions