Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Stylus-Pen Device Support. #2911

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion examples/device/hid_composite/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,18 +197,58 @@ static void send_hid_report(uint8_t report_id, uint32_t btn)
}
}
break;

default: break;
}
}

/* use this to send stylus touch signal through USB. */
static void send_stylus_touch(uint16_t x, uint16_t y, bool state)
{
// skip if hid is not ready yet
if ( !tud_hid_ready() ) return;

static bool has_stylus_pen = false;

hid_stylus_report_t report =
{
.attr = 0,
.x = 0,
.y = 0
};

report.x = x;
report.y = y;

if (state)
{
report.attr = STYLUS_ATTR_TIP_SWITCH | STYLUS_ATTR_IN_RANGE;
tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report));

has_stylus_pen = true;
}else
{
report.attr = 0;
if (has_stylus_pen) tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report));
has_stylus_pen = false;
}

}

// Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..)
// tud_hid_report_complete_cb() is used to send the next report after previous one is complete
void hid_task(void)
{
// Poll every 10ms
const uint32_t interval_ms = 10;
static uint32_t start_ms = 0;
static uint32_t touch_ms = 0;
static bool touch_state = false;

if (board_millis() - touch_ms < 100) {
touch_ms = board_millis();
send_stylus_touch(0, 0, touch_state = !touch_state);
return;
}

if ( board_millis() - start_ms < interval_ms) return; // not enough time
start_ms += interval_ms;
Expand Down
1 change: 1 addition & 0 deletions examples/device/hid_composite/src/usb_descriptors.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )),
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )),
TUD_HID_REPORT_DESC_STYLUS_PEN( HID_REPORT_ID(REPORT_ID_STYLUS_PEN )),
TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )),
TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD ))
};
Expand Down
1 change: 1 addition & 0 deletions examples/device/hid_composite/src/usb_descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ enum
{
REPORT_ID_KEYBOARD = 1,
REPORT_ID_MOUSE,
REPORT_ID_STYLUS_PEN,
REPORT_ID_CONSUMER_CONTROL,
REPORT_ID_GAMEPAD,
REPORT_ID_COUNT
Expand Down
34 changes: 34 additions & 0 deletions src/class/hid/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,29 @@ typedef enum

/// @}

//--------------------------------------------------------------------+
// Digitizer Stylus Pen
//--------------------------------------------------------------------+
/** \addtogroup ClassDriver_HID_Stylus Stylus
* @{ */

// Standard Stylus Pen Report.
typedef struct TU_ATTR_PACKED
{
uint8_t attr; /**< Attribute mask for describing current status of the stylus pen. */
uint16_t x; /**< Current x position of the mouse. */
uint16_t y; /**< Current y position of the mouse. */
} hid_stylus_report_t;

// Standard Stylus Pen Attributes Bitmap.
typedef enum
{
STYLUS_ATTR_TIP_SWITCH = TU_BIT(0), ///< Tip switch
STYLUS_ATTR_IN_RANGE = TU_BIT(1), ///< In-range bit.
} hid_stylus_attr_bm_t;

/// @}

//--------------------------------------------------------------------+
// Keyboard
//--------------------------------------------------------------------+
Expand Down Expand Up @@ -760,7 +783,9 @@ enum {
HID_USAGE_PAGE_PID = 0x0f,
HID_USAGE_PAGE_UNICODE = 0x10,
HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14,
HID_USAGE_PAGE_IN_RANGE = 0x32,
HID_USAGE_PAGE_MEDICAL = 0x40,
HID_USAGE_PAGE_TIP_SWITCH = 0x42,
HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59,
HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83
HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87
Expand Down Expand Up @@ -846,6 +871,15 @@ enum {
HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7
};

/// HID Usage Table: Digitizer Page (0x0D)
enum {
// Touch Screen.
HID_USAGE_DIGITIZER_TOUCH_SCREEN = 0x04,

// Stylus Pen.
HID_USAGE_DIGITIZER_STYLUS = 0x20,
};


/// HID Usage Table: Consumer Page (0x0C)
/// Only contains controls that supported by Windows (whole list is too long)
Expand Down
10 changes: 10 additions & 0 deletions src/class/hid/hid_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,16 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id,
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
}

bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) {
hid_stylus_report_t report = {
.attr = attrs,
.x = x,
.y = y,
};

return tud_hid_n_report(instance, report_id, &report, sizeof(report));
}

//--------------------------------------------------------------------+
// USBD-CLASS API
//--------------------------------------------------------------------+
Expand Down
42 changes: 42 additions & 0 deletions src/class/hid/hid_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t but
// use template layout report TUD_HID_REPORT_DESC_GAMEPAD
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);

// STYLUS PEN: convenient helper to send absolute stylus pen report if application
bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y);

//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
Expand Down Expand Up @@ -114,6 +117,10 @@ TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_gamepad_report(uint8_t report_i
return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons);
}

TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_stylus_report(uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) {
return tud_hid_n_stylus_report(0, report_id, attrs, x, y);
}

//--------------------------------------------------------------------+
// Application Callbacks
//--------------------------------------------------------------------+
Expand Down Expand Up @@ -257,6 +264,41 @@ void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, u
HID_COLLECTION_END , \
HID_COLLECTION_END \

// Stylus Pen Report Descriptor Template
#define TUD_HID_REPORT_DESC_STYLUS_PEN(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DIGITIZER ) , \
HID_USAGE ( HID_USAGE_DIGITIZER_TOUCH_SCREEN ) , \
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) , \
/* Report ID if any */\
__VA_ARGS__ \
HID_USAGE ( HID_USAGE_DIGITIZER_STYLUS ) , \
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) , \
HID_USAGE_PAGE ( HID_USAGE_PAGE_TIP_SWITCH ) , \
HID_USAGE_PAGE ( HID_USAGE_PAGE_IN_RANGE ) , \
HID_LOGICAL_MIN ( 0 ), \
HID_LOGICAL_MAX ( 1 ), \
HID_REPORT_SIZE ( 1 ), \
HID_REPORT_COUNT( 2 ), \
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
HID_REPORT_SIZE ( 1 ), \
HID_REPORT_COUNT( 6 ), \
HID_INPUT ( HID_CONSTANT | HID_ARRAY | HID_ABSOLUTE), \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ), \
HID_PHYSICAL_MAX_N( 0x7fff, 2 ), \
HID_LOGICAL_MAX_N ( 0x7fff, 2 ), \
HID_REPORT_SIZE ( 16 ), \
HID_REPORT_COUNT( 1 ), \
HID_UNIT_EXPONENT( 0x0f ), \
HID_UNIT ( HID_VARIABLE | HID_NONLINEAR ), \
HID_PHYSICAL_MIN( 0 ), \
HID_PHYSICAL_MAX( 0 ), \
HID_USAGE ( HID_USAGE_DESKTOP_X ), \
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
HID_USAGE ( HID_USAGE_DESKTOP_Y ), \
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
HID_COLLECTION_END , \
HID_COLLECTION_END \

// Absolute Mouse Report Descriptor Template
#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
Expand Down
Loading