diff --git a/README.md b/README.md index d512d1e28..919251243 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ TinyUSB is an open-source cross-platform USB Host/Device stack for embedded syst Support multiple device configurations by dynamically changing usb descriptors. Low power functions such as suspend, resume and remote wakeup. Following device classes are supported: - Communication Class (CDC) -- Human Interface Device (HID): Keyboard, Mouse, Gamepad etc ... +- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Mass Storage Class (MSC): with multiple LUNs - Musical Instrument Digital Interface (MIDI) diff --git a/examples/device/cdc_msc_hid/src/usb_descriptors.c b/examples/device/cdc_msc_hid/src/usb_descriptors.c index c8fca571f..72d280c2f 100644 --- a/examples/device/cdc_msc_hid/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid/src/usb_descriptors.c @@ -117,19 +117,22 @@ enum uint8_t const desc_configuration[] = { - // Config: self-powered with remote wakeup support, max power up to 100 mA + // Inteface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), #if CFG_TUD_CDC + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64), #endif #if CFG_TUD_MSC + // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 #endif #if CFG_TUD_HID - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_KEYBOARD, sizeof(desc_hid_report), 0x84, 16, 10) + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10) #endif }; diff --git a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c index 38f60a561..1faaaed66 100644 --- a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c @@ -117,19 +117,22 @@ enum uint8_t const desc_configuration[] = { - // Config: self-powered with remote wakeup support, max power up to 100 mA + // Inteface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), #if CFG_TUD_CDC + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64), #endif #if CFG_TUD_MSC + // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 #endif #if CFG_TUD_HID - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_KEYBOARD, sizeof(desc_hid_report), 0x84, 16, 10) + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10) #endif }; diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index 68909583b..231eb4fa6 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -59,8 +59,7 @@ tusb_desc_device_t const desc_device = //------------- HID Report Descriptor -------------// 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_GENERIC_INOUT(CFG_TUD_HID_BUFSIZE) }; //------------- Configuration Descriptor -------------// @@ -72,7 +71,7 @@ enum enum { - CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN }; // Use Endpoint 2 instead of 1 due to NXP MCU @@ -82,9 +81,11 @@ enum uint8_t const desc_configuration[] = { - // Config: self-powered with remote wakeup support, max power up to 100 mA + // Inteface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_KEYBOARD, sizeof(desc_hid_report), 0x84, 16, 10) + + // Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval + TUD_HID_INOUT_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x80 | EPNUM_HID, EPNUM_HID, 16, 10) }; //------------- String Descriptors -------------// diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index b91ccb04a..af2b1a091 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -75,12 +75,11 @@ enum uint8_t const desc_configuration[] = { - // Config: self-powered with remote wakeup support, max power up to 100 mA + // Inteface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), -#if CFG_TUD_MSC + // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 -#endif }; //------------- String Descriptors -------------// diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index a72fe9c86..7c702f4de 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -462,7 +462,7 @@ enum { HID_USAGE_PAGE_MSR = 0x8e, HID_USAGE_PAGE_CAMERA = 0x90, HID_USAGE_PAGE_ARCADE = 0x91, - HID_USAGE_PAGE_VENDOR = 0xFFFF // 0xFF00 - 0xFFFF + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index 1120e8e45..825be2181 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -108,8 +108,9 @@ ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate); HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ - /* 8 bits Modifier Keys (Shfit, Control, Alt) */ \ + /* Report ID if any */\ __VA_ARGS__ \ + /* 8 bits Modifier Keys (Shfit, Control, Alt) */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\ HID_USAGE_MIN ( 224 ) ,\ HID_USAGE_MAX ( 231 ) ,\ @@ -149,6 +150,7 @@ ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate); HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ __VA_ARGS__ \ HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\ HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ @@ -197,6 +199,7 @@ ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate); HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\ HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ __VA_ARGS__ \ HID_LOGICAL_MIN ( 0x00 ) ,\ HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\ @@ -217,6 +220,7 @@ ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate); HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ __VA_ARGS__ \ /* 2 bit system power control */ \ HID_LOGICAL_MIN ( 1 ) ,\ @@ -240,6 +244,7 @@ ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate); HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\ HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ __VA_ARGS__ \ /* 16 bit Button Map */ \ HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ @@ -263,6 +268,31 @@ ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate); HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ HID_COLLECTION_END \ +// HID Generic Input & Output +// - 1st parameter is report size (mandatory) +// - 2nd parameter is report id HID_REPORT_ID(n) (optional) +#define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \ + HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\ + HID_USAGE ( 0x01 ),\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\ + /* Report ID if any */\ + __VA_ARGS__ \ + /* Input */ \ + HID_USAGE ( 0x02 ),\ + HID_LOGICAL_MIN ( 0x00 ),\ + HID_LOGICAL_MAX ( 0xff ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT( report_size ),\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + /* Output */ \ + HID_USAGE ( 0x03 ),\ + HID_LOGICAL_MIN ( 0x00 ),\ + HID_LOGICAL_MAX ( 0xff ),\ + HID_REPORT_SIZE ( 8 ),\ + HID_REPORT_COUNT( report_size ),\ + HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\ + HID_COLLECTION_END \ + /*-------------------------------------------------------------------- * ASCII to KEYCODE Conversion * Expand to array of [128][2] (shift, keycode) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 7d57a7950..909deffa8 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -169,7 +169,7 @@ enum { #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) -/// Device State +/// Device State TODO remove typedef enum { TUSB_DEVICE_STATE_UNPLUG = 0 , @@ -184,7 +184,7 @@ typedef enum XFER_RESULT_STALLED, }xfer_result_t; -enum +enum // TODO remove { DESC_OFFSET_LEN = 0, DESC_OFFSET_TYPE = 1 diff --git a/src/device/usbd.h b/src/device/usbd.h index de59731a2..8debbf535 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -107,7 +107,7 @@ ATTR_WEAK void tud_resume_cb(void); #define TUD_CDC_DESC_LEN (8+9+5+5+4+5+7+9+7+7) // CDC Descriptor Template -// interface number, string index, EP notification address and size, EP data address (out,in) and size. +// Interface number, string index, EP notification address and size, EP data address (out, in) and size. #define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \ /* Interface Associate */\ 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, 0,\ @@ -149,15 +149,31 @@ ATTR_WEAK void tud_resume_cb(void); // Length of template descriptor: 25 bytes #define TUD_HID_DESC_LEN (9 + 9 + 7) +// HID Input only descriptor // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval #define TUD_HID_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epsize, _ep_interval) \ /* Interface */\ 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_HID, (_boot_protocol) ? HID_SUBCLASS_BOOT : 0, _boot_protocol, _stridx,\ /* HID descriptor */\ 9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\ - /* Endpoint descriptor */\ + /* Endpoint In */\ 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval +// Length of template descriptor: 32 bytes +#define TUD_HID_INOUT_DESC_LEN (9 + 9 + 7 + 7) + +// HID Input & Output descriptor +// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval +#define TUD_HID_INOUT_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epout, _epsize, _ep_interval) \ + /* Interface */\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_HID, (_boot_protocol) ? HID_SUBCLASS_BOOT : 0, _boot_protocol, _stridx,\ + /* HID descriptor */\ + 9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\ + /* Endpoint In */\ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval,\ + /* Endpoint Out */\ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval + #ifdef __cplusplus } #endif diff --git a/tools/build_all.py b/tools/build_all.py index 8a945712e..4f1bc2636 100644 --- a/tools/build_all.py +++ b/tools/build_all.py @@ -4,7 +4,7 @@ import sys import subprocess import time -all_device_example = ["cdc_msc_hid", "msc_dual_lun"] +all_device_example = ["cdc_msc_hid", "msc_dual_lun", "hid_generic_inout"] all_boards = ["metro_m0_express", "metro_m4_express", "pca10056", "stm32f407g_disc1"] for example in all_device_example: