Skip to content

Commit 15b1623

Browse files
committed
add hid stylus pen device.
this works with android, for bypassing that absmouse does not support android. note that, to hide cursor on android for every touch signal, find cursor option in android settings menu. references: 1. https://stackoverflow.com/questions/28536602/hid-digitizer-descriptor-doesnt-perform-well-with-landscape-orientation 2. https://github.com/jonathanedgecombe/absmouse/blob/master/src/AbsMouse.cpp
1 parent 7c1afa8 commit 15b1623

File tree

6 files changed

+121
-1
lines changed

6 files changed

+121
-1
lines changed

examples/device/hid_composite/src/main.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,43 @@ static void send_hid_report(uint8_t report_id, uint32_t btn)
197197
}
198198
}
199199
break;
200-
201200
default: break;
202201
}
203202
}
204203

204+
/* use this to send stylus touch signal through USB. */
205+
static void send_stylus_touch(uint16_t x, uint16_t y, bool state)
206+
{
207+
// skip if hid is not ready yet
208+
if ( !tud_hid_ready() ) return;
209+
210+
static bool has_stylus_pen = false;
211+
212+
hid_stylus_report_t report =
213+
{
214+
.attr = 0,
215+
.x = 0,
216+
.y = 0
217+
};
218+
219+
report.x = x;
220+
report.y = y;
221+
222+
if (state)
223+
{
224+
report.attr = STYLUS_ATTR_TIP_SWITCH | STYLUS_ATTR_IN_RANGE;
225+
tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report));
226+
227+
has_stylus_pen = true;
228+
}else
229+
{
230+
report.attr = 0;
231+
if (has_stylus_pen) tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report));
232+
has_stylus_pen = false;
233+
}
234+
235+
}
236+
205237
// Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..)
206238
// tud_hid_report_complete_cb() is used to send the next report after previous one is complete
207239
void hid_task(void)

examples/device/hid_composite/src/usb_descriptors.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ uint8_t const desc_hid_report[] =
7979
{
8080
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )),
8181
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )),
82+
TUD_HID_REPORT_DESC_STYLUS_PEN( HID_REPORT_ID(REPORT_ID_STYLUS_PEN )),
8283
TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )),
8384
TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD ))
8485
};

examples/device/hid_composite/src/usb_descriptors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum
2929
{
3030
REPORT_ID_KEYBOARD = 1,
3131
REPORT_ID_MOUSE,
32+
REPORT_ID_STYLUS_PEN,
3233
REPORT_ID_CONSUMER_CONTROL,
3334
REPORT_ID_GAMEPAD,
3435
REPORT_ID_COUNT

src/class/hid/hid.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,29 @@ typedef enum
325325

326326
/// @}
327327

328+
//--------------------------------------------------------------------+
329+
// Digitizer Stylus Pen
330+
//--------------------------------------------------------------------+
331+
/** \addtogroup ClassDriver_HID_Stylus Stylus
332+
* @{ */
333+
334+
// Standard Stylus Pen Report.
335+
typedef struct TU_ATTR_PACKED
336+
{
337+
uint8_t attr; /**< Attribute mask for describing current status of the stylus pen. */
338+
uint16_t x; /**< Current x position of the mouse. */
339+
uint16_t y; /**< Current y position of the mouse. */
340+
} hid_stylus_report_t;
341+
342+
// Standard Stylus Pen Attributes Bitmap.
343+
typedef enum
344+
{
345+
STYLUS_ATTR_TIP_SWITCH = TU_BIT(0), ///< Tip switch
346+
STYLUS_ATTR_IN_RANGE = TU_BIT(1), ///< In-range bit.
347+
} hid_stylus_attr_bm_t;
348+
349+
/// @}
350+
328351
//--------------------------------------------------------------------+
329352
// Keyboard
330353
//--------------------------------------------------------------------+
@@ -760,7 +783,9 @@ enum {
760783
HID_USAGE_PAGE_PID = 0x0f,
761784
HID_USAGE_PAGE_UNICODE = 0x10,
762785
HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14,
786+
HID_USAGE_PAGE_IN_RANGE = 0x32,
763787
HID_USAGE_PAGE_MEDICAL = 0x40,
788+
HID_USAGE_PAGE_TIP_SWITCH = 0x42,
764789
HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59,
765790
HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83
766791
HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87
@@ -846,6 +871,15 @@ enum {
846871
HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7
847872
};
848873

874+
/// HID Usage Table: Digitizer Page (0x0D)
875+
enum {
876+
// Touch Screen.
877+
HID_USAGE_DIGITIZER_TOUCH_SCREEN = 0x04,
878+
879+
// Stylus Pen.
880+
HID_USAGE_DIGITIZER_STYLUS = 0x20,
881+
};
882+
849883

850884
/// HID Usage Table: Consumer Page (0x0C)
851885
/// Only contains controls that supported by Windows (whole list is too long)

src/class/hid/hid_device.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id,
194194
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
195195
}
196196

197+
bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) {
198+
hid_stylus_report_t report = {
199+
.attr = attrs,
200+
.x = x,
201+
.y = y,
202+
};
203+
204+
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
205+
}
206+
197207
//--------------------------------------------------------------------+
198208
// USBD-CLASS API
199209
//--------------------------------------------------------------------+

src/class/hid/hid_device.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t but
7979
// use template layout report TUD_HID_REPORT_DESC_GAMEPAD
8080
bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons);
8181

82+
// STYLUS PEN: convenient helper to send absolute stylus pen report if application
83+
bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y);
84+
8285
//--------------------------------------------------------------------+
8386
// Application API (Single Port)
8487
//--------------------------------------------------------------------+
@@ -114,6 +117,10 @@ TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_gamepad_report(uint8_t report_i
114117
return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons);
115118
}
116119

120+
TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_stylus_report(uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) {
121+
return tud_hid_n_stylus_report(0, report_id, attrs, x, y);
122+
}
123+
117124
//--------------------------------------------------------------------+
118125
// Application Callbacks
119126
//--------------------------------------------------------------------+
@@ -257,6 +264,41 @@ void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, u
257264
HID_COLLECTION_END , \
258265
HID_COLLECTION_END \
259266

267+
// Stylus Pen Report Descriptor Template
268+
#define TUD_HID_REPORT_DESC_STYLUS_PEN(...) \
269+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DIGITIZER ) , \
270+
HID_USAGE ( HID_USAGE_DIGITIZER_TOUCH_SCREEN ) , \
271+
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) , \
272+
/* Report ID if any */\
273+
__VA_ARGS__ \
274+
HID_USAGE ( HID_USAGE_DIGITIZER_STYLUS ) , \
275+
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) , \
276+
HID_USAGE_PAGE ( HID_USAGE_PAGE_TIP_SWITCH ) , \
277+
HID_USAGE_PAGE ( HID_USAGE_PAGE_IN_RANGE ) , \
278+
HID_LOGICAL_MIN ( 0 ), \
279+
HID_LOGICAL_MAX ( 1 ), \
280+
HID_REPORT_SIZE ( 1 ), \
281+
HID_REPORT_COUNT( 2 ), \
282+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
283+
HID_REPORT_SIZE ( 1 ), \
284+
HID_REPORT_COUNT( 6 ), \
285+
HID_INPUT ( HID_CONSTANT | HID_ARRAY | HID_ABSOLUTE), \
286+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ), \
287+
HID_PHYSICAL_MAX( 0x7fff ), \
288+
HID_LOGICAL_MAX ( 0x7fff ), \
289+
HID_REPORT_SIZE ( 16 ), \
290+
HID_REPORT_COUNT( 1 ), \
291+
HID_UNIT_EXPONENT( -1 ), \
292+
HID_UNIT ( HID_VARIABLE | HID_NONLINEAR ), \
293+
HID_PHYSICAL_MIN( 0 ), \
294+
HID_PHYSICAL_MAX( 0 ), \
295+
HID_USAGE ( HID_USAGE_DESKTOP_X ), \
296+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
297+
HID_USAGE ( HID_USAGE_DESKTOP_Y ), \
298+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
299+
HID_COLLECTION_END , \
300+
HID_COLLECTION_END \
301+
260302
// Absolute Mouse Report Descriptor Template
261303
#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \
262304
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\

0 commit comments

Comments
 (0)