summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/class/audio/audio.h65
-rw-r--r--src/class/audio/audio_device.c2
-rw-r--r--src/class/hid/hid.h2205
-rw-r--r--src/class/midi/midi2_device.c204
-rw-r--r--src/class/midi/midi2_device.h28
-rw-r--r--src/class/mtp/mtp_device.c18
-rw-r--r--src/class/net/ncm_device.c47
-rw-r--r--src/class/usbtmc/usbtmc_device.c21
-rw-r--r--src/class/usbtmc/usbtmc_device.h1
-rw-r--r--src/class/vendor/vendor_host.c127
-rw-r--r--src/class/vendor/vendor_host.h48
-rw-r--r--src/class/video/video_device.c3
-rw-r--r--src/common/tusb_mcu.h27
-rw-r--r--src/common/tusb_types.h2
-rw-r--r--src/device/dcd.h26
-rw-r--r--src/device/usbd.c51
-rw-r--r--src/device/usbd.h2
-rw-r--r--src/host/usbh.c11
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_imxrt.h3
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h5
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_type.h25
-rw-r--r--src/portable/chipidea/ci_hs/dcd_ci_hs.c250
-rw-r--r--src/portable/chipidea/ci_hs/hcd_ci_hs.c4
-rw-r--r--src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c106
-rw-r--r--src/portable/ohci/ohci.c83
-rw-r--r--src/portable/ohci/ohci.h4
-rw-r--r--src/portable/raspberrypi/rp2040/dcd_rp2040.c3
-rw-r--r--src/portable/raspberrypi/rp2040/hcd_rp2040.c4
-rw-r--r--src/portable/raspberrypi/rp2040/rp2040_usb.c4
-rw-r--r--src/portable/raspberrypi/rp2040/rp2040_usb.h1
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_apm32.h77
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_common.h2
-rw-r--r--src/portable/synopsys/dwc2/dcd_dwc2.c7
-rw-r--r--src/tinyusb.mk1
-rw-r--r--src/tusb.h3
-rw-r--r--src/tusb_option.h6
37 files changed, 2499 insertions, 978 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b3e05f60f..e113f2d88 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -31,7 +31,6 @@ function(tinyusb_sources_get OUTPUT_VAR)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/midi/midi2_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/msc/msc_host.c
- ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_host.c
# typec
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/typec/usbc.c
PARENT_SCOPE
diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h
index 7981396c2..82db9ed9e 100644
--- a/src/class/audio/audio.h
+++ b/src/class/audio/audio.h
@@ -83,6 +83,71 @@ typedef enum {
AUDIO_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307,
} audio_terminal_output_type_t;
+/// 2.4 - Audio Class-Bi-directional Terminal Types UAC2
+typedef enum
+{
+ AUDIO_TERM_TYPE_BI_DIRECTIONAL_UNDEFINED = 0x0400,
+ AUDIO_TERM_TYPE_BI_DIRECTIONAL_HEADSET_HAND_HELD = 0x0401,
+ AUDIO_TERM_TYPE_BI_DIRECTIONAL_HEADSET_MOUNTED = 0x0402,
+ AUDIO_TERM_TYPE_BI_DIRECTIONAL_SPEAKERPHONE = 0x0403,
+ AUDIO_TERM_TYPE_BI_DIRECTIONAL_SPEAKERPHONE_ECHO_SUPPRESS = 0x0404,
+ AUDIO_TERM_TYPE_BI_DIRECTIONAL_SPEAKERPHONE_ECHO_CANCEL = 0x0405,
+} audio_terminal_bi_directional_type_t;
+
+/// 2.5 - Audio Class-Telephone Terminal Types UAC2
+typedef enum
+{
+ AUDIO_TERM_TYPE_TELEPHONE_UNDEFINED = 0x0500,
+ AUDIO_TERM_TYPE_TELEPHONE_PHONE_LINE = 0x0501,
+ AUDIO_TERM_TYPE_TELEPHONE_TELEPHONE = 0x0502,
+ AUDIO_TERM_TYPE_TELEPHONE_DOWN_LINE_PHONE = 0x0503,
+} audio_terminal_telephony_type_t;
+
+/// 2.6 - Audio Class-External Types UAC2
+typedef enum
+{
+ AUDIO_TERM_TYPE_EXTERNAL_UNDEFINED = 0x0600,
+ AUDIO_TERM_TYPE_EXTERNAL_ANALOG_CONNECTOR = 0x0601,
+ AUDIO_TERM_TYPE_EXTERNAL_DIGITAL_AUDIO = 0x0602,
+ AUDIO_TERM_TYPE_EXTERNAL_LINE_CONNECTOR = 0x0603,
+ AUDIO_TERM_TYPE_EXTERNAL_LEGACY_AUDIO_CONNECTOR = 0x0604,
+ AUDIO_TERM_TYPE_EXTERNAL_SPDIF_INTERFACE = 0x0605,
+ AUDIO_TERM_TYPE_EXTERNAL_1394_DA_STREAM = 0x0606,
+ AUDIO_TERM_TYPE_EXTERNAL_1394_DV_STREAM_SOUNDTRACK = 0x0607,
+ AUDIO_TERM_TYPE_EXTERNAL_ADAT_LIGHTPIPE = 0x0608,
+ AUDIO_TERM_TYPE_EXTERNAL_TDIF = 0x0609,
+ AUDIO_TERM_TYPE_EXTERNAL_MADI = 0x060A,
+} audio_terminal_external_type_t;
+
+/// 2.7 - Audio Class-Embedded Types UAC2
+typedef enum
+{
+ AUDIO_TERM_TYPE_EMBEDDED_UNDEFINED = 0x0700,
+ AUDIO_TERM_TYPE_EMBEDDED_LEVEL_CALIBRATION_NOISE_SOURCE = 0x0701,
+ AUDIO_TERM_TYPE_EMBEDDED_EQUALIZATION_NOISE = 0x0702,
+ AUDIO_TERM_TYPE_EMBEDDED_CD_PLAYER = 0x0703,
+ AUDIO_TERM_TYPE_EMBEDDED_DAT = 0x0704,
+ AUDIO_TERM_TYPE_EMBEDDED_DCC = 0x0705,
+ AUDIO_TERM_TYPE_EMBEDDED_COMPRESSED_AUDIO_PLAYER = 0x0706,
+ AUDIO_TERM_TYPE_EMBEDDED_ANALOG_TAPE = 0x0707,
+ AUDIO_TERM_TYPE_EMBEDDED_PHONOGRAPH = 0x0708,
+ AUDIO_TERM_TYPE_EMBEDDED_VCR_AUDIO = 0x0709,
+ AUDIO_TERM_TYPE_EMBEDDED_VIDEO_DISC_AUDIO = 0x070A,
+ AUDIO_TERM_TYPE_EMBEDDED_DVD_AUDIO = 0x070B,
+ AUDIO_TERM_TYPE_EMBEDDED_TV_TUNER_AUDIO = 0x070C,
+ AUDIO_TERM_TYPE_EMBEDDED_SATELLITE_RECEIVER_AUDIO = 0x070D,
+ AUDIO_TERM_TYPE_EMBEDDED_CABLE_TUNER_AUDIO = 0x070E,
+ AUDIO_TERM_TYPE_EMBEDDED_DSS_AUDIO = 0x070F,
+ AUDIO_TERM_TYPE_EMBEDDED_RADIO_RECEIVER = 0x0710,
+ AUDIO_TERM_TYPE_EMBEDDED_RADIO_TRANSMITTER = 0x0711,
+ AUDIO_TERM_TYPE_EMBEDDED_MULTI_TRACK_RECORDER = 0x0712,
+ AUDIO_TERM_TYPE_EMBEDDED_SYNTHESIZER = 0x0713,
+ AUDIO_TERM_TYPE_EMBEDDED_PIANO = 0x0714,
+ AUDIO_TERM_TYPE_EMBEDDED_GUITAR = 0x0715,
+ AUDIO_TERM_TYPE_EMBEDDED_DRUMS = 0x0716,
+ AUDIO_TERM_TYPE_EMBEDDED_OTHER_MUSICAL_INSTRUMENT = 0x0717,
+} audio_terminal_embedded_type_t;
+
/// Rest is yet to be implemented
//--------------------------------------------------------------------+
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index 94881521a..bc4c7e544 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -1841,7 +1841,7 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t *audio) {
static uint16_t audiod_tx_packet_size(const uint16_t *nominal_size, uint16_t data_count, uint16_t fifo_depth, uint16_t fifo_threshold, uint16_t max_depth) {
// Flow control need a FIFO size of at least 4*Navg
- if (nominal_size[1] && nominal_size[1] <= fifo_depth * 4) {
+ if (nominal_size[1] && nominal_size[1] * 4 <= fifo_depth) {
// Use blackout to prioritize normal size packet
static int ctrl_blackout = 0;
uint16_t packet_size;
diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h
index 50a206ced..a6d1dba15 100644
--- a/src/class/hid/hid.h
+++ b/src/class/hid/hid.h
@@ -368,7 +368,7 @@ typedef enum
/// @}
//--------------------------------------------------------------------+
-// HID KEYCODE
+// HID KEYCODE - defined by HID Usage Table: Keyboard/Keypad Page (0x07)
//--------------------------------------------------------------------+
#define HID_KEY_NONE 0x00
#define HID_KEY_A 0x04
@@ -772,11 +772,12 @@ enum {
HID_USAGE_PAGE_KEYBOARD = 0x07,
HID_USAGE_PAGE_LED = 0x08,
HID_USAGE_PAGE_BUTTON = 0x09,
- HID_USAGE_PAGE_ORDINAL = 0x0a,
- HID_USAGE_PAGE_TELEPHONY = 0x0b,
- HID_USAGE_PAGE_CONSUMER = 0x0c,
- HID_USAGE_PAGE_DIGITIZER = 0x0d,
- HID_USAGE_PAGE_PID = 0x0f,
+ HID_USAGE_PAGE_ORDINAL = 0x0A,
+ HID_USAGE_PAGE_TELEPHONY = 0x0B,
+ HID_USAGE_PAGE_CONSUMER = 0x0C,
+ HID_USAGE_PAGE_DIGITIZER = 0x0D,
+ HID_USAGE_PAGE_HAPTIC = 0x0E,
+ HID_USAGE_PAGE_PID = 0x0F,
HID_USAGE_PAGE_UNICODE = 0x10,
HID_USAGE_PAGE_SOC = 0x11,
HID_USAGE_PAGE_EYE_AND_HEAD_TRACKERS = 0x12,
@@ -786,528 +787,1091 @@ enum {
HID_USAGE_PAGE_SENSORS = 0x20,
// 0x21 - 0x3f is reserved
HID_USAGE_PAGE_MEDICAL_INSTRUMENT = 0x40,
+ HID_USAGE_PAGE_BRAILLE_DISPLAY = 0x41,
HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59,
HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83
HID_USAGE_PAGE_POWER = 0x84,
HID_USAGE_PAGE_BATTERY = 0x85,
// 0x86 - 0x87 is reserved for Power Device
- HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c,
- HID_USAGE_PAGE_SCALE = 0x8d,
- HID_USAGE_PAGE_MSR = 0x8e,
+ HID_USAGE_PAGE_BARCODE_SCANNER = 0x8C,
+ HID_USAGE_PAGE_SCALE = 0x8D,
+ HID_USAGE_PAGE_MSR = 0x8E,
HID_USAGE_PAGE_CAMERA = 0x90,
HID_USAGE_PAGE_ARCADE = 0x91,
+ HID_USAGE_PAGE_GAMING = 0x92, // Gaming Standards Association (GSA) HID usage page
HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page
HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF
};
/// HID Usage Table - Table 6: Generic Desktop Page
enum {
- HID_USAGE_DESKTOP_POINTER = 0x01,
- HID_USAGE_DESKTOP_MOUSE = 0x02,
- HID_USAGE_DESKTOP_JOYSTICK = 0x04,
- HID_USAGE_DESKTOP_GAMEPAD = 0x05,
- HID_USAGE_DESKTOP_KEYBOARD = 0x06,
- HID_USAGE_DESKTOP_KEYPAD = 0x07,
- HID_USAGE_DESKTOP_MULTI_AXIS_CONTROLLER = 0x08,
- HID_USAGE_DESKTOP_TABLET_PC_SYSTEM = 0x09,
- HID_USAGE_DESKTOP_X = 0x30,
- HID_USAGE_DESKTOP_Y = 0x31,
- HID_USAGE_DESKTOP_Z = 0x32,
- HID_USAGE_DESKTOP_RX = 0x33,
- HID_USAGE_DESKTOP_RY = 0x34,
- HID_USAGE_DESKTOP_RZ = 0x35,
- HID_USAGE_DESKTOP_SLIDER = 0x36,
- HID_USAGE_DESKTOP_DIAL = 0x37,
- HID_USAGE_DESKTOP_WHEEL = 0x38,
- HID_USAGE_DESKTOP_HAT_SWITCH = 0x39,
- HID_USAGE_DESKTOP_COUNTED_BUFFER = 0x3a,
- HID_USAGE_DESKTOP_BYTE_COUNT = 0x3b,
- HID_USAGE_DESKTOP_MOTION_WAKEUP = 0x3c,
- HID_USAGE_DESKTOP_START = 0x3d,
- HID_USAGE_DESKTOP_SELECT = 0x3e,
- HID_USAGE_DESKTOP_VX = 0x40,
- HID_USAGE_DESKTOP_VY = 0x41,
- HID_USAGE_DESKTOP_VZ = 0x42,
- HID_USAGE_DESKTOP_VBRX = 0x43,
- HID_USAGE_DESKTOP_VBRY = 0x44,
- HID_USAGE_DESKTOP_VBRZ = 0x45,
- HID_USAGE_DESKTOP_VNO = 0x46,
- HID_USAGE_DESKTOP_FEATURE_NOTIFICATION = 0x47,
- HID_USAGE_DESKTOP_RESOLUTION_MULTIPLIER = 0x48,
- HID_USAGE_DESKTOP_SYSTEM_CONTROL = 0x80,
- HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN = 0x81,
- HID_USAGE_DESKTOP_SYSTEM_SLEEP = 0x82,
- HID_USAGE_DESKTOP_SYSTEM_WAKE_UP = 0x83,
- HID_USAGE_DESKTOP_SYSTEM_CONTEXT_MENU = 0x84,
- HID_USAGE_DESKTOP_SYSTEM_MAIN_MENU = 0x85,
- HID_USAGE_DESKTOP_SYSTEM_APP_MENU = 0x86,
- HID_USAGE_DESKTOP_SYSTEM_MENU_HELP = 0x87,
- HID_USAGE_DESKTOP_SYSTEM_MENU_EXIT = 0x88,
- HID_USAGE_DESKTOP_SYSTEM_MENU_SELECT = 0x89,
- HID_USAGE_DESKTOP_SYSTEM_MENU_RIGHT = 0x8A,
- HID_USAGE_DESKTOP_SYSTEM_MENU_LEFT = 0x8B,
- HID_USAGE_DESKTOP_SYSTEM_MENU_UP = 0x8C,
- HID_USAGE_DESKTOP_SYSTEM_MENU_DOWN = 0x8D,
- HID_USAGE_DESKTOP_SYSTEM_COLD_RESTART = 0x8E,
- HID_USAGE_DESKTOP_SYSTEM_WARM_RESTART = 0x8F,
- HID_USAGE_DESKTOP_DPAD_UP = 0x90,
- HID_USAGE_DESKTOP_DPAD_DOWN = 0x91,
- HID_USAGE_DESKTOP_DPAD_RIGHT = 0x92,
- HID_USAGE_DESKTOP_DPAD_LEFT = 0x93,
- HID_USAGE_DESKTOP_SYSTEM_DOCK = 0xA0,
- HID_USAGE_DESKTOP_SYSTEM_UNDOCK = 0xA1,
- HID_USAGE_DESKTOP_SYSTEM_SETUP = 0xA2,
- HID_USAGE_DESKTOP_SYSTEM_BREAK = 0xA3,
- HID_USAGE_DESKTOP_SYSTEM_DEBUGGER_BREAK = 0xA4,
- HID_USAGE_DESKTOP_APPLICATION_BREAK = 0xA5,
- HID_USAGE_DESKTOP_APPLICATION_DEBUGGER_BREAK = 0xA6,
- HID_USAGE_DESKTOP_SYSTEM_SPEAKER_MUTE = 0xA7,
- HID_USAGE_DESKTOP_SYSTEM_HIBERNATE = 0xA8,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INVERT = 0xB0,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INTERNAL = 0xB1,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_EXTERNAL = 0xB2,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_BOTH = 0xB3,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_DUAL = 0xB4,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY = 0xB6,
- HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7
+ HID_USAGE_DESKTOP_POINTER = 0x01, // CP
+ HID_USAGE_DESKTOP_MOUSE = 0x02, // CA
+ // 03 Reserved
+
+ HID_USAGE_DESKTOP_JOYSTICK = 0x04, // CA
+ HID_USAGE_DESKTOP_GAMEPAD = 0x05, // CA
+ HID_USAGE_DESKTOP_KEYBOARD = 0x06, // CA
+ HID_USAGE_DESKTOP_KEYPAD = 0x07, // CA
+ HID_USAGE_DESKTOP_MULTI_AXIS_CONTROLLER = 0x08, // CA
+ HID_USAGE_DESKTOP_TABLET_PC_SYSTEM = 0x09, // CA
+ HID_USAGE_DESKTOP_WATER_COOLING = 0x0A, // CA
+ HID_USAGE_DESKTOP_COMPUTER_CHASSIS = 0x0B, // CA
+ HID_USAGE_DESKTOP_WIRELESS_RADIO = 0x0C, // CA
+ HID_USAGE_DESKTOP_PORTABLE_DEVICE = 0x0D, // CA
+ HID_USAGE_DESKTOP_SYSTEM_MULTI_AXIS_CONTROLLER = 0x0E, // CA
+ HID_USAGE_DESKTOP_SPATIAL_CONTROLLER = 0x0F, // CA
+ HID_USAGE_DESKTOP_ASSISTIVE = 0x10, // CA
+ HID_USAGE_DESKTOP_DEVICE_DOCK = 0x11, // CA
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE = 0x12, // CA
+ HID_USAGE_DESKTOP_CALL_STATE_MANAGEMENT = 0x13, // CA
+ // 14-2F Reserved
+
+ HID_USAGE_DESKTOP_X = 0x30, // DV
+ HID_USAGE_DESKTOP_Y = 0x31, // DV
+ HID_USAGE_DESKTOP_Z = 0x32, // DV
+ HID_USAGE_DESKTOP_RX = 0x33, // DV
+ HID_USAGE_DESKTOP_RY = 0x34, // DV
+ HID_USAGE_DESKTOP_RZ = 0x35, // DV
+ HID_USAGE_DESKTOP_SLIDER = 0x36, // DV
+ HID_USAGE_DESKTOP_DIAL = 0x37, // DV
+ HID_USAGE_DESKTOP_WHEEL = 0x38, // DV
+ HID_USAGE_DESKTOP_HAT_SWITCH = 0x39, // DV
+ HID_USAGE_DESKTOP_COUNTED_BUFFER = 0x3A, // CL
+ HID_USAGE_DESKTOP_BYTE_COUNT = 0x3B, // DV
+ HID_USAGE_DESKTOP_MOTION_WAKEUP = 0x3C, // OSC/DF
+ HID_USAGE_DESKTOP_START = 0x3D, // OOC
+ HID_USAGE_DESKTOP_SELECT = 0x3E, // OOC
+ // 3F Reserved
+
+ HID_USAGE_DESKTOP_VX = 0x40, // DV
+ HID_USAGE_DESKTOP_VY = 0x41, // DV
+ HID_USAGE_DESKTOP_VZ = 0x42, // DV
+ HID_USAGE_DESKTOP_VBRX = 0x43, // DV
+ HID_USAGE_DESKTOP_VBRY = 0x44, // DV
+ HID_USAGE_DESKTOP_VBRZ = 0x45, // DV
+ HID_USAGE_DESKTOP_VNO = 0x46, // DV
+ HID_USAGE_DESKTOP_FEATURE_NOTIFICATION = 0x47, // DV/DF
+ HID_USAGE_DESKTOP_RESOLUTION_MULTIPLIER = 0x48, // DV
+ HID_USAGE_DESKTOP_QX = 0x49, // DV
+ HID_USAGE_DESKTOP_QY = 0x4A, // DV
+ HID_USAGE_DESKTOP_QZ = 0x4B, // DV
+ HID_USAGE_DESKTOP_QW = 0x4C, // DV
+ // 4D-7F Reserved
+
+ HID_USAGE_DESKTOP_SYSTEM_CONTROL = 0x80, // CA
+ HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN = 0x81, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_SLEEP = 0x82, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_WAKE_UP = 0x83, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_CONTEXT_MENU = 0x84, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_MAIN_MENU = 0x85, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_APP_MENU = 0x86, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_MENU_HELP = 0x87, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_MENU_EXIT = 0x88, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_MENU_SELECT = 0x89, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_MENU_RIGHT = 0x8A, // RTC
+ HID_USAGE_DESKTOP_SYSTEM_MENU_LEFT = 0x8B, // RTC
+ HID_USAGE_DESKTOP_SYSTEM_MENU_UP = 0x8C, // RTC
+ HID_USAGE_DESKTOP_SYSTEM_MENU_DOWN = 0x8D, // RTC
+ HID_USAGE_DESKTOP_SYSTEM_COLD_RESTART = 0x8E, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_WARM_RESTART = 0x8F, // OSC
+ HID_USAGE_DESKTOP_DPAD_UP = 0x90, // OOC
+ HID_USAGE_DESKTOP_DPAD_DOWN = 0x91, // OOC
+ HID_USAGE_DESKTOP_DPAD_RIGHT = 0x92, // OOC
+ HID_USAGE_DESKTOP_DPAD_LEFT = 0x93, // OOC
+ HID_USAGE_DESKTOP_INDEX_TRIGGER = 0x94, // MC/DV
+ HID_USAGE_DESKTOP_PALM_TRIGGER = 0x95, // MC/DV
+ HID_USAGE_DESKTOP_THUMBSTICK = 0x96, // CP
+ HID_USAGE_DESKTOP_SYSTEM_FUNCTION_SHIFT = 0x97, // MC
+ HID_USAGE_DESKTOP_SYSTEM_FUNCTION_SHIFT_LOCK = 0x98, // OOC
+ HID_USAGE_DESKTOP_SYSTEM_FUNCTION_SHIFT_LOCK_INDICATOR = 0x99, // DV
+ HID_USAGE_DESKTOP_SYSTEM_DISMISS_NOTIFICATION = 0x9A, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DO_NOT_DISTURB = 0x9B, // OOC
+ // 9C-9F Reserved
+
+ HID_USAGE_DESKTOP_SYSTEM_DOCK = 0xA0, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_UNDOCK = 0xA1, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_SETUP = 0xA2, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_BREAK = 0xA3, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DEBUGGER_BREAK = 0xA4, // OSC
+ HID_USAGE_DESKTOP_APPLICATION_BREAK = 0xA5, // OSC
+ HID_USAGE_DESKTOP_APPLICATION_DEBUGGER_BREAK = 0xA6, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_SPEAKER_MUTE = 0xA7, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_HIBERNATE = 0xA8, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_MICROPHONE_MUTE = 0xA9, // OOC
+ HID_USAGE_DESKTOP_SYSTEM_ACCESSIBILITY_BINDING = 0xAA, // OOC
+ // AB-AF Reserved
+
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INVERT = 0xB0, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_INTERNAL = 0xB1, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_EXTERNAL = 0xB2, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_BOTH = 0xB3, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_DUAL = 0xB4, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_SWAP_PRIMARY_SECONDARY = 0xB6, // OSC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7, // OSC
+ // B8-BF Reserved
+
+ HID_USAGE_DESKTOP_SENSOR_ZONE = 0xC0, // CL
+ HID_USAGE_DESKTOP_RPM = 0xC1, // DV
+ HID_USAGE_DESKTOP_COOLANT_LEVEL = 0xC2, // DV
+ HID_USAGE_DESKTOP_COOLANT_CRITICAL_LEVEL = 0xC3, // SV
+ HID_USAGE_DESKTOP_COOLANT_PUMP = 0xC4, // US
+ HID_USAGE_DESKTOP_CHASSIS_ENCLOSURE = 0xC5, // CL
+ HID_USAGE_DESKTOP_WIRELESS_RADIO_BUTTON = 0xC6, // OOC
+ HID_USAGE_DESKTOP_WIRELESS_RADIO_LED = 0xC7, // OOC
+ HID_USAGE_DESKTOP_WIRELESS_RADIO_SLIDER_SWITCH = 0xC8, // OOC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_ROTATION_LOCK_BUTTON = 0xC9, // OOC
+ HID_USAGE_DESKTOP_SYSTEM_DISPLAY_ROTATION_LOCK_SLIDER_SWITCH = 0xCA, // OOC
+ HID_USAGE_DESKTOP_CONTROL_ENABLE = 0xCB, // DF
+ // CC-CF Reserved
+
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE_UNIQUE_ID = 0xD0, // DV
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE_VENDOR_ID = 0xD1, // DV
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE_PRIMARY_USAGE_PAGE = 0xD2, // DV
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE_PRIMARY_USAGE_ID = 0xD3, // DV
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE_DOCKING_STATE = 0xD4, // DF
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE_DISPLAY_OCCLUSION = 0xD5, // CL
+ HID_USAGE_DESKTOP_DOCKABLE_DEVICE_OBJECT_TYPE = 0xD6, // DV
+ // D7-DF Reserved
+
+ HID_USAGE_DESKTOP_CALL_ACTIVE_LED = 0xE0, // OOC
+ HID_USAGE_DESKTOP_CALL_MUTE_TOGGLE = 0xE1, // OSC
+ HID_USAGE_DESKTOP_CALL_MUTE_LED = 0xE2 // OOC
+ // E3-FFFF Reserved
+};
+
+/// HID Usage Table: Simulation Controls Page (0x02)
+enum {
+ HID_USAGE_SIMULATION_CONTROLS_FLIGHT_SIMULATION_DEVICE = 0x01, // CA
+ HID_USAGE_SIMULATION_CONTROLS_AUTOMOBILE_SIMULATION_DEVICE = 0x02, // CA
+ HID_USAGE_SIMULATION_CONTROLS_TANK_SIMULATION_DEVICE = 0x03, // CA
+ HID_USAGE_SIMULATION_CONTROLS_SPACESHIP_SIMULATION_DEVICE = 0x04, // CA
+ HID_USAGE_SIMULATION_CONTROLS_SUBMARINE_SIMULATION_DEVICE = 0x05, // CA
+ HID_USAGE_SIMULATION_CONTROLS_SAILING_SIMULATION_DEVICE = 0x06, // CA
+ HID_USAGE_SIMULATION_CONTROLS_MOTORCYCLE_SIMULATION_DEVICE = 0x07, // CA
+ HID_USAGE_SIMULATION_CONTROLS_SPORTS_SIMULATION_DEVICE = 0x08, // CA
+ HID_USAGE_SIMULATION_CONTROLS_AIRPLANE_SIMULATION_DEVICE = 0x09, // CA
+ HID_USAGE_SIMULATION_CONTROLS_HELICOPTER_SIMULATION_DEVICE = 0x0A, // CA
+ HID_USAGE_SIMULATION_CONTROLS_MAGIC_CARPET_SIMULATION_DEVICE = 0x0B, // CA
+ HID_USAGE_SIMULATION_CONTROLS_BICYCLE_SIMULATION_DEVICE = 0x0C, // CA
+ // 0D-1F Reserved
+
+ HID_USAGE_SIMULATION_CONTROLS_FLIGHT_CONTROL_STICK = 0x20, // CA
+ HID_USAGE_SIMULATION_CONTROLS_FLIGHT_STICK = 0x21, // CA
+ HID_USAGE_SIMULATION_CONTROLS_CYCLIC_CONTROL = 0x22, // CP
+ HID_USAGE_SIMULATION_CONTROLS_CYCLIC_TRIM = 0x23, // CP
+ HID_USAGE_SIMULATION_CONTROLS_FLIGHT_YOKE = 0x24, // CA
+ HID_USAGE_SIMULATION_CONTROLS_TRACK_CONTROL = 0x25, // CP
+ // 26-AF Reserved
+
+ HID_USAGE_SIMULATION_CONTROLS_AILERON = 0xB0, // DV
+ HID_USAGE_SIMULATION_CONTROLS_AILERON_TRIM = 0xB1, // DV
+ HID_USAGE_SIMULATION_CONTROLS_ANTI_TORQUE_CONTROL = 0xB2, // DV
+ HID_USAGE_SIMULATION_CONTROLS_AUTOPILOT_ENABLE = 0xB3, // OOC
+ HID_USAGE_SIMULATION_CONTROLS_CHAFF_RELEASE = 0xB4, // OSC
+ HID_USAGE_SIMULATION_CONTROLS_COLLECTIVE_CONTROL = 0xB5, // DV
+ HID_USAGE_SIMULATION_CONTROLS_DIVE_BRAKE = 0xB6, // DV
+ HID_USAGE_SIMULATION_CONTROLS_ELECTRONIC_COUNTERMEASURES = 0xB7, // OOC
+ HID_USAGE_SIMULATION_CONTROLS_ELEVATOR = 0xB8, // DV
+ HID_USAGE_SIMULATION_CONTROLS_ELEVATOR_TRIM = 0xB9, // DV
+ HID_USAGE_SIMULATION_CONTROLS_RUDDER = 0xBA, // DV
+ HID_USAGE_SIMULATION_CONTROLS_THROTTLE = 0xBB, // DV
+ HID_USAGE_SIMULATION_CONTROLS_FLIGHT_COMMUNICATIONS = 0xBC, // OOC
+ HID_USAGE_SIMULATION_CONTROLS_FLARE_RELEASE = 0xBD, // OSC
+ HID_USAGE_SIMULATION_CONTROLS_LANDING_GEAR = 0xBE, // OOC
+ HID_USAGE_SIMULATION_CONTROLS_TOE_BRAKE = 0xBF, // DV
+ HID_USAGE_SIMULATION_CONTROLS_TRIGGER = 0xC0, // MC
+ HID_USAGE_SIMULATION_CONTROLS_WEAPONS_ARM = 0xC1, // OOC
+ HID_USAGE_SIMULATION_CONTROLS_WEAPONS_SELECT = 0xC2, // OSC
+ HID_USAGE_SIMULATION_CONTROLS_WING_FLAPS = 0xC3, // DV
+ HID_USAGE_SIMULATION_CONTROLS_ACCELERATOR = 0xC4, // DV
+ HID_USAGE_SIMULATION_CONTROLS_BRAKE = 0xC5, // DV
+ HID_USAGE_SIMULATION_CONTROLS_CLUTCH = 0xC6, // DV
+ HID_USAGE_SIMULATION_CONTROLS_SHIFTER = 0xC7, // DV
+ HID_USAGE_SIMULATION_CONTROLS_STEERING = 0xC8, // DV
+ HID_USAGE_SIMULATION_CONTROLS_TURRET_DIRECTION = 0xC9, // DV
+ HID_USAGE_SIMULATION_CONTROLS_BARREL_ELEVATION = 0xCA, // DV
+ HID_USAGE_SIMULATION_CONTROLS_DIVE_PLANE = 0xCB, // DV
+ HID_USAGE_SIMULATION_CONTROLS_BALLAST = 0xCC, // DV
+ HID_USAGE_SIMULATION_CONTROLS_BICYCLE_CRANK = 0xCD, // DV
+ HID_USAGE_SIMULATION_CONTROLS_HANDLE_BARS = 0xCE, // DV
+ HID_USAGE_SIMULATION_CONTROLS_FRONT_BRAKE = 0xCF, // DV
+ HID_USAGE_SIMULATION_CONTROLS_REAR_BRAKE = 0xD0, // DV
+ // D1-FFFF Reserved
+};
+
+/// HID Usage Table: VR Controls Page (0x03)
+enum {
+ HID_USAGE_VR_CONTROLS_BELT = 0x01, // CA
+ HID_USAGE_VR_CONTROLS_BODY_SUIT = 0x02, // CA
+ HID_USAGE_VR_CONTROLS_FLEXOR = 0x03, // CP
+ HID_USAGE_VR_CONTROLS_GLOVE = 0x04, // CA
+ HID_USAGE_VR_CONTROLS_HEAD_TRACKER = 0x05, // CP
+ HID_USAGE_VR_CONTROLS_HEAD_MOUNTED_DISPLAY = 0x06, // CA
+ HID_USAGE_VR_CONTROLS_HAND_TRACKER = 0x07, // CA
+ HID_USAGE_VR_CONTROLS_OCULOMETER = 0x08, // CA
+ HID_USAGE_VR_CONTROLS_VEST = 0x09, // CA
+ HID_USAGE_VR_CONTROLS_ANIMATRONIC_DEVICE = 0x0A, // CA
+ // 0B-1F Reserved
+
+ HID_USAGE_VR_CONTROLS_STEREO_ENABLE = 0x20, // OOC
+ HID_USAGE_VR_CONTROLS_DISPLAY_ENABLE = 0x21 // OOC
+ // 22-FFFF Reserved
+};
+
+/// HID Usage Table: Sports Controls Page (0x04)
+enum {
+ HID_USAGE_SPORTS_CONTROLS_BASEBALL_BAT = 0x01, // CA
+ HID_USAGE_SPORTS_CONTROLS_GOLF_CLUB = 0x02, // CA
+ HID_USAGE_SPORTS_CONTROLS_ROWING_MACHINE = 0x03, // CA
+ HID_USAGE_SPORTS_CONTROLS_TREADMILL = 0x04, // CA
+ // 05-2F Reserved
+
+ HID_USAGE_SPORTS_CONTROLS_OAR = 0x30, // DV
+ HID_USAGE_SPORTS_CONTROLS_SLOPE = 0x31, // DV
+ HID_USAGE_SPORTS_CONTROLS_RATE = 0x32, // DV
+ HID_USAGE_SPORTS_CONTROLS_STICK_SPEED = 0x33, // DV
+ HID_USAGE_SPORTS_CONTROLS_STICK_FACE_ANGLE = 0x34, // DV
+ HID_USAGE_SPORTS_CONTROLS_STICK_HEEL_TOE = 0x35, // DV
+ HID_USAGE_SPORTS_CONTROLS_STICK_FOLLOW_THROUGH = 0x36, // DV
+ HID_USAGE_SPORTS_CONTROLS_STICK_TEMPO = 0x37, // DV
+ HID_USAGE_SPORTS_CONTROLS_STICK_TYPE = 0x38, // NAry
+ HID_USAGE_SPORTS_CONTROLS_STICK_HEIGHT = 0x39, // DV
+ // 3A-4F Reserved
+
+ HID_USAGE_SPORTS_CONTROLS_PUTTER = 0x50, // Sel
+ HID_USAGE_SPORTS_CONTROLS_1_IRON = 0x51, // Sel
+ HID_USAGE_SPORTS_CONTROLS_2_IRON = 0x52, // Sel
+ HID_USAGE_SPORTS_CONTROLS_3_IRON = 0x53, // Sel
+ HID_USAGE_SPORTS_CONTROLS_4_IRON = 0x54, // Sel
+ HID_USAGE_SPORTS_CONTROLS_5_IRON = 0x55, // Sel
+ HID_USAGE_SPORTS_CONTROLS_6_IRON = 0x56, // Sel
+ HID_USAGE_SPORTS_CONTROLS_7_IRON = 0x57, // Sel
+ HID_USAGE_SPORTS_CONTROLS_8_IRON = 0x58, // Sel
+ HID_USAGE_SPORTS_CONTROLS_9_IRON = 0x59, // Sel
+ HID_USAGE_SPORTS_CONTROLS_10_IRON = 0x5A, // Sel
+ HID_USAGE_SPORTS_CONTROLS_11_IRON = 0x5B, // Sel
+ HID_USAGE_SPORTS_CONTROLS_SAND_WEDGE = 0x5C, // Sel
+ HID_USAGE_SPORTS_CONTROLS_LOFT_WEDGE = 0x5D, // Sel
+ HID_USAGE_SPORTS_CONTROLS_POWER_WEDGE = 0x5E, // Sel
+ HID_USAGE_SPORTS_CONTROLS_1_WOOD = 0x5F, // Sel
+ HID_USAGE_SPORTS_CONTROLS_3_WOOD = 0x60, // Sel
+ HID_USAGE_SPORTS_CONTROLS_5_WOOD = 0x61, // Sel
+ HID_USAGE_SPORTS_CONTROLS_7_WOOD = 0x62, // Sel
+ HID_USAGE_SPORTS_CONTROLS_9_WOOD = 0x63, // Sel
+ // 64-FFFF Reserved
+};
+
+/// HID Usage Table: Game Controls Page (0x05)
+enum {
+ HID_USAGE_GAME_CONTROLS_3D_GAME_CONTROLLER = 0x01, // CA
+ HID_USAGE_GAME_CONTROLS_PINBALL_DEVICE = 0x02, // CA
+ HID_USAGE_GAME_CONTROLS_GUN_DEVICE = 0x03, // CA
+ // 04-1F Reserved
+
+ HID_USAGE_GAME_CONTROLS_POINT_OF_VIEW = 0x20, // CP
+ HID_USAGE_GAME_CONTROLS_TURN_RIGHT_LEFT = 0x21, // DV
+ HID_USAGE_GAME_CONTROLS_PITCH_FORWARD_BACKWARD = 0x22, // DV
+ HID_USAGE_GAME_CONTROLS_ROLL_RIGHT_LEFT = 0x23, // DV
+ HID_USAGE_GAME_CONTROLS_MOVE_RIGHT_LEFT = 0x24, // DV
+ HID_USAGE_GAME_CONTROLS_MOVE_FORWARD_BACKWARD = 0x25, // DV
+ HID_USAGE_GAME_CONTROLS_MOVE_UP_DOWN = 0x26, // DV
+ HID_USAGE_GAME_CONTROLS_LEAN_RIGHT_LEFT = 0x27, // DV
+ HID_USAGE_GAME_CONTROLS_LEAN_FORWARD_BACKWARD = 0x28, // DV
+ HID_USAGE_GAME_CONTROLS_HEIGHT_OF_POV = 0x29, // DV
+ HID_USAGE_GAME_CONTROLS_FLIPPER = 0x2A, // MC
+ HID_USAGE_GAME_CONTROLS_SECONDARY_FLIPPER = 0x2B, // MC
+ HID_USAGE_GAME_CONTROLS_BUMP = 0x2C, // MC
+ HID_USAGE_GAME_CONTROLS_NEW_GAME = 0x2D, // OSC
+ HID_USAGE_GAME_CONTROLS_SHOOT_BALL = 0x2E, // OSC
+ HID_USAGE_GAME_CONTROLS_PLAYER = 0x2F, // OSC
+ HID_USAGE_GAME_CONTROLS_GUN_BOLT = 0x30, // OOC
+ HID_USAGE_GAME_CONTROLS_GUN_CLIP = 0x31, // OOC
+ HID_USAGE_GAME_CONTROLS_GUN_SELECTOR = 0x32, // NAry
+ HID_USAGE_GAME_CONTROLS_GUN_SINGLE_SHOT = 0x33, // Sel
+ HID_USAGE_GAME_CONTROLS_GUN_BURST = 0x34, // Sel
+ HID_USAGE_GAME_CONTROLS_GUN_AUTOMATIC = 0x35, // Sel
+ HID_USAGE_GAME_CONTROLS_GUN_SAFETY = 0x36, // OOC
+ HID_USAGE_GAME_CONTROLS_GAMEPAD_FIRE_JUMP = 0x37, // CL
+ // 38 Reserved
+
+ HID_USAGE_GAME_CONTROLS_GAMEPAD_TRIGGER = 0x39, // CL
+ HID_USAGE_GAME_CONTROLS_FORM_FITTING_GAMEPAD = 0x3A // SF
+ // 3B-FFFF Reserved
+};
+
+/// HID Usage Table: Generic Device Controls Page (0x06)
+enum {
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_BACKGROUND_NONUSER_CONTROLS = 0x01, // CA
+ // 02-1F Reserved
+
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_BATTERY_STRENGTH = 0x20, // DV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_WIRELESS_CHANNEL = 0x21, // DV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_WIRELESS_ID = 0x22, // DV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_DISCOVER_WIRELESS_CONTROL = 0x23, // OSC
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_SECURITY_CODE_CHARACTER_ENTERED = 0x24, // OSC
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_SECURITY_CODE_CHARACTER_ERASED = 0x25, // OSC
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_SECURITY_CODE_CLEARED = 0x26, // OSC
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_SEQUENCE_ID = 0x27, // DV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_SEQUENCE_ID_RESET = 0x28, // DF
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_RF_SIGNAL_STRENGTH = 0x29, // DV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_SOFTWARE_VERSION = 0x2A, // CL
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_PROTOCOL_VERSION = 0x2B, // CL
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_HARDWARE_VERSION = 0x2C, // CL
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_MAJOR = 0x2D, // SV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_MINOR = 0x2E, // SV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_REVISION = 0x2F, // SV
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_HANDEDNESS = 0x30, // NAry
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_EITHER_HAND = 0x31, // Sel
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_LEFT_HAND = 0x32, // Sel
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_RIGHT_HAND = 0x33, // Sel
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_BOTH_HANDS = 0x34, // Sel
+ // 35-3F Reserved
+
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_GRIP_POSE_OFFSET = 0x40, // CP
+ HID_USAGE_GENERIC_DEVICE_CONTROLS_POINTER_POSE_OFFSET = 0x41 // CP
+ // 42-FFFF Reserved
+};
+
+/// HID Usage Table: Keyboard/Keypad Page (0x07)
+/// Defined above
+
+/// HID Usage Table: LED Page (0x08)
+enum {
+ HID_USAGE_LED_NUM_LOCK = 0x01, // OOC
+ HID_USAGE_LED_CAPS_LOCK = 0x02, // OOC
+ HID_USAGE_LED_SCROLL_LOCK = 0x03, // OOC
+ HID_USAGE_LED_COMPOSE = 0x04, // OOC
+ HID_USAGE_LED_KANA = 0x05, // OOC
+ HID_USAGE_LED_POWER = 0x06, // OOC
+ HID_USAGE_LED_SHIFT = 0x07, // OOC
+ HID_USAGE_LED_DO_NOT_SHIFT = 0x08, // OOC
+ HID_USAGE_LED_MUTE = 0x09, // OOC
+ HID_USAGE_LED_TONE_ENABLE = 0x0A, // OOC
+ HID_USAGE_LED_HIGH_CUT_FILTER = 0x0B, // OOC
+ HID_USAGE_LED_LOW_CUT_FILTER = 0x0C, // OOC
+ HID_USAGE_LED_EQUALIZER_ENABLE = 0x0D, // OOC
+ HID_USAGE_LED_SOUND_FIELD_ON = 0x0E, // OOC
+ HID_USAGE_LED_SURROUND_ON = 0x0F, // OOC
+ HID_USAGE_LED_REPEAT = 0x10, // OOC
+ HID_USAGE_LED_STEREO = 0x11, // OOC
+ HID_USAGE_LED_SAMPLING_RATE_DETECT = 0x12, // OOC
+ HID_USAGE_LED_SPINNING = 0x13, // OOC
+ HID_USAGE_LED_CAV = 0x14, // OOC
+ HID_USAGE_LED_CLV = 0x15, // OOC
+ HID_USAGE_LED_RECORDING_FORMAT_DETECT = 0x16, // OOC
+ HID_USAGE_LED_OFF_HOOK = 0x17, // OOC
+ HID_USAGE_LED_RING = 0x18, // OOC
+ HID_USAGE_LED_MESSAGE_WAITING = 0x19, // OOC
+ HID_USAGE_LED_DATA_MODE = 0x1A, // OOC
+ HID_USAGE_LED_BATTERY_OPERATION = 0x1B, // OOC
+ HID_USAGE_LED_BATTERY_OK = 0x1C, // OOC
+ HID_USAGE_LED_BATTERY_LOW = 0x1D, // OOC
+ HID_USAGE_LED_SPEAKER = 0x1E, // OOC
+ HID_USAGE_LED_HEADSET = 0x1F, // OOC
+ HID_USAGE_LED_HOLD = 0x20, // OOC
+ HID_USAGE_LED_MICROPHONE = 0x21, // OOC
+ HID_USAGE_LED_COVERAGE = 0x22, // OOC
+ HID_USAGE_LED_NIGHT_MODE = 0x23, // OOC
+ HID_USAGE_LED_SEND_CALLS = 0x24, // OOC
+ HID_USAGE_LED_CALL_PICKUPS = 0x25, // OOC
+ HID_USAGE_LED_CONFERENCE = 0x26, // OOC
+ HID_USAGE_LED_STANDBY = 0x27, // OOC
+ HID_USAGE_LED_CAMERA_ON = 0x28, // OOC
+ HID_USAGE_LED_CAMERA_OFF = 0x29, // OOC
+ HID_USAGE_LED_ON_LINE = 0x2A, // OOC
+ HID_USAGE_LED_OFF_LINE = 0x2B, // OOC
+ HID_USAGE_LED_BUSY = 0x2C, // OOC
+ HID_USAGE_LED_READY = 0x2D, // OOC
+ HID_USAGE_LED_PAPER_OUT = 0x2E, // OOC
+ HID_USAGE_LED_PAPER_JAM = 0x2F, // OOC
+ HID_USAGE_LED_REMOTE = 0x30, // OOC
+ HID_USAGE_LED_FORWARD = 0x31, // OOC
+ HID_USAGE_LED_REVERSE = 0x32, // OOC
+ HID_USAGE_LED_STOP = 0x33, // OOC
+ HID_USAGE_LED_REWIND = 0x34, // OOC
+ HID_USAGE_LED_FAST_FORWARD = 0x35, // OOC
+ HID_USAGE_LED_PLAY = 0x36, // OOC
+ HID_USAGE_LED_PAUSE = 0x37, // OOC
+ HID_USAGE_LED_RECORD = 0x38, // OOC
+ HID_USAGE_LED_ERROR = 0x39, // OOC
+ HID_USAGE_LED_USAGE_SELECTED_INDICATOR = 0x3A, // US
+ HID_USAGE_LED_USAGE_IN_USE_INDICATOR = 0x3B, // US
+ HID_USAGE_LED_USAGE_MULTI_MODE_INDICATOR = 0x3C, // UM
+ HID_USAGE_LED_INDICATOR_ON = 0x3D, // Sel
+ HID_USAGE_LED_INDICATOR_FLASH = 0x3E, // Sel
+ HID_USAGE_LED_INDICATOR_SLOW_BLINK = 0x3F, // Sel
+ HID_USAGE_LED_INDICATOR_FAST_BLINK = 0x40, // Sel
+ HID_USAGE_LED_INDICATOR_OFF = 0x41, // Sel
+ HID_USAGE_LED_FLASH_ON_TIME = 0x42, // DV
+ HID_USAGE_LED_SLOW_BLINK_ON_TIME = 0x43, // DV
+ HID_USAGE_LED_SLOW_BLINK_OFF_TIME = 0x44, // DV
+ HID_USAGE_LED_FAST_BLINK_ON_TIME = 0x45, // DV
+ HID_USAGE_LED_FAST_BLINK_OFF_TIME = 0x46, // DV
+ HID_USAGE_LED_USAGE_INDICATOR_COLOR = 0x47, // UM
+ HID_USAGE_LED_INDICATOR_RED = 0x48, // Sel
+ HID_USAGE_LED_INDICATOR_GREEN = 0x49, // Sel
+ HID_USAGE_LED_INDICATOR_AMBER = 0x4A, // Sel
+ HID_USAGE_LED_GENERIC_INDICATOR = 0x4B, // OOC
+ HID_USAGE_LED_SYSTEM_SUSPEND = 0x4C, // OOC
+ HID_USAGE_LED_EXTERNAL_POWER_CONNECTED = 0x4D, // OOC
+ HID_USAGE_LED_INDICATOR_BLUE = 0x4E, // Sel
+ HID_USAGE_LED_INDICATOR_ORANGE = 0x4F, // Sel
+ HID_USAGE_LED_GOOD_STATUS = 0x50, // OOC
+ HID_USAGE_LED_WARNING_STATUS = 0x51, // OOC
+ HID_USAGE_LED_RGB_LED = 0x52, // CL
+ HID_USAGE_LED_RED_LED_CHANNEL = 0x53, // DV
+ HID_USAGE_LED_BLUE_LED_CHANNEL = 0x54, // DV
+ HID_USAGE_LED_GREEN_LED_CHANNEL = 0x55, // DV
+ HID_USAGE_LED_LED_INTENSITY = 0x56, // DV
+ HID_USAGE_LED_SYSTEM_MICROPHONE_MUTE = 0x57, // OOC
+ // 58-5F Reserved
+
+ HID_USAGE_LED_PLAYER_INDICATOR = 0x60, // NAry
+ HID_USAGE_LED_PLAYER_1 = 0x61, // Sel
+ HID_USAGE_LED_PLAYER_2 = 0x62, // Sel
+ HID_USAGE_LED_PLAYER_3 = 0x63, // Sel
+ HID_USAGE_LED_PLAYER_4 = 0x64, // Sel
+ HID_USAGE_LED_PLAYER_5 = 0x65, // Sel
+ HID_USAGE_LED_PLAYER_6 = 0x66, // Sel
+ HID_USAGE_LED_PLAYER_7 = 0x67, // Sel
+ HID_USAGE_LED_PLAYER_8 = 0x68, // Sel
+ // 69-FFFF Reserved
+};
+
+/// HID Usage Table: Button Page (0x09)
+/// Intentionally skipped
+
+/// HID Usage Table: Ordinal Page (0x0A)
+/// Intentionally skipped
+
+/// HID Usage Table: Telephony Device Page (0x0B)
+enum {
+ HID_USAGE_TELEPHONY_PHONE = 0x0001, // CA
+ HID_USAGE_TELEPHONY_ANSWERING_MACHINE = 0x0002, // CA
+ HID_USAGE_TELEPHONY_MESSAGE_CONTROLS = 0x0003, // CL
+ HID_USAGE_TELEPHONY_HANDSET = 0x0004, // CL
+ HID_USAGE_TELEPHONY_HEADSET = 0x0005, // CL/CA
+ HID_USAGE_TELEPHONY_TELEPHONY_KEY_PAD = 0x0006, // NAry
+ HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON = 0x0007, // NAry
+ // 08-1F Reserved
+
+ HID_USAGE_TELEPHONY_HOOK_SWITCH = 0x0020, // OOC
+ HID_USAGE_TELEPHONY_FLASH = 0x0021, // MC
+ HID_USAGE_TELEPHONY_FEATURE = 0x0022, // OSC
+ HID_USAGE_TELEPHONY_HOLD = 0x0023, // OOC
+ HID_USAGE_TELEPHONY_REDIAL = 0x0024, // OSC
+ HID_USAGE_TELEPHONY_TRANSFER = 0x0025, // OSC
+ HID_USAGE_TELEPHONY_DROP = 0x0026, // OSC
+ HID_USAGE_TELEPHONY_PARK = 0x0027, // OOC
+ HID_USAGE_TELEPHONY_FORWARD_CALLS = 0x0028, // OOC
+ HID_USAGE_TELEPHONY_ALTERNATE_FUNCTION = 0x0029, // MC
+ HID_USAGE_TELEPHONY_LINE = 0x002A, // OSC/NAry
+ HID_USAGE_TELEPHONY_SPEAKER_PHONE = 0x002B, // OOC
+ HID_USAGE_TELEPHONY_CONFERENCE = 0x002C, // OOC
+ HID_USAGE_TELEPHONY_RING_ENABLE = 0x002D, // OOC
+ HID_USAGE_TELEPHONY_RING_SELECT = 0x002E, // OSC
+ HID_USAGE_TELEPHONY_PHONE_MUTE = 0x002F, // OOC
+ HID_USAGE_TELEPHONY_CALLER_ID = 0x0030, // MC
+ HID_USAGE_TELEPHONY_SEND = 0x0031, // OOC
+ // 32-4F Reserved
+
+ HID_USAGE_TELEPHONY_SPEED_DIAL = 0x0050, // OSC
+ HID_USAGE_TELEPHONY_STORE_NUMBER = 0x0051, // OSC
+ HID_USAGE_TELEPHONY_RECALL_NUMBER = 0x0052, // OSC
+ HID_USAGE_TELEPHONY_PHONE_DIRECTORY = 0x0053, // OOC
+ // 54-6F Reserved
+
+ HID_USAGE_TELEPHONY_VOICE_MAIL = 0x0070, // OOC
+ HID_USAGE_TELEPHONY_SCREEN_CALLS = 0x0071, // OOC
+ HID_USAGE_TELEPHONY_DO_NOT_DISTURB = 0x0072, // OOC
+ HID_USAGE_TELEPHONY_MESSAGE = 0x0073, // OSC
+ HID_USAGE_TELEPHONY_ANSWER_ON_OFF = 0x0074, // OOC
+ // 75-8F Reserved
+
+ HID_USAGE_TELEPHONY_INSIDE_DIAL_TONE = 0x0090, // MC
+ HID_USAGE_TELEPHONY_OUTSIDE_DIAL_TONE = 0x0091, // MC
+ HID_USAGE_TELEPHONY_INSIDE_RING_TONE = 0x0092, // MC
+ HID_USAGE_TELEPHONY_OUTSIDE_RING_TONE = 0x0093, // MC
+ HID_USAGE_TELEPHONY_PRIORITY_RING_TONE = 0x0094, // MC
+ HID_USAGE_TELEPHONY_INSIDE_RINGBACK = 0x0095, // MC
+ HID_USAGE_TELEPHONY_PRIORITY_RINGBACK = 0x0096, // MC
+ HID_USAGE_TELEPHONY_LINE_BUSY_TONE = 0x0097, // MC
+ HID_USAGE_TELEPHONY_REORDER_TONE = 0x0098, // MC
+ HID_USAGE_TELEPHONY_CALL_WAITING_TONE = 0x0099, // MC
+ HID_USAGE_TELEPHONY_CONFIRMATION_TONE_1 = 0x009A, // MC
+ HID_USAGE_TELEPHONY_CONFIRMATION_TONE_2 = 0x009B, // MC
+ HID_USAGE_TELEPHONY_TONES_OFF = 0x009C, // OOC
+ HID_USAGE_TELEPHONY_OUTSIDE_RINGBACK = 0x009D, // MC
+ HID_USAGE_TELEPHONY_RINGER = 0x009E, // OOC
+ // 9F-AF Reserved
+
+ HID_USAGE_TELEPHONY_PHONE_KEY_0 = 0x00B0, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_1 = 0x00B1, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_2 = 0x00B2, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_3 = 0x00B3, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_4 = 0x00B4, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_5 = 0x00B5, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_6 = 0x00B6, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_7 = 0x00B7, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_8 = 0x00B8, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_9 = 0x00B9, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_STAR = 0x00BA, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_POUND = 0x00BB, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_A = 0x00BC, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_B = 0x00BD, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_C = 0x00BE, // Sel
+ HID_USAGE_TELEPHONY_PHONE_KEY_D = 0x00BF, // Sel
+ HID_USAGE_TELEPHONY_PHONE_CALL_HISTORY_KEY = 0x00C0, // Sel
+ HID_USAGE_TELEPHONY_PHONE_CALLER_ID_KEY = 0x00C1, // Sel
+ HID_USAGE_TELEPHONY_PHONE_SETTINGS_KEY = 0x00C2, // Sel
+ // C3-EF Reserved
+
+ HID_USAGE_TELEPHONY_HOST_CONTROL = 0x00F0, // OOC
+ HID_USAGE_TELEPHONY_HOST_AVAILABLE = 0x00F1, // OOC
+ HID_USAGE_TELEPHONY_HOST_CALL_ACTIVE = 0x00F2, // OOC
+ HID_USAGE_TELEPHONY_ACTIVATE_HANDSET_AUDIO = 0x00F3, // OOC
+ HID_USAGE_TELEPHONY_RING_TYPE = 0x00F4, // NAry
+ HID_USAGE_TELEPHONY_REDIALABLE_PHONE_NUMBER = 0x00F5, // OOC
+ // F6-F7 Reserved
+
+ HID_USAGE_TELEPHONY_STOP_RING_TONE = 0x00F8, // Sel
+ HID_USAGE_TELEHONY_PSTN_RING_TONE = 0x00F9, // Sel
+ HID_USAGE_TELEPHONY_HOST_RING_TONE = 0x00FA, // Sel
+ HID_USAGE_TELEPHONY_ALERT_SOUND_ERROR = 0x00FB, // Sel
+ HID_USAGE_TELEPHONY_ALERT_SOUND_CONFIRM = 0x00FC, // Sel
+ HID_USAGE_TELEPHONY_ALERT_SOUND_NOTIFICATION = 0x00FD, // Sel
+ HID_USAGE_TELEPHONY_SILENT_RING = 0x00FE, // Sel
+ // FF-107 Reserved
+
+ HID_USAGE_TELEPHONY_EMAIL_MESSAGE_WAITING = 0x0108, // OOC
+ HID_USAGE_TELEPHONY_VOICEMAIL_MESSAGE_WAITING = 0x0109, // OOC
+ HID_USAGE_TELEPHONY_HOST_HOLD = 0x010A, // OOC
+ // 10B-10F Reserved
+
+ HID_USAGE_TELEPHONY_INCOMING_CALL_HISTORY_COUNT = 0x0110, // DV
+ HID_USAGE_TELEPHONY_OUTGOING_CALL_HISTORY_COUNT = 0x0111, // DV
+ HID_USAGE_TELEPHONY_INCOMING_CALL_HISTORY = 0x0112, // CL
+ HID_USAGE_TELEPHONY_OUTGOING_CALL_HISTORY = 0x0113, // CL
+ HID_USAGE_TELEPHONY_PHONE_LOCALE = 0x0114, // DV
+ // 115-13F Reserved
+
+ HID_USAGE_TELEPHONY_PHONE_TIME_SECOND = 0x0140, // DV
+ HID_USAGE_TELEPHONY_PHONE_TIME_MINUTE = 0x0141, // DV
+ HID_USAGE_TELEPHONY_PHONE_TIME_HOUR = 0x0142, // DV
+ HID_USAGE_TELEPHONY_PHONE_DATE_DAY = 0x0143, // DV
+ HID_USAGE_TELEPHONY_PHONE_DATE_MONTH = 0x0144, // DV
+ HID_USAGE_TELEPHONY_PHONE_DATE_YEAR = 0x0145, // DV
+ HID_USAGE_TELEPHONY_HANDSET_NICKNAME = 0x0146, // DV
+ HID_USAGE_TELEPHONY_ADDRESS_BOOK_ID = 0x0147, // DV
+ // 148-149 Reserved
+
+ HID_USAGE_TELEPHONY_CALL_DURATION = 0x014A, // DV
+ HID_USAGE_TELEPHONY_DUAL_MODE_PHONE = 0x014B, // CA
+ // 14C-FFFF Reserved
};
/// HID Usage Table: Consumer Page (0x0C)
-/// Only contains controls that supported by Windows (whole list is too long)
enum {
- HID_USAGE_CONSUMER_UNASSIGNED = 0x0000,
+ HID_USAGE_CONSUMER_UNASSIGNED = 0x0000,
// Generic Control
- HID_USAGE_CONSUMER_CONTROL = 0x0001,
- HID_USAGE_CONSUMER_NUMERIC_KEY_PAD = 0x0002,
- HID_USAGE_CONSUMER_PROGRAMMABLE_BUTTONS = 0x0003,
- HID_USAGE_CONSUMER_MICROPHONE = 0x0004,
- HID_USAGE_CONSUMER_HEADPHONE = 0x0005,
- HID_USAGE_CONSUMER_GRAPHIC_EQUALIZER = 0x0006,
- // 07-1F Reserved
+ HID_USAGE_CONSUMER_CONTROL = 0x0001, // CA
+ HID_USAGE_CONSUMER_NUMERIC_KEY_PAD = 0x0002, // NAry
+ HID_USAGE_CONSUMER_PROGRAMMABLE_BUTTONS = 0x0003, // NAry
+ HID_USAGE_CONSUMER_MICROPHONE = 0x0004, // CA
+ HID_USAGE_CONSUMER_HEADPHONE = 0x0005, // CA
+ HID_USAGE_CONSUMER_GRAPHIC_EQUALIZER = 0x0006, // CA
+ HID_USAGE_CONSUMER_KEYBOARD_BACKLIGHT = 0x0007, // CA
+ // 08-1F Reserved
- HID_USAGE_CONSUMER_PLUS_10 = 0x0020,
- HID_USAGE_CONSUMER_PLUS_100 = 0x0021,
- HID_USAGE_CONSUMER_AM_PM = 0x0022,
+ HID_USAGE_CONSUMER_PLUS_10 = 0x0020, // OSC
+ HID_USAGE_CONSUMER_PLUS_100 = 0x0021, // OSC
+ HID_USAGE_CONSUMER_AM_PM = 0x0022, // OSC
// 23-3F Reserved
// Power Control
- HID_USAGE_CONSUMER_POWER = 0x0030,
- HID_USAGE_CONSUMER_RESET = 0x0031,
- HID_USAGE_CONSUMER_SLEEP = 0x0032,
+ HID_USAGE_CONSUMER_POWER = 0x0030, // OOC
+ HID_USAGE_CONSUMER_RESET = 0x0031, // OSC
+ HID_USAGE_CONSUMER_SLEEP = 0x0032, // OSC
- HID_USAGE_CONSUMER_SLEEP_AFTER = 0x0033,
- HID_USAGE_CONSUMER_SLEEP_MODE = 0x0034,
- HID_USAGE_CONSUMER_ILLUMINATION = 0x0035,
- HID_USAGE_CONSUMER_FUNCTION_BUTTONS = 0x0036,
+ HID_USAGE_CONSUMER_SLEEP_AFTER = 0x0033, // OSC
+ HID_USAGE_CONSUMER_SLEEP_MODE = 0x0034, // RTC
+ HID_USAGE_CONSUMER_ILLUMINATION = 0x0035, // OOC
+ HID_USAGE_CONSUMER_FUNCTION_BUTTONS = 0x0036, // NAry
// 37-3F Reserved
- HID_USAGE_CONSUMER_MENU = 0x0040,
- HID_USAGE_CONSUMER_MENU_PICK = 0x0041,
- HID_USAGE_CONSUMER_MENU_UP = 0x0042,
- HID_USAGE_CONSUMER_MENU_DOWN = 0x0043,
- HID_USAGE_CONSUMER_MENU_LEFT = 0x0044,
- HID_USAGE_CONSUMER_MENU_RIGHT = 0x0045,
- HID_USAGE_CONSUMER_MENU_ESCAPE = 0x0046,
- HID_USAGE_CONSUMER_MENU_VALUE_INCREASE = 0x0047,
- HID_USAGE_CONSUMER_MENU_VALUE_DECREASE = 0x0048,
+ HID_USAGE_CONSUMER_MENU = 0x0040, // OOC
+ HID_USAGE_CONSUMER_MENU_PICK = 0x0041, // OSC
+ HID_USAGE_CONSUMER_MENU_UP = 0x0042, // OSC
+ HID_USAGE_CONSUMER_MENU_DOWN = 0x0043, // OSC
+ HID_USAGE_CONSUMER_MENU_LEFT = 0x0044, // OSC
+ HID_USAGE_CONSUMER_MENU_RIGHT = 0x0045, // OSC
+ HID_USAGE_CONSUMER_MENU_ESCAPE = 0x0046, // OSC
+ HID_USAGE_CONSUMER_MENU_VALUE_INCREASE = 0x0047, // OSC
+ HID_USAGE_CONSUMER_MENU_VALUE_DECREASE = 0x0048, // OSC
// 49-5F Reserved
- HID_USAGE_CONSUMER_DATA_ON_SCREEN = 0x0060,
- HID_USAGE_CONSUMER_CLOSED_CAPTION = 0x0061,
- HID_USAGE_CONSUMER_CLOSED_CAPTION_SELECT = 0x0062,
- HID_USAGE_CONSUMER_VCR_TV = 0x0063,
- HID_USAGE_CONSUMER_BROADCAST_MODE = 0x0064,
- HID_USAGE_CONSUMER_SNAPSHOT = 0x0065,
- HID_USAGE_CONSUMER_STILL = 0x0066,
-
- // 67-7F Reserved
- // Screen Brightness
- HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT = 0x006F,
- HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT = 0x0070,
-
- // These HID usages operate only on mobile systems (battery powered) and
- // require Windows 8 (build 8302 or greater).
- HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C,
- HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6,
- HID_USAGE_CONSUMER_WIRELESS_RADIO_LED = 0x00C7,
- HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8,
-
- HID_USAGE_CONSUMER_SELECTION = 0x0080,
- HID_USAGE_CONSUMER_ASSIGN_SELECTION = 0x0081,
- HID_USAGE_CONSUMER_MODE_STEP = 0x0082,
- HID_USAGE_CONSUMER_RECALL_LAST = 0x0083,
- HID_USAGE_CONSUMER_ENTER_CHANNEL = 0x0084,
- HID_USAGE_CONSUMER_ORDER_MOVIE = 0x0085,
- HID_USAGE_CONSUMER_CHANNEL = 0x0086,
- HID_USAGE_CONSUMER_MEDIA_SELECTION = 0x0087,
- HID_USAGE_CONSUMER_MEDIA_SELECT_COMPUTER = 0x0088,
- HID_USAGE_CONSUMER_MEDIA_SELECT_TV = 0x0089,
- HID_USAGE_CONSUMER_MEDIA_SELECT_WWW = 0x008A,
- HID_USAGE_CONSUMER_MEDIA_SELECT_DVD = 0x008B,
- HID_USAGE_CONSUMER_MEDIA_SELECT_TELEPHONE = 0x008C,
- HID_USAGE_CONSUMER_MEDIA_SELECT_PROGRAM_GUIDE = 0x008D,
- HID_USAGE_CONSUMER_MEDIA_SELECT_VIDEO_PHONE = 0x008E,
- HID_USAGE_CONSUMER_MEDIA_SELECT_GAMES = 0x008F,
- HID_USAGE_CONSUMER_MEDIA_SELECT_MESSAGES = 0x0090,
- HID_USAGE_CONSUMER_MEDIA_SELECT_CD = 0x0091,
- HID_USAGE_CONSUMER_MEDIA_SELECT_VCR = 0x0092,
- HID_USAGE_CONSUMER_MEDIA_SELECT_TUNER = 0x0093,
- HID_USAGE_CONSUMER_QUIT = 0x0094,
- HID_USAGE_CONSUMER_HELP = 0x0095,
- HID_USAGE_CONSUMER_MEDIA_SELECT_TAPE = 0x0096,
- HID_USAGE_CONSUMER_MEDIA_SELECT_CABLE = 0x0097,
- HID_USAGE_CONSUMER_MEDIA_SELECT_SATELLITE = 0x0098,
- HID_USAGE_CONSUMER_MEDIA_SELECT_SECURITY = 0x0099,
- HID_USAGE_CONSUMER_MEDIA_SELECT_HOME = 0x009A,
- HID_USAGE_CONSUMER_MEDIA_SELECT_CALL = 0x009B,
- HID_USAGE_CONSUMER_CHANNEL_INCREMENT = 0x009C,
- HID_USAGE_CONSUMER_CHANNEL_DECREMENT = 0x009D,
- HID_USAGE_CONSUMER_MEDIA_SELECT_SAP = 0x009E,
+ HID_USAGE_CONSUMER_DATA_ON_SCREEN = 0x0060, // OOC
+ HID_USAGE_CONSUMER_CLOSED_CAPTION = 0x0061, // OOC
+ HID_USAGE_CONSUMER_CLOSED_CAPTION_SELECT = 0x0062, // OSC
+ HID_USAGE_CONSUMER_VCR_TV = 0x0063, // OOC
+ HID_USAGE_CONSUMER_BROADCAST_MODE = 0x0064, // OSC
+ HID_USAGE_CONSUMER_SNAPSHOT = 0x0065, // OSC
+ HID_USAGE_CONSUMER_STILL = 0x0066, // OSC
+ HID_USAGE_CONSUMER_PICTURE_IN_PICTURE_TOGGLE = 0x0067, // OSC
+ HID_USAGE_CONSUMER_PICTURE_IN_PICTURE_SWAP = 0x0068, // OSC
+ HID_USAGE_CONSUMER_RED_MENU_BUTTON = 0x0069, // MC
+ HID_USAGE_CONSUMER_GREEN_MENU_BUTTON = 0x006A, // MC
+ HID_USAGE_CONSUMER_BLUE_MENU_BUTTON = 0x006B, // MC
+ HID_USAGE_CONSUMER_YELLOW_MENU_BUTTON = 0x006C, // MC
+ HID_USAGE_CONSUMER_ASPECT = 0x006D, // OSC
+ HID_USAGE_CONSUMER_3D_MODE_SELECT = 0x006E, // OSC
+ HID_USAGE_CONSUMER_DISPLAY_BRIGHTNESS_INCREMENT = 0x006F, // RTC
+ HID_USAGE_CONSUMER_DISPLAY_BRIGHTNESS_DECREMENT = 0x0070, // RTC
+ HID_USAGE_CONSUMER_DISPLAY_BRIGHTNESS = 0x0071, // LC
+ HID_USAGE_CONSUMER_DISPLAY_BACKLIGHT_TOGGLE = 0x0072, // OOC
+ HID_USAGE_CONSUMER_DISPLAY_SET_BRIGHTNESS_TO_MINIMUM = 0x0073, // OSC
+ HID_USAGE_CONSUMER_DISPLAY_SET_BRIGHTNESS_TO_MAXIMUM = 0x0074, // OSC
+ HID_USAGE_CONSUMER_DISPLAY_SET_AUTO_BRIGHTNESS = 0x0075, // OOC
+ HID_USAGE_CONSUMER_CAMERA_ACCESS_ENABLED = 0x0076, // OOC
+ HID_USAGE_CONSUMER_CAMERA_ACCESS_DISABLED = 0x0077, // OOC
+ HID_USAGE_CONSUMER_CAMERA_ACCESS_TOGGLE = 0x0078, // OOC
+ HID_USAGE_CONSUMER_KEYBOARD_BRIGHTNESS_INCREMENT = 0x0079, // OSC
+ HID_USAGE_CONSUMER_KEYBOARD_BRIGHTNESS_DECREMENT = 0x007A, // OSC
+ HID_USAGE_CONSUMER_KEYBOARD_BACKLIGHT_SET_LEVEL = 0x007B, // LC
+ HID_USAGE_CONSUMER_KEYBOARD_BACKLIGHT_OOC = 0x007C, // OOC
+ HID_USAGE_CONSUMER_KEYBOARD_BACKLIGHT_SET_MINIMUM = 0x007D, // OSC
+ HID_USAGE_CONSUMER_KEYBOARD_BACKLIGHT_SET_MAXIMUM = 0x007E, // OSC
+ HID_USAGE_CONSUMER_KEYBOARD_BACKLIGHT_AUTO = 0x007F, // OOC
+ HID_USAGE_CONSUMER_SELECTION = 0x0080, // NAry
+ HID_USAGE_CONSUMER_ASSIGN_SELECTION = 0x0081, // OSC
+ HID_USAGE_CONSUMER_MODE_STEP = 0x0082, // OSC
+ HID_USAGE_CONSUMER_RECALL_LAST = 0x0083, // OSC
+ HID_USAGE_CONSUMER_ENTER_CHANNEL = 0x0084, // OSC
+ HID_USAGE_CONSUMER_ORDER_MOVIE = 0x0085, // OSC
+ HID_USAGE_CONSUMER_CHANNEL = 0x0086, // LC
+ HID_USAGE_CONSUMER_MEDIA_SELECTION = 0x0087, // NAry
+ HID_USAGE_CONSUMER_MEDIA_SELECT_COMPUTER = 0x0088, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_TV = 0x0089, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_WWW = 0x008A, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_DVD = 0x008B, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_TELEPHONE = 0x008C, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_PROGRAM_GUIDE = 0x008D, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_VIDEO_PHONE = 0x008E, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_GAMES = 0x008F, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_MESSAGES = 0x0090, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_CD = 0x0091, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_VCR = 0x0092, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_TUNER = 0x0093, // Sel
+ HID_USAGE_CONSUMER_QUIT = 0x0094, // OSC
+ HID_USAGE_CONSUMER_HELP = 0x0095, // OOC
+ HID_USAGE_CONSUMER_MEDIA_SELECT_TAPE = 0x0096, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_CABLE = 0x0097, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_SATELLITE = 0x0098, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_SECURITY = 0x0099, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_HOME = 0x009A, // Sel
+ HID_USAGE_CONSUMER_MEDIA_SELECT_CALL = 0x009B, // Sel
+ HID_USAGE_CONSUMER_CHANNEL_INCREMENT = 0x009C, // OSC
+ HID_USAGE_CONSUMER_CHANNEL_DECREMENT = 0x009D, // OSC
+ HID_USAGE_CONSUMER_MEDIA_SELECT_SAP = 0x009E, // Sel
// 9F Reserved
- HID_USAGE_CONSUMER_VCR_PLUS = 0x00A0,
- HID_USAGE_CONSUMER_ONCE = 0x00A1,
- HID_USAGE_CONSUMER_DAILY = 0x00A2,
- HID_USAGE_CONSUMER_WEEKLY = 0x00A3,
- HID_USAGE_CONSUMER_MONTHLY = 0x00A4,
+ HID_USAGE_CONSUMER_VCR_PLUS = 0x00A0, // OSC
+ HID_USAGE_CONSUMER_ONCE = 0x00A1, // OSC
+ HID_USAGE_CONSUMER_DAILY = 0x00A2, // OSC
+ HID_USAGE_CONSUMER_WEEKLY = 0x00A3, // OSC
+ HID_USAGE_CONSUMER_MONTHLY = 0x00A4, // OSC
// A5-AF Reserved
- HID_USAGE_CONSUMER_PLAY = 0x00B0,
- HID_USAGE_CONSUMER_PAUSE = 0x00B1,
- HID_USAGE_CONSUMER_RECORD = 0x00B2,
- HID_USAGE_CONSUMER_FAST_FORWARD = 0x00B3,
- HID_USAGE_CONSUMER_REWIND = 0x00B4,
- HID_USAGE_CONSUMER_SCAN_NEXT_TRACK = 0x00B5,
- HID_USAGE_CONSUMER_SCAN_PREVIOUS_TRACK = 0x00B6,
- HID_USAGE_CONSUMER_STOP = 0x00B7,
- HID_USAGE_CONSUMER_EJECT = 0x00B8,
- HID_USAGE_CONSUMER_RANDOM_PLAY = 0x00B9,
- HID_USAGE_CONSUMER_SELECT_DISC = 0x00BA,
- HID_USAGE_CONSUMER_ENTER_DISC = 0x00BB,
- HID_USAGE_CONSUMER_REPEAT = 0x00BC,
- HID_USAGE_CONSUMER_TRACKING = 0x00BD,
- HID_USAGE_CONSUMER_TRACK_NORMAL = 0x00BE,
- HID_USAGE_CONSUMER_SLOW_TRACKING = 0x00BF,
- HID_USAGE_CONSUMER_FRAME_FORWARD = 0x00C0,
- HID_USAGE_CONSUMER_FRAME_BACK = 0x00C1,
- HID_USAGE_CONSUMER_MARK = 0x00C2,
- HID_USAGE_CONSUMER_CLEAR_MARK = 0x00C3,
- HID_USAGE_CONSUMER_REPEAT_FROM_MARK = 0x00C4,
- HID_USAGE_CONSUMER_RETURN_TO_MARK = 0x00C5,
- HID_USAGE_CONSUMER_SEARCH_MARK_FORWARD = 0x00C6,
- HID_USAGE_CONSUMER_SEARCH_MARK_BACKWARDS = 0x00C7,
- HID_USAGE_CONSUMER_COUNTER_RESET = 0x00C8,
- HID_USAGE_CONSUMER_SHOW_COUNTER = 0x00C9,
- HID_USAGE_CONSUMER_TRACKING_INCREMENT = 0x00CA,
- HID_USAGE_CONSUMER_TRACKING_DECREMENT = 0x00CB,
- HID_USAGE_CONSUMER_STOP_EJECT = 0x00CC,
+ HID_USAGE_CONSUMER_PLAY = 0x00B0, // OOC
+ HID_USAGE_CONSUMER_PAUSE = 0x00B1, // OOC
+ HID_USAGE_CONSUMER_RECORD = 0x00B2, // OOC
+ HID_USAGE_CONSUMER_FAST_FORWARD = 0x00B3, // OOC
+ HID_USAGE_CONSUMER_REWIND = 0x00B4, // OOC
+ HID_USAGE_CONSUMER_SCAN_NEXT_TRACK = 0x00B5, // OSC
+ HID_USAGE_CONSUMER_SCAN_PREVIOUS_TRACK = 0x00B6, // OSC
+ HID_USAGE_CONSUMER_STOP = 0x00B7, // OSC
+ HID_USAGE_CONSUMER_EJECT = 0x00B8, // OSC
+ HID_USAGE_CONSUMER_RANDOM_PLAY = 0x00B9, // OOC
+ HID_USAGE_CONSUMER_SELECT_DISC = 0x00BA, // NAry
+ HID_USAGE_CONSUMER_ENTER_DISC = 0x00BB, // MC
+ HID_USAGE_CONSUMER_REPEAT = 0x00BC, // OSC
+ HID_USAGE_CONSUMER_TRACKING = 0x00BD, // LC
+ HID_USAGE_CONSUMER_TRACK_NORMAL = 0x00BE, // OSC
+ HID_USAGE_CONSUMER_SLOW_TRACKING = 0x00BF, // LC
+ HID_USAGE_CONSUMER_FRAME_FORWARD = 0x00C0, // RTC
+ HID_USAGE_CONSUMER_FRAME_BACK = 0x00C1, // RTC
+ HID_USAGE_CONSUMER_MARK = 0x00C2, // OSC
+ HID_USAGE_CONSUMER_CLEAR_MARK = 0x00C3, // OSC
+ HID_USAGE_CONSUMER_REPEAT_FROM_MARK = 0x00C4, // OOC
+ HID_USAGE_CONSUMER_RETURN_TO_MARK = 0x00C5, // OSC
+ HID_USAGE_CONSUMER_SEARCH_MARK_FORWARD = 0x00C6, // OSC
+ HID_USAGE_CONSUMER_SEARCH_MARK_BACKWARDS = 0x00C7, // OSC
+ HID_USAGE_CONSUMER_COUNTER_RESET = 0x00C8, // OSC
- // Media Control
- HID_USAGE_CONSUMER_PLAY_PAUSE = 0x00CD,
+ // These HID usages operate only on mobile systems (battery powered) and
+ // require Windows 8 (build 8302 or greater).
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_CONTROLS = 0x000C,
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_BUTTONS = 0x00C6,
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_LED = 0x00C7,
+ HID_USAGE_CONSUMER_WIRELESS_RADIO_SLIDER_SWITCH = 0x00C8,
- HID_USAGE_CONSUMER_PLAY_SKIP = 0x00CE,
- // CF-DF Reserved
- HID_USAGE_CONSUMER_VOLUME = 0x00E0,
- HID_USAGE_CONSUMER_BALANCE = 0x00E1,
- HID_USAGE_CONSUMER_MUTE = 0x00E2,
- HID_USAGE_CONSUMER_BASS = 0x00E3,
- HID_USAGE_CONSUMER_TREBLE = 0x00E4,
- HID_USAGE_CONSUMER_BASS_BOOST = 0x00E5,
- HID_USAGE_CONSUMER_SURROUND_MODE = 0x00E6,
- HID_USAGE_CONSUMER_LOUDNESS = 0x00E7,
- HID_USAGE_CONSUMER_MPX = 0x00E8,
- HID_USAGE_CONSUMER_VOLUME_INCREMENT = 0x00E9,
- HID_USAGE_CONSUMER_VOLUME_DECREMENT = 0x00EA,
+ HID_USAGE_CONSUMER_SHOW_COUNTER = 0x00C9, // OSC
+ HID_USAGE_CONSUMER_TRACKING_INCREMENT = 0x00CA, // RTC
+ HID_USAGE_CONSUMER_TRACKING_DECREMENT = 0x00CB, // RTC
+ HID_USAGE_CONSUMER_STOP_EJECT = 0x00CC, // OSC
+ HID_USAGE_CONSUMER_PLAY_PAUSE = 0x00CD, // OSC
+ HID_USAGE_CONSUMER_PLAY_SKIP = 0x00CE, // OSC
+ HID_USAGE_CONSUMER_VOICE_COMMAND = 0x00CF, // OSC
+ HID_USAGE_CONSUMER_INVOKE_CAPTURE_INTERFACE = 0x00D0, // Sel
+ HID_USAGE_CONSUMER_START_OR_STOP_GAME_RECORDING = 0x00D1, // Sel
+ HID_USAGE_CONSUMER_HISTORICAL_GAME_CAPTURE = 0x00D2, // Sel
+ HID_USAGE_CONSUMER_CAPTURE_GAME_SCREENSHOT = 0x00D3, // Sel
+ HID_USAGE_CONSUMER_SHOW_OR_HIDE_RECORDING_INDICATOR = 0x00D4, // Sel
+ HID_USAGE_CONSUMER_START_OR_STOP_MICROPHONE_CAPTURE = 0x00D5, // Sel
+ HID_USAGE_CONSUMER_START_OR_STOP_CAMERA_CAPTURE = 0x00D6, // Sel
+ HID_USAGE_CONSUMER_START_OR_STOP_GAME_BROADCAST = 0x00D7, // Sel
+ HID_USAGE_CONSUMER_START_OR_STOP_VOICE_DICTATION_SESSION = 0x00D8, // OOC
+ HID_USAGE_CONSUMER_INVOKE_DISMISS_EMOJI_PICKER = 0x00D9, // OOC
+ // DA-DF Reserved
+ HID_USAGE_CONSUMER_VOLUME = 0x00E0, // LC
+ HID_USAGE_CONSUMER_BALANCE = 0x00E1, // LC
+ HID_USAGE_CONSUMER_MUTE = 0x00E2, // OOC
+ HID_USAGE_CONSUMER_BASS = 0x00E3, // LC
+ HID_USAGE_CONSUMER_TREBLE = 0x00E4, // LC
+ HID_USAGE_CONSUMER_BASS_BOOST = 0x00E5, // OOC
+ HID_USAGE_CONSUMER_SURROUND_MODE = 0x00E6, // OSC
+ HID_USAGE_CONSUMER_LOUDNESS = 0x00E7, // OOC
+ HID_USAGE_CONSUMER_MPX = 0x00E8, // OOC
+ HID_USAGE_CONSUMER_VOLUME_INCREMENT = 0x00E9, // RTC
+ HID_USAGE_CONSUMER_VOLUME_DECREMENT = 0x00EA, // RTC
// EB-EF Reserved
- HID_USAGE_CONSUMER_SPEED_SELECT = 0x00F0,
- HID_USAGE_CONSUMER_PLAYBACK_SPEED = 0x00F1,
- HID_USAGE_CONSUMER_STANDARD_PLAY = 0x00F2,
- HID_USAGE_CONSUMER_LONG_PLAY = 0x00F3,
- HID_USAGE_CONSUMER_EXTENDED_PLAY = 0x00F4,
- HID_USAGE_CONSUMER_SLOW = 0x00F5,
+ HID_USAGE_CONSUMER_SPEED_SELECT = 0x00F0, // OSC
+ HID_USAGE_CONSUMER_PLAYBACK_SPEED = 0x00F1, // NAry
+ HID_USAGE_CONSUMER_STANDARD_PLAY = 0x00F2, // Sel
+ HID_USAGE_CONSUMER_LONG_PLAY = 0x00F3, // Sel
+ HID_USAGE_CONSUMER_EXTENDED_PLAY = 0x00F4, // Sel
+ HID_USAGE_CONSUMER_SLOW = 0x00F5, // OSC
// F6-FF Reserved
- HID_USAGE_CONSUMER_FAN_ENABLE = 0x0100,
- HID_USAGE_CONSUMER_FAN_SPEED = 0x0101,
- HID_USAGE_CONSUMER_LIGHT_ENABLE = 0x0102,
- HID_USAGE_CONSUMER_LIGHT_ILLUMINATION_LEVEL = 0x0103,
- HID_USAGE_CONSUMER_CLIMATE_CONTROL_ENABLE = 0x0104,
- HID_USAGE_CONSUMER_ROOM_TEMPERATURE = 0x0105,
- HID_USAGE_CONSUMER_SECURITY_ENABLE = 0x0106,
- HID_USAGE_CONSUMER_FIRE_ALARM = 0x0107,
- HID_USAGE_CONSUMER_POLICE_ALARM = 0x0108,
- HID_USAGE_CONSUMER_PROXIMITY = 0x0109,
- HID_USAGE_CONSUMER_MOTION = 0x010A,
- HID_USAGE_CONSUMER_DURESS_ALARM = 0x010B,
- HID_USAGE_CONSUMER_HOLDUP_ALARM = 0x010C,
- HID_USAGE_CONSUMER_MEDICAL_ALARM = 0x010D,
+ HID_USAGE_CONSUMER_FAN_ENABLE = 0x0100, // OOC
+ HID_USAGE_CONSUMER_FAN_SPEED = 0x0101, // LC
+ HID_USAGE_CONSUMER_LIGHT_ENABLE = 0x0102, // OOC
+ HID_USAGE_CONSUMER_LIGHT_ILLUMINATION_LEVEL = 0x0103, // LC
+ HID_USAGE_CONSUMER_CLIMATE_CONTROL_ENABLE = 0x0104, // OOC
+ HID_USAGE_CONSUMER_ROOM_TEMPERATURE = 0x0105, // LC
+ HID_USAGE_CONSUMER_SECURITY_ENABLE = 0x0106, // OOC
+ HID_USAGE_CONSUMER_FIRE_ALARM = 0x0107, // OSC
+ HID_USAGE_CONSUMER_POLICE_ALARM = 0x0108, // OSC
+ HID_USAGE_CONSUMER_PROXIMITY = 0x0109, // LC
+ HID_USAGE_CONSUMER_MOTION = 0x010A, // OSC
+ HID_USAGE_CONSUMER_DURESS_ALARM = 0x010B, // OSC
+ HID_USAGE_CONSUMER_HOLDUP_ALARM = 0x010C, // OSC
+ HID_USAGE_CONSUMER_MEDICAL_ALARM = 0x010D, // OSC
// 10E-14F Reserved
- HID_USAGE_CONSUMER_BALANCE_RIGHT = 0x0150,
- HID_USAGE_CONSUMER_BALANCE_LEFT = 0x0151,
- HID_USAGE_CONSUMER_BASS_INCREMENT = 0x0152,
- HID_USAGE_CONSUMER_BASS_DECREMENT = 0x0153,
- HID_USAGE_CONSUMER_TREBLE_INCREMENT = 0x0154,
- HID_USAGE_CONSUMER_TREBLE_DECREMENT = 0x0155,
+ HID_USAGE_CONSUMER_BALANCE_RIGHT = 0x0150, // RTC
+ HID_USAGE_CONSUMER_BALANCE_LEFT = 0x0151, // RTC
+ HID_USAGE_CONSUMER_BASS_INCREMENT = 0x0152, // RTC
+ HID_USAGE_CONSUMER_BASS_DECREMENT = 0x0153, // RTC
+ HID_USAGE_CONSUMER_TREBLE_INCREMENT = 0x0154, // RTC
+ HID_USAGE_CONSUMER_TREBLE_DECREMENT = 0x0155, // RTC
// 156-15F Reserved
- HID_USAGE_CONSUMER_SPEAKER_SYSTEM = 0x0160,
- HID_USAGE_CONSUMER_CHANNEL_LEFT = 0x0161,
- HID_USAGE_CONSUMER_CHANNEL_RIGHT = 0x0162,
- HID_USAGE_CONSUMER_CHANNEL_CENTER = 0x0163,
- HID_USAGE_CONSUMER_CHANNEL_FRONT = 0x0164,
- HID_USAGE_CONSUMER_CHANNEL_CENTER_FRONT = 0x0165,
- HID_USAGE_CONSUMER_CHANNEL_SIDE = 0x0166,
- HID_USAGE_CONSUMER_CHANNEL_SURROUND = 0x0167,
- HID_USAGE_CONSUMER_CHANNEL_LOW_FREQUENCY = 0x0168,
- // Enhancement
- // CL 15.12.1
- HID_USAGE_CONSUMER_CHANNEL_TOP = 0x0169,
- HID_USAGE_CONSUMER_CHANNEL_UNKNOWN = 0x016A,
+ HID_USAGE_CONSUMER_SPEAKER_SYSTEM = 0x0160, // CL
+ HID_USAGE_CONSUMER_CHANNEL_LEFT = 0x0161, // CL
+ HID_USAGE_CONSUMER_CHANNEL_RIGHT = 0x0162, // CL
+ HID_USAGE_CONSUMER_CHANNEL_CENTER = 0x0163, // CL
+ HID_USAGE_CONSUMER_CHANNEL_FRONT = 0x0164, // CL
+ HID_USAGE_CONSUMER_CHANNEL_CENTER_FRONT = 0x0165, // CL
+ HID_USAGE_CONSUMER_CHANNEL_SIDE = 0x0166, // CL
+ HID_USAGE_CONSUMER_CHANNEL_SURROUND = 0x0167, // CL
+ HID_USAGE_CONSUMER_CHANNEL_LOW_FREQUENCY = 0x0168, // CL
+ HID_USAGE_CONSUMER_CHANNEL_TOP = 0x0169, // CL
+ HID_USAGE_CONSUMER_CHANNEL_UNKNOWN = 0x016A, // CL
// 16B-16F Reserved
- HID_USAGE_CONSUMER_SUB_CHANNEL = 0x0170,
- HID_USAGE_CONSUMER_SUB_CHANNEL_INCREMENT = 0x0171,
- HID_USAGE_CONSUMER_SUB_CHANNEL_DECREMENT = 0x0172,
- HID_USAGE_CONSUMER_ALTERNATE_AUDIO_INCREMENT = 0x0173,
- HID_USAGE_CONSUMER_ALTERNATE_AUDIO_DECREMENT = 0x0174,
+ HID_USAGE_CONSUMER_SUB_CHANNEL = 0x0170, // LC
+ HID_USAGE_CONSUMER_SUB_CHANNEL_INCREMENT = 0x0171, // OSC
+ HID_USAGE_CONSUMER_SUB_CHANNEL_DECREMENT = 0x0172, // OSC
+ HID_USAGE_CONSUMER_ALTERNATE_AUDIO_INCREMENT = 0x0173, // OSC
+ HID_USAGE_CONSUMER_ALTERNATE_AUDIO_DECREMENT = 0x0174, // OSC
// 175-17F Reserved
- HID_USAGE_CONSUMER_APPLICATION_LAUNCH_BUTTONS = 0x0180,
- HID_USAGE_CONSUMER_AL_LAUNCH_BUTTON_CONFIGURATION = 0x0181,
- // Tool
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_PROGRAMMABLE_BUTTON = 0x0182,
- // Configuration
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183,
- // Configuration
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_WORD_PROCESSOR = 0x0184,
- HID_USAGE_CONSUMER_AL_TEXT_EDITOR = 0x0185,
- HID_USAGE_CONSUMER_AL_SPREADSHEET = 0x0186,
- HID_USAGE_CONSUMER_AL_GRAPHICS_EDITOR = 0x0187,
- HID_USAGE_CONSUMER_AL_PRESENTATION_APP = 0x0188,
- HID_USAGE_CONSUMER_AL_DATABASE_APP = 0x0189,
- HID_USAGE_CONSUMER_AL_EMAIL_READER = 0x018A,
- HID_USAGE_CONSUMER_AL_NEWSREADER = 0x018B,
- HID_USAGE_CONSUMER_AL_VOICEMAIL = 0x018C,
- HID_USAGE_CONSUMER_AL_CONTACTS_ADDRESS_BOOK = 0x018D,
- HID_USAGE_CONSUMER_AL_CALENDAR_SCHEDULE = 0x018E,
- HID_USAGE_CONSUMER_AL_TASK_PROJECT_MANAGER = 0x018F,
- HID_USAGE_CONSUMER_AL_LOG_JOURNAL_TIMECARD = 0x0190,
- HID_USAGE_CONSUMER_AL_CHECKBOOK_FINANCE = 0x0191,
- HID_USAGE_CONSUMER_AL_CALCULATOR = 0x0192,
- HID_USAGE_CONSUMER_AL_A_V_CAPTURE_PLAYBACK = 0x0193,
- HID_USAGE_CONSUMER_AL_LOCAL_MACHINE_BROWSER = 0x0194,
- HID_USAGE_CONSUMER_AL_LAN_WAN_BROWSER = 0x0195,
- HID_USAGE_CONSUMER_AL_INTERNET_BROWSER = 0x0196,
- HID_USAGE_CONSUMER_AL_REMOTE_NETWORKING_ISP = 0x0197,
- // Connect
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_NETWORK_CONFERENCE = 0x0198,
- HID_USAGE_CONSUMER_AL_NETWORK_CHAT = 0x0199,
- HID_USAGE_CONSUMER_AL_TELEPHONY_DIALER = 0x019A,
- HID_USAGE_CONSUMER_AL_LOGON = 0x019B,
- HID_USAGE_CONSUMER_AL_LOGOFF = 0x019C,
- HID_USAGE_CONSUMER_AL_LOGON_LOGOFF = 0x019D,
- HID_USAGE_CONSUMER_AL_TERMINAL_LOCK_SCREENSAVER = 0x019E,
- HID_USAGE_CONSUMER_AL_CONTROL_PANEL = 0x019F,
- HID_USAGE_CONSUMER_AL_COMMAND_LINE_PROCESSOR_RUN = 0x01A0,
- HID_USAGE_CONSUMER_AL_PROCESS_TASK_MANAGER = 0x01A1,
- HID_USAGE_CONSUMER_AL_SELECT_TASK_APPLICATION = 0x01A2,
- HID_USAGE_CONSUMER_AL_NEXT_TASK_APPLICATION = 0x01A3,
- HID_USAGE_CONSUMER_AL_PREVIOUS_TASK_APPLICATION = 0x01A4,
- HID_USAGE_CONSUMER_AL_PREEMPTIVE_HALT = 0x01A5,
- // Task_Application
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_INTEGRATED_HELP_CENTER = 0x01A6,
- HID_USAGE_CONSUMER_AL_DOCUMENTS = 0x01A7,
- HID_USAGE_CONSUMER_AL_THESAURUS = 0x01A8,
- HID_USAGE_CONSUMER_AL_DICTIONARY = 0x01A9,
- HID_USAGE_CONSUMER_AL_DESKTOP = 0x01AA,
- HID_USAGE_CONSUMER_AL_SPELL_CHECK = 0x01AB,
- HID_USAGE_CONSUMER_AL_GRAMMAR_CHECK = 0x01AC,
- HID_USAGE_CONSUMER_AL_WIRELESS_STATUS = 0x01AD,
- HID_USAGE_CONSUMER_AL_KEYBOARD_LAYOUT = 0x01AE,
- HID_USAGE_CONSUMER_AL_VIRUS_PROTECTION = 0x01AF,
- HID_USAGE_CONSUMER_AL_ENCRYPTION = 0x01B0,
- HID_USAGE_CONSUMER_AL_SCREEN_SAVER = 0x01B1,
- HID_USAGE_CONSUMER_AL_ALARMS = 0x01B2,
- HID_USAGE_CONSUMER_AL_CLOCK = 0x01B3,
- HID_USAGE_CONSUMER_AL_FILE_BROWSER = 0x01B4,
- HID_USAGE_CONSUMER_AL_POWER_STATUS = 0x01B5,
- HID_USAGE_CONSUMER_AL_IMAGE_BROWSER = 0x01B6,
- HID_USAGE_CONSUMER_AL_AUDIO_BROWSER = 0x01B7,
- HID_USAGE_CONSUMER_AL_MOVIE_BROWSER = 0x01B8,
- HID_USAGE_CONSUMER_AL_DIGITAL_RIGHTS_MANAGER = 0x01B9,
- HID_USAGE_CONSUMER_AL_DIGITAL_WALLET = 0x01BA,
+ HID_USAGE_CONSUMER_APPLICATION_LAUNCH_BUTTONS = 0x0180, // NAry
+ HID_USAGE_CONSUMER_AL_LAUNCH_BUTTON_CONFIGURATION = 0x0181, // Sel
+ HID_USAGE_CONSUMER_AL_PROGRAMMABLE_BUTTON = 0x0182, // Sel
+ HID_USAGE_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION = 0x0183, // Sel
+ HID_USAGE_CONSUMER_AL_WORD_PROCESSOR = 0x0184, // Sel
+ HID_USAGE_CONSUMER_AL_TEXT_EDITOR = 0x0185, // Sel
+ HID_USAGE_CONSUMER_AL_SPREADSHEET = 0x0186, // Sel
+ HID_USAGE_CONSUMER_AL_GRAPHICS_EDITOR = 0x0187, // Sel
+ HID_USAGE_CONSUMER_AL_PRESENTATION_APP = 0x0188, // Sel
+ HID_USAGE_CONSUMER_AL_DATABASE_APP = 0x0189, // Sel
+ HID_USAGE_CONSUMER_AL_EMAIL_READER = 0x018A, // Sel
+ HID_USAGE_CONSUMER_AL_NEWSREADER = 0x018B, // Sel
+ HID_USAGE_CONSUMER_AL_VOICEMAIL = 0x018C, // Sel
+ HID_USAGE_CONSUMER_AL_CONTACTS_ADDRESS_BOOK = 0x018D, // Sel
+ HID_USAGE_CONSUMER_AL_CALENDAR_SCHEDULE = 0x018E, // Sel
+ HID_USAGE_CONSUMER_AL_TASK_PROJECT_MANAGER = 0x018F, // Sel
+ HID_USAGE_CONSUMER_AL_LOG_JOURNAL_TIMECARD = 0x0190, // Sel
+ HID_USAGE_CONSUMER_AL_CHECKBOOK_FINANCE = 0x0191, // Sel
+ HID_USAGE_CONSUMER_AL_CALCULATOR = 0x0192, // Sel
+ HID_USAGE_CONSUMER_AL_A_V_CAPTURE_PLAYBACK = 0x0193, // Sel
+ HID_USAGE_CONSUMER_AL_LOCAL_MACHINE_BROWSER = 0x0194, // Sel
+ HID_USAGE_CONSUMER_AL_LAN_WAN_BROWSER = 0x0195, // Sel
+ HID_USAGE_CONSUMER_AL_INTERNET_BROWSER = 0x0196, // Sel
+ HID_USAGE_CONSUMER_AL_REMOTE_NETWORKING_ISP = 0x0197, // Sel
+ HID_USAGE_CONSUMER_AL_NETWORK_CONFERENCE = 0x0198, // Sel
+ HID_USAGE_CONSUMER_AL_NETWORK_CHAT = 0x0199, // Sel
+ HID_USAGE_CONSUMER_AL_TELEPHONY_DIALER = 0x019A, // Sel
+ HID_USAGE_CONSUMER_AL_LOGON = 0x019B, // Sel
+ HID_USAGE_CONSUMER_AL_LOGOFF = 0x019C, // Sel
+ HID_USAGE_CONSUMER_AL_LOGON_LOGOFF = 0x019D, // Sel
+ HID_USAGE_CONSUMER_AL_TERMINAL_LOCK_SCREENSAVER = 0x019E, // Sel
+ HID_USAGE_CONSUMER_AL_CONTROL_PANEL = 0x019F, // Sel
+ HID_USAGE_CONSUMER_AL_COMMAND_LINE_PROCESSOR_RUN = 0x01A0, // Sel
+ HID_USAGE_CONSUMER_AL_PROCESS_TASK_MANAGER = 0x01A1, // Sel
+ HID_USAGE_CONSUMER_AL_SELECT_TASK_APPLICATION = 0x01A2, // Sel
+ HID_USAGE_CONSUMER_AL_NEXT_TASK_APPLICATION = 0x01A3, // Sel
+ HID_USAGE_CONSUMER_AL_PREVIOUS_TASK_APPLICATION = 0x01A4, // Sel
+ HID_USAGE_CONSUMER_AL_PREEMPTIVE_HALT = 0x01A5, // Sel
+ HID_USAGE_CONSUMER_AL_INTEGRATED_HELP_CENTER = 0x01A6, // Sel
+ HID_USAGE_CONSUMER_AL_DOCUMENTS = 0x01A7, // Sel
+ HID_USAGE_CONSUMER_AL_THESAURUS = 0x01A8, // Sel
+ HID_USAGE_CONSUMER_AL_DICTIONARY = 0x01A9, // Sel
+ HID_USAGE_CONSUMER_AL_DESKTOP = 0x01AA, // Sel
+ HID_USAGE_CONSUMER_AL_SPELL_CHECK = 0x01AB, // Sel
+ HID_USAGE_CONSUMER_AL_GRAMMAR_CHECK = 0x01AC, // Sel
+ HID_USAGE_CONSUMER_AL_WIRELESS_STATUS = 0x01AD, // Sel
+ HID_USAGE_CONSUMER_AL_KEYBOARD_LAYOUT = 0x01AE, // Sel
+ HID_USAGE_CONSUMER_AL_VIRUS_PROTECTION = 0x01AF, // Sel
+ HID_USAGE_CONSUMER_AL_ENCRYPTION = 0x01B0, // Sel
+ HID_USAGE_CONSUMER_AL_SCREEN_SAVER = 0x01B1, // Sel
+ HID_USAGE_CONSUMER_AL_ALARMS = 0x01B2, // Sel
+ HID_USAGE_CONSUMER_AL_CLOCK = 0x01B3, // Sel
+ HID_USAGE_CONSUMER_AL_FILE_BROWSER = 0x01B4, // Sel
+ HID_USAGE_CONSUMER_AL_POWER_STATUS = 0x01B5, // Sel
+ HID_USAGE_CONSUMER_AL_IMAGE_BROWSER = 0x01B6, // Sel
+ HID_USAGE_CONSUMER_AL_AUDIO_BROWSER = 0x01B7, // Sel
+ HID_USAGE_CONSUMER_AL_MOVIE_BROWSER = 0x01B8, // Sel
+ HID_USAGE_CONSUMER_AL_DIGITAL_RIGHTS_MANAGER = 0x01B9, // Sel
+ HID_USAGE_CONSUMER_AL_DIGITAL_WALLET = 0x01BA, // Sel
// 1BB Reserved
- HID_USAGE_CONSUMER_AL_INSTANT_MESSAGING = 0x01BC,
- HID_USAGE_CONSUMER_AL_OEM_FEATURES_TIPS_TUTORIAL = 0x01BD,
- // Browser
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_OEM_HELP = 0x01BE,
- HID_USAGE_CONSUMER_AL_ONLINE_COMMUNITY = 0x01BF,
- HID_USAGE_CONSUMER_AL_ENTERTAINMENT_CONTENT = 0x01C0,
- // Browser
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_ONLINE_SHOPPING_BROWSER = 0x01C1,
- HID_USAGE_CONSUMER_AL_SMARTCARD_INFORMATION_HELP = 0x01C2,
- HID_USAGE_CONSUMER_AL_MARKET_MONITOR_FINANCE = 0x01C3,
- // Browser
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_CUSTOMIZED_CORPORATE_NEWS = 0x01C4,
- // Browser
- // Sel 15.15
- HID_USAGE_CONSUMER_AL_ONLINE_ACTIVITY_BROWSER = 0x01C5,
- HID_USAGE_CONSUMER_AL_RESEARCH_SEARCH_BROWSER = 0x01C6,
- HID_USAGE_CONSUMER_AL_AUDIO_PLAYER = 0x01C7,
- // 1C8-1FF Reserved
- HID_USAGE_CONSUMER_GENERIC_GUI_APPLICATION = 0x0200,
- // ' Controls
- // '
- HID_USAGE_CONSUMER_AC_NEW = 0x0201,
- HID_USAGE_CONSUMER_AC_OPEN = 0x0202,
- HID_USAGE_CONSUMER_AC_CLOSE = 0x0203,
- HID_USAGE_CONSUMER_AC_EXIT = 0x0204,
- HID_USAGE_CONSUMER_AC_MAXIMIZE = 0x0205,
- HID_USAGE_CONSUMER_AC_MINIMIZE = 0x0206,
- HID_USAGE_CONSUMER_AC_SAVE = 0x0207,
- HID_USAGE_CONSUMER_AC_PRINT = 0x0208,
- HID_USAGE_CONSUMER_AC_PROPERTIES = 0x0209,
- HID_USAGE_CONSUMER_AC_UNDO = 0x021A,
- HID_USAGE_CONSUMER_AC_COPY = 0x021B,
- HID_USAGE_CONSUMER_AC_CUT = 0x021C,
- HID_USAGE_CONSUMER_AC_PASTE = 0x021D,
- HID_USAGE_CONSUMER_AC_SELECT_ALL = 0x021E,
- HID_USAGE_CONSUMER_AC_FIND = 0x021F,
- HID_USAGE_CONSUMER_AC_FIND_AND_REPLACE = 0x0220,
- // Browser/Explorer Specific
- HID_USAGE_CONSUMER_AC_SEARCH = 0x0221,
- HID_USAGE_CONSUMER_AC_GO_TO = 0x0222,
- HID_USAGE_CONSUMER_AC_HOME = 0x0223,
- HID_USAGE_CONSUMER_AC_BACK = 0x0224,
- HID_USAGE_CONSUMER_AC_FORWARD = 0x0225,
- HID_USAGE_CONSUMER_AC_STOP = 0x0226,
- HID_USAGE_CONSUMER_AC_REFRESH = 0x0227,
- HID_USAGE_CONSUMER_AC_PREVIOUS_LINK = 0x0228,
- HID_USAGE_CONSUMER_AC_NEXT_LINK = 0x0229,
- HID_USAGE_CONSUMER_AC_BOOKMARKS = 0x022A,
- HID_USAGE_CONSUMER_AC_HISTORY = 0x022B,
- HID_USAGE_CONSUMER_AC_SUBSCRIPTIONS = 0x022C,
- HID_USAGE_CONSUMER_AC_ZOOM_IN = 0x022D,
- HID_USAGE_CONSUMER_AC_ZOOM_OUT = 0x022E,
- HID_USAGE_CONSUMER_AC_ZOOM = 0x022F,
- HID_USAGE_CONSUMER_AC_FULL_SCREEN_VIEW = 0x0230,
- HID_USAGE_CONSUMER_AC_NORMAL_VIEW = 0x0231,
- HID_USAGE_CONSUMER_AC_VIEW_TOGGLE = 0x0232,
- HID_USAGE_CONSUMER_AC_SCROLL_UP = 0x0233,
- HID_USAGE_CONSUMER_AC_SCROLL_DOWN = 0x0234,
- HID_USAGE_CONSUMER_AC_SCROLL = 0x0235,
- HID_USAGE_CONSUMER_AC_PAN_LEFT = 0x0236,
- HID_USAGE_CONSUMER_AC_PAN_RIGHT = 0x0237,
- // Mouse Horizontal scroll
- HID_USAGE_CONSUMER_AC_PAN = 0x0238,
- HID_USAGE_CONSUMER_AC_NEW_WINDOW = 0x0239,
- HID_USAGE_CONSUMER_AC_TILE_HORIZONTALLY = 0x023A,
- HID_USAGE_CONSUMER_AC_TILE_VERTICALLY = 0x023B,
- HID_USAGE_CONSUMER_AC_FORMAT = 0x023C,
- HID_USAGE_CONSUMER_AC_EDIT = 0x023D,
- HID_USAGE_CONSUMER_AC_BOLD = 0x023E,
- HID_USAGE_CONSUMER_AC_ITALICS = 0x023F,
- HID_USAGE_CONSUMER_AC_UNDERLINE = 0x0240,
- HID_USAGE_CONSUMER_AC_STRIKETHROUGH = 0x0241,
- HID_USAGE_CONSUMER_AC_SUBSCRIPT = 0x0242,
- HID_USAGE_CONSUMER_AC_SUPERSCRIPT = 0x0243,
- HID_USAGE_CONSUMER_AC_ALL_CAPS = 0x0244,
- HID_USAGE_CONSUMER_AC_ROTATE = 0x0245,
- HID_USAGE_CONSUMER_AC_RESIZE = 0x0246,
- HID_USAGE_CONSUMER_AC_FLIP_HORIZONTAL = 0x0247,
- HID_USAGE_CONSUMER_AC_FLIP_VERTICAL = 0x0248,
- HID_USAGE_CONSUMER_AC_MIRROR_HORIZONTAL = 0x0249,
- HID_USAGE_CONSUMER_AC_MIRROR_VERTICAL = 0x024A,
- HID_USAGE_CONSUMER_AC_FONT_SELECT = 0x024B,
- HID_USAGE_CONSUMER_AC_FONT_COLOR = 0x024C,
- HID_USAGE_CONSUMER_AC_FONT_SIZE = 0x024D,
- HID_USAGE_CONSUMER_AC_JUSTIFY_LEFT = 0x024E,
- HID_USAGE_CONSUMER_AC_JUSTIFY_CENTER_H = 0x024F,
- HID_USAGE_CONSUMER_AC_JUSTIFY_RIGHT = 0x0250,
- HID_USAGE_CONSUMER_AC_JUSTIFY_BLOCK_H = 0x0251,
- HID_USAGE_CONSUMER_AC_JUSTIFY_TOP = 0x0252,
- HID_USAGE_CONSUMER_AC_JUSTIFY_CENTER_V = 0x0253,
- HID_USAGE_CONSUMER_AC_JUSTIFY_BOTTOM = 0x0254,
- HID_USAGE_CONSUMER_AC_JUSTIFY_BLOCK_V = 0x0255,
- HID_USAGE_CONSUMER_AC_INDENT_DECREASE = 0x0256,
- HID_USAGE_CONSUMER_AC_INDENT_INCREASE = 0x0257,
- HID_USAGE_CONSUMER_AC_NUMBERED_LIST = 0x0258,
- HID_USAGE_CONSUMER_AC_RESTART_NUMBERING = 0x0259,
- HID_USAGE_CONSUMER_AC_BULLETED_LIST = 0x025A,
- HID_USAGE_CONSUMER_AC_PROMOTE = 0x025B,
- HID_USAGE_CONSUMER_AC_DEMOTE = 0x025C,
- HID_USAGE_CONSUMER_AC_YES = 0x025D,
- HID_USAGE_CONSUMER_AC_NO = 0x025E,
- HID_USAGE_CONSUMER_AC_CANCEL = 0x025F,
- HID_USAGE_CONSUMER_AC_CATALOG = 0x0260,
- HID_USAGE_CONSUMER_AC_BUY_CHECKOUT = 0x0261,
- HID_USAGE_CONSUMER_AC_ADD_TO_CART = 0x0262,
- HID_USAGE_CONSUMER_AC_EXPAND = 0x0263,
- HID_USAGE_CONSUMER_AC_EXPAND_ALL = 0x0264,
- HID_USAGE_CONSUMER_AC_COLLAPSE = 0x0265,
- HID_USAGE_CONSUMER_AC_COLLAPSE_ALL = 0x0266,
- HID_USAGE_CONSUMER_AC_PRINT_PREVIEW = 0x0267,
- HID_USAGE_CONSUMER_AC_PASTE_SPECIAL = 0x0268,
- HID_USAGE_CONSUMER_AC_INSERT_MODE = 0x0269,
- HID_USAGE_CONSUMER_AC_DELETE = 0x026A,
- HID_USAGE_CONSUMER_AC_LOCK = 0x026B,
- HID_USAGE_CONSUMER_AC_UNLOCK = 0x026C,
- HID_USAGE_CONSUMER_AC_PROTECT = 0x026D,
- HID_USAGE_CONSUMER_AC_UNPROTECT = 0x026E,
- HID_USAGE_CONSUMER_AC_ATTACH_COMMENT = 0x026F,
- HID_USAGE_CONSUMER_AC_DELETE_COMMENT = 0x0270,
- HID_USAGE_CONSUMER_AC_VIEW_COMMENT = 0x0271,
- HID_USAGE_CONSUMER_AC_SELECT_WORD = 0x0272,
- HID_USAGE_CONSUMER_AC_SELECT_SENTENCE = 0x0273,
- HID_USAGE_CONSUMER_AC_SELECT_PARAGRAPH = 0x0274,
- HID_USAGE_CONSUMER_AC_SELECT_COLUMN = 0x0275,
- HID_USAGE_CONSUMER_AC_SELECT_ROW = 0x0276,
- HID_USAGE_CONSUMER_AC_SELECT_TABLE = 0x0277,
- HID_USAGE_CONSUMER_AC_SELECT_OBJECT = 0x0278,
- HID_USAGE_CONSUMER_AC_REDO_REPEAT = 0x0279,
- HID_USAGE_CONSUMER_AC_SORT = 0x027A,
- HID_USAGE_CONSUMER_AC_SORT_ASCENDING = 0x027B,
- HID_USAGE_CONSUMER_AC_SORT_DESCENDING = 0x027C,
- HID_USAGE_CONSUMER_AC_FILTER = 0x027D,
- HID_USAGE_CONSUMER_AC_SET_CLOCK = 0x027E,
- HID_USAGE_CONSUMER_AC_VIEW_CLOCK = 0x027F,
- HID_USAGE_CONSUMER_AC_SELECT_TIME_ZONE = 0x0280,
- HID_USAGE_CONSUMER_AC_EDIT_TIME_ZONES = 0x0281,
- HID_USAGE_CONSUMER_AC_SET_ALARM = 0x0282,
- HID_USAGE_CONSUMER_AC_CLEAR_ALARM = 0x0283,
- HID_USAGE_CONSUMER_AC_SNOOZE_ALARM = 0x0284,
- HID_USAGE_CONSUMER_AC_RESET_ALARM = 0x0285,
- HID_USAGE_CONSUMER_AC_SYNCHRONIZE = 0x0286,
- HID_USAGE_CONSUMER_AC_SEND_RECEIVE = 0x0287,
- HID_USAGE_CONSUMER_AC_SEND_TO = 0x0288,
- HID_USAGE_CONSUMER_AC_REPLY = 0x0289,
- HID_USAGE_CONSUMER_AC_REPLY_ALL = 0x028A,
- HID_USAGE_CONSUMER_AC_FORWARD_MSG = 0x028B,
- HID_USAGE_CONSUMER_AC_SEND = 0x028C,
- HID_USAGE_CONSUMER_AC_ATTACH_FILE = 0x028D,
- HID_USAGE_CONSUMER_AC_UPLOAD = 0x028E,
- HID_USAGE_CONSUMER_AC_DOWNLOAD_SAVE_TARGET_AS = 0x028F,
- HID_USAGE_CONSUMER_AC_SET_BORDERS = 0x0290,
- HID_USAGE_CONSUMER_AC_INSERT_ROW = 0x0291,
- HID_USAGE_CONSUMER_AC_INSERT_COLUMN = 0x0292,
- HID_USAGE_CONSUMER_AC_INSERT_FILE = 0x0293,
- HID_USAGE_CONSUMER_AC_INSERT_PICTURE = 0x0294,
- HID_USAGE_CONSUMER_AC_INSERT_OBJECT = 0x0295,
- HID_USAGE_CONSUMER_AC_INSERT_SYMBOL = 0x0296,
- HID_USAGE_CONSUMER_AC_SAVE_AND_CLOSE = 0x0297,
- HID_USAGE_CONSUMER_AC_RENAME = 0x0298,
- HID_USAGE_CONSUMER_AC_MERGE = 0x0299,
- HID_USAGE_CONSUMER_AC_SPLIT = 0x029A,
- HID_USAGE_CONSUMER_AC_DISRIBUTE_HORIZONTALLY = 0x029B,
- HID_USAGE_CONSUMER_AC_DISTRIBUTE_VERTICALLY = 0x029C,
- // 29D-FFFF Reserved
+ HID_USAGE_CONSUMER_AL_INSTANT_MESSAGING = 0x01BC, // Sel
+ HID_USAGE_CONSUMER_AL_OEM_FEATURES_TIPS_TUTORIAL = 0x01BD, // Sel
+ HID_USAGE_CONSUMER_AL_OEM_HELP = 0x01BE, // Sel
+ HID_USAGE_CONSUMER_AL_ONLINE_COMMUNITY = 0x01BF, // Sel
+ HID_USAGE_CONSUMER_AL_ENTERTAINMENT_CONTENT = 0x01C0, // Sel
+ HID_USAGE_CONSUMER_AL_ONLINE_SHOPPING_BROWSER = 0x01C1, // Sel
+ HID_USAGE_CONSUMER_AL_SMARTCARD_INFORMATION_HELP = 0x01C2, // Sel
+ HID_USAGE_CONSUMER_AL_MARKET_MONITOR_FINANCE = 0x01C3, // Sel
+ HID_USAGE_CONSUMER_AL_CUSTOMIZED_CORPORATE_NEWS = 0x01C4, // Sel
+ HID_USAGE_CONSUMER_AL_ONLINE_ACTIVITY_BROWSER = 0x01C5, // Sel
+ HID_USAGE_CONSUMER_AL_RESEARCH_SEARCH_BROWSER = 0x01C6, // Sel
+ HID_USAGE_CONSUMER_AL_AUDIO_PLAYER = 0x01C7, // Sel
+ HID_USAGE_CONSUMER_AL_MESSAGE_STATUS = 0x01C8, // Sel
+ HID_USAGE_CONSUMER_AL_CONTACT_SYNC = 0x01C9, // Sel
+ HID_USAGE_CONSUMER_AL_NAVIGATION = 0x01CA, // Sel
+ HID_USAGE_CONSUMER_AL_CONTEXT_AWARE_DESKTOP_ASSISTANT = 0x01CB, // Sel
+ // 1CC-1FF Reserved
+ HID_USAGE_CONSUMER_GENERIC_GUI_APPLICATION = 0x0200, // NAry
+ HID_USAGE_CONSUMER_AC_NEW = 0x0201, // Sel
+ HID_USAGE_CONSUMER_AC_OPEN = 0x0202, // Sel
+ HID_USAGE_CONSUMER_AC_CLOSE = 0x0203, // Sel
+ HID_USAGE_CONSUMER_AC_EXIT = 0x0204, // Sel
+ HID_USAGE_CONSUMER_AC_MAXIMIZE = 0x0205, // Sel
+ HID_USAGE_CONSUMER_AC_MINIMIZE = 0x0206, // Sel
+ HID_USAGE_CONSUMER_AC_SAVE = 0x0207, // Sel
+ HID_USAGE_CONSUMER_AC_PRINT = 0x0208, // Sel
+ HID_USAGE_CONSUMER_AC_PROPERTIES = 0x0209, // Sel
+ // 20A-219 Reserved
+ HID_USAGE_CONSUMER_AC_UNDO = 0x021A, // Sel
+ HID_USAGE_CONSUMER_AC_COPY = 0x021B, // Sel
+ HID_USAGE_CONSUMER_AC_CUT = 0x021C, // Sel
+ HID_USAGE_CONSUMER_AC_PASTE = 0x021D, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_ALL = 0x021E, // Sel
+ HID_USAGE_CONSUMER_AC_FIND = 0x021F, // Sel
+ HID_USAGE_CONSUMER_AC_FIND_AND_REPLACE = 0x0220, // Sel
+ HID_USAGE_CONSUMER_AC_SEARCH = 0x0221, // Sel
+ HID_USAGE_CONSUMER_AC_GO_TO = 0x0222, // Sel
+ HID_USAGE_CONSUMER_AC_HOME = 0x0223, // Sel
+ HID_USAGE_CONSUMER_AC_BACK = 0x0224, // Sel
+ HID_USAGE_CONSUMER_AC_FORWARD = 0x0225, // Sel
+ HID_USAGE_CONSUMER_AC_STOP = 0x0226, // Sel
+ HID_USAGE_CONSUMER_AC_REFRESH = 0x0227, // Sel
+ HID_USAGE_CONSUMER_AC_PREVIOUS_LINK = 0x0228, // Sel
+ HID_USAGE_CONSUMER_AC_NEXT_LINK = 0x0229, // Sel
+ HID_USAGE_CONSUMER_AC_BOOKMARKS = 0x022A, // Sel
+ HID_USAGE_CONSUMER_AC_HISTORY = 0x022B, // Sel
+ HID_USAGE_CONSUMER_AC_SUBSCRIPTIONS = 0x022C, // Sel
+ HID_USAGE_CONSUMER_AC_ZOOM_IN = 0x022D, // Sel
+ HID_USAGE_CONSUMER_AC_ZOOM_OUT = 0x022E, // Sel
+ HID_USAGE_CONSUMER_AC_ZOOM = 0x022F, // LC
+ HID_USAGE_CONSUMER_AC_FULL_SCREEN_VIEW = 0x0230, // Sel
+ HID_USAGE_CONSUMER_AC_NORMAL_VIEW = 0x0231, // Sel
+ HID_USAGE_CONSUMER_AC_VIEW_TOGGLE = 0x0232, // Sel
+ HID_USAGE_CONSUMER_AC_SCROLL_UP = 0x0233, // Sel
+ HID_USAGE_CONSUMER_AC_SCROLL_DOWN = 0x0234, // Sel
+ HID_USAGE_CONSUMER_AC_SCROLL = 0x0235, // LC
+ HID_USAGE_CONSUMER_AC_PAN_LEFT = 0x0236, // Sel
+ HID_USAGE_CONSUMER_AC_PAN_RIGHT = 0x0237, // Sel
+ HID_USAGE_CONSUMER_AC_PAN = 0x0238, // LC
+ HID_USAGE_CONSUMER_AC_NEW_WINDOW = 0x0239, // Sel
+ HID_USAGE_CONSUMER_AC_TILE_HORIZONTALLY = 0x023A, // Sel
+ HID_USAGE_CONSUMER_AC_TILE_VERTICALLY = 0x023B, // Sel
+ HID_USAGE_CONSUMER_AC_FORMAT = 0x023C, // Sel
+ HID_USAGE_CONSUMER_AC_EDIT = 0x023D, // Sel
+ HID_USAGE_CONSUMER_AC_BOLD = 0x023E, // Sel
+ HID_USAGE_CONSUMER_AC_ITALICS = 0x023F, // Sel
+ HID_USAGE_CONSUMER_AC_UNDERLINE = 0x0240, // Sel
+ HID_USAGE_CONSUMER_AC_STRIKETHROUGH = 0x0241, // Sel
+ HID_USAGE_CONSUMER_AC_SUBSCRIPT = 0x0242, // Sel
+ HID_USAGE_CONSUMER_AC_SUPERSCRIPT = 0x0243, // Sel
+ HID_USAGE_CONSUMER_AC_ALL_CAPS = 0x0244, // Sel
+ HID_USAGE_CONSUMER_AC_ROTATE = 0x0245, // Sel
+ HID_USAGE_CONSUMER_AC_RESIZE = 0x0246, // Sel
+ HID_USAGE_CONSUMER_AC_FLIP_HORIZONTAL = 0x0247, // Sel
+ HID_USAGE_CONSUMER_AC_FLIP_VERTICAL = 0x0248, // Sel
+ HID_USAGE_CONSUMER_AC_MIRROR_HORIZONTAL = 0x0249, // Sel
+ HID_USAGE_CONSUMER_AC_MIRROR_VERTICAL = 0x024A, // Sel
+ HID_USAGE_CONSUMER_AC_FONT_SELECT = 0x024B, // Sel
+ HID_USAGE_CONSUMER_AC_FONT_COLOR = 0x024C, // Sel
+ HID_USAGE_CONSUMER_AC_FONT_SIZE = 0x024D, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_LEFT = 0x024E, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_CENTER_H = 0x024F, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_RIGHT = 0x0250, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_BLOCK_H = 0x0251, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_TOP = 0x0252, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_CENTER_V = 0x0253, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_BOTTOM = 0x0254, // Sel
+ HID_USAGE_CONSUMER_AC_JUSTIFY_BLOCK_V = 0x0255, // Sel
+ HID_USAGE_CONSUMER_AC_INDENT_DECREASE = 0x0256, // Sel
+ HID_USAGE_CONSUMER_AC_INDENT_INCREASE = 0x0257, // Sel
+ HID_USAGE_CONSUMER_AC_NUMBERED_LIST = 0x0258, // Sel
+ HID_USAGE_CONSUMER_AC_RESTART_NUMBERING = 0x0259, // Sel
+ HID_USAGE_CONSUMER_AC_BULLETED_LIST = 0x025A, // Sel
+ HID_USAGE_CONSUMER_AC_PROMOTE = 0x025B, // Sel
+ HID_USAGE_CONSUMER_AC_DEMOTE = 0x025C, // Sel
+ HID_USAGE_CONSUMER_AC_YES = 0x025D, // Sel
+ HID_USAGE_CONSUMER_AC_NO = 0x025E, // Sel
+ HID_USAGE_CONSUMER_AC_CANCEL = 0x025F, // Sel
+ HID_USAGE_CONSUMER_AC_CATALOG = 0x0260, // Sel
+ HID_USAGE_CONSUMER_AC_BUY_CHECKOUT = 0x0261, // Sel
+ HID_USAGE_CONSUMER_AC_ADD_TO_CART = 0x0262, // Sel
+ HID_USAGE_CONSUMER_AC_EXPAND = 0x0263, // Sel
+ HID_USAGE_CONSUMER_AC_EXPAND_ALL = 0x0264, // Sel
+ HID_USAGE_CONSUMER_AC_COLLAPSE = 0x0265, // Sel
+ HID_USAGE_CONSUMER_AC_COLLAPSE_ALL = 0x0266, // Sel
+ HID_USAGE_CONSUMER_AC_PRINT_PREVIEW = 0x0267, // Sel
+ HID_USAGE_CONSUMER_AC_PASTE_SPECIAL = 0x0268, // Sel
+ HID_USAGE_CONSUMER_AC_INSERT_MODE = 0x0269, // Sel
+ HID_USAGE_CONSUMER_AC_DELETE = 0x026A, // Sel
+ HID_USAGE_CONSUMER_AC_LOCK = 0x026B, // Sel
+ HID_USAGE_CONSUMER_AC_UNLOCK = 0x026C, // Sel
+ HID_USAGE_CONSUMER_AC_PROTECT = 0x026D, // Sel
+ HID_USAGE_CONSUMER_AC_UNPROTECT = 0x026E, // Sel
+ HID_USAGE_CONSUMER_AC_ATTACH_COMMENT = 0x026F, // Sel
+ HID_USAGE_CONSUMER_AC_DELETE_COMMENT = 0x0270, // Sel
+ HID_USAGE_CONSUMER_AC_VIEW_COMMENT = 0x0271, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_WORD = 0x0272, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_SENTENCE = 0x0273, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_PARAGRAPH = 0x0274, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_COLUMN = 0x0275, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_ROW = 0x0276, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_TABLE = 0x0277, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_OBJECT = 0x0278, // Sel
+ HID_USAGE_CONSUMER_AC_REDO_REPEAT = 0x0279, // Sel
+ HID_USAGE_CONSUMER_AC_SORT = 0x027A, // Sel
+ HID_USAGE_CONSUMER_AC_SORT_ASCENDING = 0x027B, // Sel
+ HID_USAGE_CONSUMER_AC_SORT_DESCENDING = 0x027C, // Sel
+ HID_USAGE_CONSUMER_AC_FILTER = 0x027D, // Sel
+ HID_USAGE_CONSUMER_AC_SET_CLOCK = 0x027E, // Sel
+ HID_USAGE_CONSUMER_AC_VIEW_CLOCK = 0x027F, // Sel
+ HID_USAGE_CONSUMER_AC_SELECT_TIME_ZONE = 0x0280, // Sel
+ HID_USAGE_CONSUMER_AC_EDIT_TIME_ZONES = 0x0281, // Sel
+ HID_USAGE_CONSUMER_AC_SET_ALARM = 0x0282, // Sel
+ HID_USAGE_CONSUMER_AC_CLEAR_ALARM = 0x0283, // Sel
+ HID_USAGE_CONSUMER_AC_SNOOZE_ALARM = 0x0284, // Sel
+ HID_USAGE_CONSUMER_AC_RESET_ALARM = 0x0285, // Sel
+ HID_USAGE_CONSUMER_AC_SYNCHRONIZE = 0x0286, // Sel
+ HID_USAGE_CONSUMER_AC_SEND_RECEIVE = 0x0287, // Sel
+ HID_USAGE_CONSUMER_AC_SEND_TO = 0x0288, // Sel
+ HID_USAGE_CONSUMER_AC_REPLY = 0x0289, // Sel
+ HID_USAGE_CONSUMER_AC_REPLY_ALL = 0x028A, // Sel
+ HID_USAGE_CONSUMER_AC_FORWARD_MSG = 0x028B, // Sel
+ HID_USAGE_CONSUMER_AC_SEND = 0x028C, // Sel
+ HID_USAGE_CONSUMER_AC_ATTACH_FILE = 0x028D, // Sel
+ HID_USAGE_CONSUMER_AC_UPLOAD = 0x028E, // Sel
+ HID_USAGE_CONSUMER_AC_DOWNLOAD_SAVE_TARGET_AS = 0x028F, // Sel
+ HID_USAGE_CONSUMER_AC_SET_BORDERS = 0x0290, // Sel
+ HID_USAGE_CONSUMER_AC_INSERT_ROW = 0x0291, // Sel
+ HID_USAGE_CONSUMER_AC_INSERT_COLUMN = 0x0292, // Sel
+ HID_USAGE_CONSUMER_AC_INSERT_FILE = 0x0293, // Sel
+ HID_USAGE_CONSUMER_AC_INSERT_PICTURE = 0x0294, // Sel
+ HID_USAGE_CONSUMER_AC_INSERT_OBJECT = 0x0295, // Sel
+ HID_USAGE_CONSUMER_AC_INSERT_SYMBOL = 0x0296, // Sel
+ HID_USAGE_CONSUMER_AC_SAVE_AND_CLOSE = 0x0297, // Sel
+ HID_USAGE_CONSUMER_AC_RENAME = 0x0298, // Sel
+ HID_USAGE_CONSUMER_AC_MERGE = 0x0299, // Sel
+ HID_USAGE_CONSUMER_AC_SPLIT = 0x029A, // Sel
+ HID_USAGE_CONSUMER_AC_DISRIBUTE_HORIZONTALLY = 0x029B, // Sel
+ HID_USAGE_CONSUMER_AC_DISTRIBUTE_VERTICALLY = 0x029C, // Sel
+ HID_USAGE_CONSUMER_AC_NEXT_KEYBOARD_LAYOUT_SELECT = 0x029D, // Sel
+ HID_USAGE_CONSUMER_AC_NAVIGATION_GUIDANCE = 0x029E, // Sel
+ HID_USAGE_CONSUMER_AC_DESKTOP_SHOW_ALL_WINDOWS = 0x029F, // Sel
+ HID_USAGE_CONSUMER_AC_SOFT_KEY_LEFT = 0x02A0, // Sel
+ HID_USAGE_CONSUMER_AC_SOFT_KEY_RIGHT = 0x02A1, // Sel
+ HID_USAGE_CONSUMER_AC_DESKTOP_SHOW_ALL_APPLICATIONS = 0x02A2, // Sel
+ // 2A3-2AF Reserved
+ HID_USAGE_CONSUMER_AC_IDLE_KEEP_ALIVE = 0x02B0, // Sel
+ // 2B1-2BF Reserved
+ HID_USAGE_CONSUMER_EXTENDED_KEYBOARD_ATTRIBUTES_COLLECTION = 0x02C0, // CL
+ HID_USAGE_CONSUMER_KEYBOARD_FORM_FACTOR = 0x02C1, // SV
+ HID_USAGE_CONSUMER_KEYBOARD_KEY_TYPE = 0x02C2, // SV
+ HID_USAGE_CONSUMER_KEYBOARD_PHYSICAL_LAYOUT = 0x02C3, // SV
+ HID_USAGE_CONSUMER_VENDOR_SPECIFIC_KEYBOARD_PHYSICAL_LAYOUT = 0x02C4, // SV
+ HID_USAGE_CONSUMER_KEYBOARD_IETF_LANGUAGE_TAG_INDEX = 0x02C5, // SV
+ HID_USAGE_CONSUMER_IMPLEMENTED_KEYBOARD_INPUT_ASSIST_CONTROLS = 0x02C6, // SV
+ HID_USAGE_CONSUMER_KEYBOARD_INPUT_ASSIST_PREVIOUS = 0x02C7, // Sel
+ HID_USAGE_CONSUMER_KEYBOARD_INPUT_ASSIST_NEXT = 0x02C8, // Sel
+ HID_USAGE_CONSUMER_KEYBOARD_INPUT_ASSIST_PREVIOUS_GROUP = 0x02C9, // Sel
+ HID_USAGE_CONSUMER_KEYBOARD_INPUT_ASSIST_NEXT_GROUP = 0x02CA, // Sel
+ HID_USAGE_CONSUMER_KEYBOARD_INPUT_ASSIST_ACCEPT = 0x02CB, // Sel
+ HID_USAGE_CONSUMER_KEYBOARD_INPUT_ASSIST_CANCEL = 0x02CC, // Sel
+ // 2CD-2CF Reserved
+ HID_USAGE_CONSUMER_PRIVACY_SCREEN_TOGGLE = 0x02D0, // OOC
+ HID_USAGE_CONSUMER_PRIVACY_SCREEN_LEVEL_DECREMENT = 0x02D1, // RTC
+ HID_USAGE_CONSUMER_PRIVACY_SCREEN_LEVEL_INCREMENT = 0x02D2, // RTC
+ HID_USAGE_CONSUMER_PRIVACY_SCREEN_LEVEL_MINIMUM = 0x02D3, // OSC
+ HID_USAGE_CONSUMER_PRIVACY_SCREEN_LEVEL_MAXIMUM = 0x02D4, // OSC
+ // 2D5-4FF Reserved
+ HID_USAGE_CONSUMER_CONTACT_EDITED = 0x0500, // OOC
+ HID_USAGE_CONSUMER_CONTACT_ADDED = 0x0501, // OOC
+ HID_USAGE_CONSUMER_CONTACT_RECORD_ACTIVE = 0x0502, // OOC
+ HID_USAGE_CONSUMER_CONTACT_INDEX = 0x0503, // DV
+ HID_USAGE_CONSUMER_CONTACT_NICKNAME = 0x0504, // DV
+ HID_USAGE_CONSUMER_CONTACT_FIRST_NAME = 0x0505, // DV
+ HID_USAGE_CONSUMER_CONTACT_LAST_NAME = 0x0506, // DV
+ HID_USAGE_CONSUMER_CONTACT_FULL_NAME = 0x0507, // DV
+ HID_USAGE_CONSUMER_CONTACT_PHONE_NUMBER_PERSONAL = 0x0508, // DV
+ HID_USAGE_CONSUMER_CONTACT_PHONE_NUMBER_BUSINESS = 0x0509, // DV
+ HID_USAGE_CONSUMER_CONTACT_PHONE_NUMBER_MOBILE = 0x050A, // DV
+ HID_USAGE_CONSUMER_CONTACT_PHONE_NUMBER_PAGER = 0x050B, // DV
+ HID_USAGE_CONSUMER_CONTACT_PHONE_NUMBER_FAX = 0x050C, // DV
+ HID_USAGE_CONSUMER_CONTACT_PHONE_NUMBER_OTHER = 0x050D, // DV
+ HID_USAGE_CONSUMER_CONTACT_EMAIL_PERSONAL = 0x050E, // DV
+ HID_USAGE_CONSUMER_CONTACT_EMAIL_BUSINESS = 0x050F, // DV
+ HID_USAGE_CONSUMER_CONTACT_EMAIL_OTHER = 0x0510, // DV
+ HID_USAGE_CONSUMER_CONTACT_EMAIL_MAIN = 0x0511, // DV
+ HID_USAGE_CONSUMER_CONTACT_SPEED_DIAL_NUMBER = 0x0512, // DV
+ HID_USAGE_CONSUMER_CONTACT_STATUS_FLAG = 0x0513, // DV
+ HID_USAGE_CONSUMER_CONTACT_MISC = 0x0514, // DV
+ HID_USAGE_CONSUMER_KEYBOARD_BRIGHTNESS_NEXT = 0x0515, // OSC
+ HID_USAGE_CONSUMER_KEYBOARD_BRIGHTNESS_PREVIOUS = 0x0516, // OSC
+ HID_USAGE_CONSUMER_KEYBOARD_BACKLIGHT_LEVEL_SUGGESTION = 0x0517, // SV
+ // 518-FFFF Reserved
+ // For Backwards compatibility to prevent current builds from breaking
+ HID_USAGE_CONSUMER_BRIGHTNESS_INCREMENT = HID_USAGE_CONSUMER_DISPLAY_BRIGHTNESS_INCREMENT, // RTC
+ HID_USAGE_CONSUMER_BRIGHTNESS_DECREMENT = HID_USAGE_CONSUMER_DISPLAY_BRIGHTNESS_DECREMENT, // RTC
};
/// HID Usage Table: Digitizer Page (0x0D)
@@ -1371,6 +1935,7 @@ enum {
HID_USAGE_DIGITIZER_SURFACE_SWITCH = 0x57, // DF
HID_USAGE_DIGITIZER_BUTTON_SWITCH = 0x58, // DF
HID_USAGE_DIGITIZER_PAD_TYPE = 0x59, // SF
+ HID_USAGE_DIGITIZER_SECONDARY_BARREL_SWITCH = 0x5A, // MC
HID_USAGE_DIGITIZER_TRANSDUCER_SERIAL_NUMBER = 0x5B, // SV
HID_USAGE_DIGITIZER_PREFERRED_COLOR = 0x5C, // DV
HID_USAGE_DIGITIZER_PREFERRED_COLOR_LOCKED = 0x5D, // MC
@@ -1431,151 +1996,500 @@ enum {
// Reserved (0xB1 - 0xFFFF)
};
+/// HID Usage Table: Haptics Page (0x0E)
+enum{
+ HID_USAGE_HAPTICS_SIMPLE_HAPTIC_CONTROLLER = 0x0001, // CA/CL
+ // Reserved (0x0002 - 0x000F)
+ HID_USAGE_HAPTICS_WAVEFORM_LIST = 0x0010, // NAry
+ HID_USAGE_HAPTICS_DURATION_LIST = 0x0011, // NAry
+ // Reserved (0x0012 - 0x001F)
+ HID_USAGE_HAPTICS_AUTO_TRIGGER = 0x0020, // DV
+ HID_USAGE_HAPTICS_MANUAL_TRIGGER = 0x0021, // DV
+ HID_USAGE_HAPTICS_AUTO_TRIGGER_ASSOCIATED_CONTROL = 0x0022, // SV
+ HID_USAGE_HAPTICS_INTENSITY = 0x0023, // DV
+ HID_USAGE_HAPTICS_REPEAT_COUNT = 0x0024, // DV
+ HID_USAGE_HAPTICS_RETRIGGER_PERIOD = 0x0025, // DV
+ HID_USAGE_HAPTICS_WAVEFORM_VENDOR_PAGE = 0x0026, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_VENDOR_ID = 0x0027, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME = 0x0028, // SV
+ // Reserved (0x0029 - 0x1000)
+ HID_USAGE_HAPTICS_WAVEFORM_NONE = 0x1001, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_STOP = 0x1002, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_CLICK = 0x1003, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_BUZZ_CONTINUOUS = 0x1004, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_RUMBLE_CONTINUOUS = 0x1005, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_PRESS = 0x1006, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_RELEASE = 0x1007, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_HOVER = 0x1008, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_SUCCESS = 0x1009, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_ERROR = 0x100A, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_INK_CONTINUOUS = 0x100B, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_PENCIL_CONTINUOUS = 0x100C, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_MARKER_CONTINUOUS = 0x100D, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_CHISEL_MARKER_CONTINUOUS = 0x100E, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_BRUSH_CONTINUOUS = 0x100F, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_ERASER_CONTINUOUS = 0x1010, // SV
+ HID_USAGE_HAPTICS_WAVEFORM_SPARKLE_CONTINUOUS = 0x1011, // SV
+ // Reserved (0x1012 - 0xFFFF)
+};
+
/// HID Usage Table: Physical Input Device Page (0x0F)
enum {
HID_USAGE_PID_UNDEFINED = 0x00,
- HID_USAGE_PID_PHYSICAL_INPUT_DEVICE = 0x01,
- HID_USAGE_PID_NORMAL = 0x20,
- HID_USAGE_PID_SET_EFFECT_REPORT = 0x21,
- HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_INDEX = 0x22,
- HID_USAGE_PID_PARAMETER_BLOCK_OFFSET = 0x23,
- HID_USAGE_PID_ROM_FLAG = 0x24,
- HID_USAGE_PID_EFFECT_TYPE = 0x25,
- HID_USAGE_PID_ET_CONSTANTFORCE = 0x26,
- HID_USAGE_PID_ET_RAMP = 0x27,
- HID_USAGE_PID_ET_CUSTOMFORCE = 0x28,
- HID_USAGE_PID_ET_SQUARE = 0x30,
- HID_USAGE_PID_ET_SINE = 0x31,
- HID_USAGE_PID_ET_TRIANGLE = 0x32,
- HID_USAGE_PID_ET_SAWTOOTH_UP = 0x33,
- HID_USAGE_PID_ET_SAWTOOTH_DOWN = 0x34,
- HID_USAGE_PID_ET_SPRING = 0x40,
- HID_USAGE_PID_ET_DAMPER = 0x41,
- HID_USAGE_PID_ET_INERTIA = 0x42,
- HID_USAGE_PID_ET_FRICTION = 0x43,
- HID_USAGE_PID_DURATION = 0x50,
- HID_USAGE_PID_SAMPLE_PERIOD = 0x51,
- HID_USAGE_PID_GAIN = 0x52,
- HID_USAGE_PID_TRIGGER_BUTTON = 0x53,
- HID_USAGE_PID_TRIGGER_REPEAT_INTERVAL = 0x54,
- HID_USAGE_PID_AXES_ENABLE = 0x55,
- HID_USAGE_PID_DIRECTION_ENABLE = 0x56,
- HID_USAGE_PID_DIRECTION = 0x57,
- HID_USAGE_PID_TYPE_SPECIFIC_BLOCK_OFFSET = 0x58,
- HID_USAGE_PID_BLOCK_TYPE = 0x59,
- HID_USAGE_PID_SET_ENVELOPE_REPORT = 0x5a,
- HID_USAGE_PID_ATTACK_LEVEL = 0x5b,
- HID_USAGE_PID_ATTACK_TIME = 0x5c,
- HID_USAGE_PID_FADE_LEVEL = 0x5d,
- HID_USAGE_PID_FADE_TIME = 0x5e,
- HID_USAGE_PID_SET_CONDITION_REPORT = 0x5f,
- HID_USAGE_PID_CENTERPOINT_OFFSET = 0x60,
- HID_USAGE_PID_POSITIVE_COEFFICIENT = 0x61,
- HID_USAGE_PID_NEGATIVE_COEFFICIENT = 0x62,
- HID_USAGE_PID_POSITIVE_SATURATION = 0x63,
- HID_USAGE_PID_NEGATIVE_SATURATION = 0x64,
- HID_USAGE_PID_DEAD_BAND = 0x65,
- HID_USAGE_PID_DOWNLOAD_FORCE_SAMPLE = 0x66,
- HID_USAGE_PID_ISOCH_CUSTOMFORCE_ENABLE = 0x67,
- HID_USAGE_PID_CUSTOMFORCE_DATA_REPORT = 0x68,
- HID_USAGE_PID_CUSTOMFORCE_DATA = 0x69,
- HID_USAGE_PID_CUSTOMFORCE_VENDOR_DEFINED_DATA = 0x6a,
- HID_USAGE_PID_SET_CUSTOMFORCE_REPORT = 0x6b,
- HID_USAGE_PID_CUSTOMFORCE_DATA_OFFSET = 0x6c,
- HID_USAGE_PID_SAMPLE_COUNT = 0x6d,
- HID_USAGE_PID_SET_PERIODIC_REPORT = 0x6e,
- HID_USAGE_PID_OFFSET = 0x6f,
- HID_USAGE_PID_MAGNITUDE = 0x70,
- HID_USAGE_PID_PHASE = 0x71,
- HID_USAGE_PID_PERIOD = 0x72,
- HID_USAGE_PID_SET_CONSTANTFORCE_REPORT = 0x73,
- HID_USAGE_PID_SET_RAMPFORCE_REPORT = 0x74,
- HID_USAGE_PID_RAMP_START = 0x75,
- HID_USAGE_PID_RAMP_END = 0x76,
- HID_USAGE_PID_EFFECT_OPERATION_REPORT = 0x77,
- HID_USAGE_PID_EFFECT_OPERATION = 0x78,
- HID_USAGE_PID_OP_EFFECT_START = 0x79,
- HID_USAGE_PID_OP_EFFECT_START_SOLO = 0x7a,
- HID_USAGE_PID_OP_EFFECT_STOP = 0x7b,
- HID_USAGE_PID_LOOP_COUNT = 0x7c,
- HID_USAGE_PID_DEVICE_GAIN_REPORT = 0x7d,
- HID_USAGE_PID_DEVICE_GAIN = 0x7e,
- HID_USAGE_PID_PARAMETER_BLOCK_POOLS_REPORT = 0x7f,
- HID_USAGE_PID_RAM_POOL_SIZE = 0x80,
- HID_USAGE_PID_ROM_POOL_SIZE = 0x81,
- HID_USAGE_PID_ROM_EFFECT_BLOCK_COUNT = 0x82,
- HID_USAGE_PID_SIMULTANEOUS_EFFECTS_MAX = 0x83,
- HID_USAGE_PID_POOL_ALIGNMENT = 0x84,
- HID_USAGE_PID_PARAMETER_BLOCK_MOVE_REPORT = 0x85,
- HID_USAGE_PID_MOVE_SOURCE = 0x86,
- HID_USAGE_PID_MOVE_DESTINATION = 0x87,
- HID_USAGE_PID_MOVE_LENGTH = 0x88,
- HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_LOAD_REPORT = 0x89,
- HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_LOAD_STATUS = 0x8b,
- HID_USAGE_PID_BLOCK_LOAD_SUCCESS = 0x8c,
- HID_USAGE_PID_BLOCK_LOAD_FULL = 0x8d,
- HID_USAGE_PID_BLOCK_LOAD_ERROR = 0x8e,
- HID_USAGE_PID_BLOCK_HANDLE = 0x8f,
- HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_FREE_REPORT = 0x90,
- HID_USAGE_PID_TYPE_SPECIFIC_BLOCK_HANDLE = 0x91,
- HID_USAGE_PID_PID_STATE_REPORT = 0x92,
- HID_USAGE_PID_EFFECT_PLAYING = 0x94,
- HID_USAGE_PID_PID_DEVICE_CONTROL_REPORT = 0x95,
- HID_USAGE_PID_PID_DEVICE_CONTROL = 0x96,
- HID_USAGE_PID_DC_ENABLE_ACTUATORS = 0x97,
- HID_USAGE_PID_DC_DISABLE_ACTUATORS = 0x98,
- HID_USAGE_PID_DC_STOP_ALL_EFFECTS = 0x99,
- HID_USAGE_PID_DC_RESET = 0x9a,
- HID_USAGE_PID_DC_PAUSE = 0x9b,
- HID_USAGE_PID_DC_CONTINUE = 0x9c,
- HID_USAGE_PID_DEVICE_PAUSED = 0x9f,
- HID_USAGE_PID_ACTUATORS_ENABLED = 0xa0,
- HID_USAGE_PID_SAFETY_SWITCH = 0xa4,
- HID_USAGE_PID_ACTUATOR_OVERRIDE_SWITCH = 0xa5,
- HID_USAGE_PID_ACTUATOR_POWER = 0xa6,
- HID_USAGE_PID_START_DELAY = 0xa7,
- HID_USAGE_PID_PARAMETER_BLOCK_SIZE = 0xa8,
- HID_USAGE_PID_DEVICEMANAGED_POOL = 0xa9,
- HID_USAGE_PID_SHARED_PARAMETER_BLOCKS = 0xaa,
- HID_USAGE_PID_CREATE_NEW_EFFECT_PARAMETER_BLOCK_REPORT = 0xab,
- HID_USAGE_PID_RAM_POOL_AVAILABLE = 0xac,
+ HID_USAGE_PID_PHYSICAL_INPUT_DEVICE = 0x01, // CA
+ // Reserved (0x02 - 0x1F)
+ HID_USAGE_PID_NORMAL = 0x20, // DV
+ HID_USAGE_PID_SET_EFFECT_REPORT = 0x21, // CL
+ HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_INDEX = 0x22, // DV
+ HID_USAGE_PID_PARAMETER_BLOCK_OFFSET = 0x23, // DV
+ HID_USAGE_PID_ROM_FLAG = 0x24, // DF
+ HID_USAGE_PID_EFFECT_TYPE = 0x25, // NAry
+ HID_USAGE_PID_ET_CONSTANTFORCE = 0x26, // Sel
+ HID_USAGE_PID_ET_RAMP = 0x27, // Sel
+ HID_USAGE_PID_ET_CUSTOMFORCE = 0x28, // Sel
+ // Reserved (0x29 - 0x2F)
+ HID_USAGE_PID_ET_SQUARE = 0x30, // Sel
+ HID_USAGE_PID_ET_SINE = 0x31, // Sel
+ HID_USAGE_PID_ET_TRIANGLE = 0x32, // Sel
+ HID_USAGE_PID_ET_SAWTOOTH_UP = 0x33, // Sel
+ HID_USAGE_PID_ET_SAWTOOTH_DOWN = 0x34, // Sel
+ // Reserved (0x35 - 0x3F)
+ HID_USAGE_PID_ET_SPRING = 0x40, // Sel
+ HID_USAGE_PID_ET_DAMPER = 0x41, // Sel
+ HID_USAGE_PID_ET_INERTIA = 0x42, // Sel
+ HID_USAGE_PID_ET_FRICTION = 0x43, // Sel
+ // Reserved (0x44 - 0x4F)
+ HID_USAGE_PID_DURATION = 0x50, // DV
+ HID_USAGE_PID_SAMPLE_PERIOD = 0x51, // DV
+ HID_USAGE_PID_GAIN = 0x52, // DV
+ HID_USAGE_PID_TRIGGER_BUTTON = 0x53, // DV
+ HID_USAGE_PID_TRIGGER_REPEAT_INTERVAL = 0x54, // DV
+ HID_USAGE_PID_AXES_ENABLE = 0x55, // US
+ HID_USAGE_PID_DIRECTION_ENABLE = 0x56, // DF
+ HID_USAGE_PID_DIRECTION = 0x57, // CL
+ HID_USAGE_PID_TYPE_SPECIFIC_BLOCK_OFFSET = 0x58, // CL
+ HID_USAGE_PID_BLOCK_TYPE = 0x59, // NAry
+ HID_USAGE_PID_SET_ENVELOPE_REPORT = 0x5A, // CL/SV
+ HID_USAGE_PID_ATTACK_LEVEL = 0x5B, // DV
+ HID_USAGE_PID_ATTACK_TIME = 0x5C, // DV
+ HID_USAGE_PID_FADE_LEVEL = 0x5D, // DV
+ HID_USAGE_PID_FADE_TIME = 0x5E, // DV
+ HID_USAGE_PID_SET_CONDITION_REPORT = 0x5F, // CL/SV
+ HID_USAGE_PID_CENTERPOINT_OFFSET = 0x60, // DV
+ HID_USAGE_PID_POSITIVE_COEFFICIENT = 0x61, // DV
+ HID_USAGE_PID_NEGATIVE_COEFFICIENT = 0x62, // DV
+ HID_USAGE_PID_POSITIVE_SATURATION = 0x63, // DV
+ HID_USAGE_PID_NEGATIVE_SATURATION = 0x64, // DV
+ HID_USAGE_PID_DEAD_BAND = 0x65, // DV
+ HID_USAGE_PID_DOWNLOAD_FORCE_SAMPLE = 0x66, // CL
+ HID_USAGE_PID_ISOCH_CUSTOMFORCE_ENABLE = 0x67, // DF
+ HID_USAGE_PID_CUSTOMFORCE_DATA_REPORT = 0x68, // CL
+ HID_USAGE_PID_CUSTOMFORCE_DATA = 0x69, // DV
+ HID_USAGE_PID_CUSTOMFORCE_VENDOR_DEFINED_DATA = 0x6A, // DV
+ HID_USAGE_PID_SET_CUSTOMFORCE_REPORT = 0x6B, // CL/SV
+ HID_USAGE_PID_CUSTOMFORCE_DATA_OFFSET = 0x6C, // DV
+ HID_USAGE_PID_SAMPLE_COUNT = 0x6D, // DV
+ HID_USAGE_PID_SET_PERIODIC_REPORT = 0x6E, // CL/SV
+ HID_USAGE_PID_OFFSET = 0x6F, // DV
+ HID_USAGE_PID_MAGNITUDE = 0x70, // DV
+ HID_USAGE_PID_PHASE = 0x71, // DV
+ HID_USAGE_PID_PERIOD = 0x72, // DV
+ HID_USAGE_PID_SET_CONSTANTFORCE_REPORT = 0x73, // CL/SV
+ HID_USAGE_PID_SET_RAMPFORCE_REPORT = 0x74, // CL/SV
+ HID_USAGE_PID_RAMP_START = 0x75, // DV
+ HID_USAGE_PID_RAMP_END = 0x76, // DV
+ HID_USAGE_PID_EFFECT_OPERATION_REPORT = 0x77, // CL
+ HID_USAGE_PID_EFFECT_OPERATION = 0x78, // NAry
+ HID_USAGE_PID_OP_EFFECT_START = 0x79, // Sel
+ HID_USAGE_PID_OP_EFFECT_START_SOLO = 0x7A, // Sel
+ HID_USAGE_PID_OP_EFFECT_STOP = 0x7B, // Sel
+ HID_USAGE_PID_LOOP_COUNT = 0x7C, // DV
+ HID_USAGE_PID_DEVICE_GAIN_REPORT = 0x7D, // CL
+ HID_USAGE_PID_DEVICE_GAIN = 0x7E, // DV
+ HID_USAGE_PID_PARAMETER_BLOCK_POOLS_REPORT = 0x7F, // CL
+ HID_USAGE_PID_RAM_POOL_SIZE = 0x80, // DV
+ HID_USAGE_PID_ROM_POOL_SIZE = 0x81, // SV
+ HID_USAGE_PID_ROM_EFFECT_BLOCK_COUNT = 0x82, // SV
+ HID_USAGE_PID_SIMULTANEOUS_EFFECTS_MAX = 0x83, // SV
+ HID_USAGE_PID_POOL_ALIGNMENT = 0x84, // SV
+ HID_USAGE_PID_PARAMETER_BLOCK_MOVE_REPORT = 0x85, // CL
+ HID_USAGE_PID_MOVE_SOURCE = 0x86, // DV
+ HID_USAGE_PID_MOVE_DESTINATION = 0x87, // DV
+ HID_USAGE_PID_MOVE_LENGTH = 0x88, // DV
+ HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_LOAD_REPORT = 0x89, // CL
+ // Reserved (0x8A)
+ HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_LOAD_STATUS = 0x8B, // NAry
+ HID_USAGE_PID_BLOCK_LOAD_SUCCESS = 0x8C, // Sel
+ HID_USAGE_PID_BLOCK_LOAD_FULL = 0x8D, // Sel
+ HID_USAGE_PID_BLOCK_LOAD_ERROR = 0x8E, // Sel
+ HID_USAGE_PID_BLOCK_HANDLE = 0x8F, // DV
+ HID_USAGE_PID_EFFECT_PARAMETER_BLOCK_FREE_REPORT = 0x90, // CL
+ HID_USAGE_PID_TYPE_SPECIFIC_BLOCK_HANDLE = 0x91, // CL
+ HID_USAGE_PID_PID_STATE_REPORT = 0x92, // CL
+ // Reserved (0x93)
+ HID_USAGE_PID_EFFECT_PLAYING = 0x94, // DF
+ HID_USAGE_PID_PID_DEVICE_CONTROL_REPORT = 0x95, // CL
+ HID_USAGE_PID_PID_DEVICE_CONTROL = 0x96, // NAry
+ HID_USAGE_PID_DC_ENABLE_ACTUATORS = 0x97, // Sel
+ HID_USAGE_PID_DC_DISABLE_ACTUATORS = 0x98, // Sel
+ HID_USAGE_PID_DC_STOP_ALL_EFFECTS = 0x99, // Sel
+ HID_USAGE_PID_DC_RESET = 0x9A, // Sel
+ HID_USAGE_PID_DC_PAUSE = 0x9B, // Sel
+ HID_USAGE_PID_DC_CONTINUE = 0x9C, // Sel
+ // Reserved (0x9D - 0x9E)
+ HID_USAGE_PID_DEVICE_PAUSED = 0x9F, // DF
+ HID_USAGE_PID_ACTUATORS_ENABLED = 0xA0, // DF
+ // Reserved (0xA1 - 0xA3)
+ HID_USAGE_PID_SAFETY_SWITCH = 0xA4, // DF
+ HID_USAGE_PID_ACTUATOR_OVERRIDE_SWITCH = 0xA5, // DF
+ HID_USAGE_PID_ACTUATOR_POWER = 0xA6, // OOC
+ HID_USAGE_PID_START_DELAY = 0xA7, // DV
+ HID_USAGE_PID_PARAMETER_BLOCK_SIZE = 0xA8, // CL
+ HID_USAGE_PID_DEVICEMANAGED_POOL = 0xA9, // SF
+ HID_USAGE_PID_SHARED_PARAMETER_BLOCKS = 0xAA, // SF
+ HID_USAGE_PID_CREATE_NEW_EFFECT_PARAMETER_BLOCK_REPORT = 0xAB, // CL
+ HID_USAGE_PID_RAM_POOL_AVAILABLE = 0xAC, // DV
+ // Reserved (0xAD - 0xFFFF)
+};
+
+/// HID Usage Table: Unicode Page (0x10)
+/// Intentionally skipped
+
+/// HID Usage Table: SoC Page (0x11)
+enum {
+ HID_USAGE_SOC_SOC_CONTROL = 0x01, // CA
+ HID_USAGE_SOC_FIRMWARE_TRANSFER = 0x02, // CL
+ HID_USAGE_SOC_FIRMWARE_FILE_ID = 0x03, // DV
+ HID_USAGE_SOC_FILE_OFFSET_IN_BYTES = 0x04, // DV
+ HID_USAGE_SOC_FILE_TRANSFER_SIZE_MAX_IN_BYTES = 0x05, // DV
+ HID_USAGE_SOC_FILE_PAYLOAD = 0x06, // DV
+ HID_USAGE_SOC_FILE_PAYLOAD_SIZE_IN_BYTES = 0x07, // DV
+ HID_USAGE_SOC_FILE_PAYLOAD_CONTAINS_LAST_BYTES = 0x08, // DF
+ HID_USAGE_SOC_FILE_TRANSFER_STOP = 0x09, // DF
+ HID_USAGE_SOC_FILE_TRANSFER_TILL_END = 0x0A // DF
+ // Reserved (0x0B - 0xFFFF)
+};
+
+/// HID Usage Table: Eye and Head Trackers Page (0x12)
+enum {
+ HID_USAGE_EYE_AND_HEAD_TRACKER_EYE_TRACKER = 0x0001, // CA
+ HID_USAGE_EYE_AND_HEAD_TRACKER_HEAD_TRACKER = 0x0002, // CA
+ // Reserved (0x0003 - 0x000F)
+ HID_USAGE_EYE_AND_HEAD_TRACKER_TRACKING_DATA = 0x0010, // CP
+ HID_USAGE_EYE_AND_HEAD_TRACKER_CAPABILITIES = 0x0011, // CL
+ HID_USAGE_EYE_AND_HEAD_TRACKER_CONFIGURATION = 0x0012, // CL
+ HID_USAGE_EYE_AND_HEAD_TRACKER_STATUS = 0x0013, // CL
+ HID_USAGE_EYE_AND_HEAD_TRACKER_CONTROL = 0x0014, // CL
+ // Reserved (0x0015 - 0x001F)
+ HID_USAGE_EYE_AND_HEAD_TRACKER_SENSOR_TIMESTAMP = 0x0020, // DV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_POSITION_X = 0x0021, // DV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_POSITION_Y = 0x0022, // DV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_POSITION_Z = 0x0023, // DV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_GAZE_POINT = 0x0024, // CP
+ HID_USAGE_EYE_AND_HEAD_TRACKER_LEFT_EYE_POSITION = 0x0025, // CP
+ HID_USAGE_EYE_AND_HEAD_TRACKER_RIGHT_EYE_POSITION = 0x0026, // CP
+ HID_USAGE_EYE_AND_HEAD_TRACKER_HEAD_POSITION = 0x0027, // CP
+ HID_USAGE_EYE_AND_HEAD_TRACKER_HEAD_DIRECTION_POINT = 0x0028, // CP
+ HID_USAGE_EYE_AND_HEAD_TRACKER_ROTATION_ABOUT_X_AXIS = 0x0029, // DV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_ROTATION_ABOUT_Y_AXIS = 0x002A, // DV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_ROTATION_ABOUT_Z_AXIS = 0x002B, // DV
+ // Reserved (0x002C - 0x00FF)
+ HID_USAGE_EYE_AND_HEAD_TRACKER_TRACKER_QUALITY = 0x0100, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_MINIMUM_TRACKING_DISTANCE = 0x0101, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_OPTIMUM_TRACKING_DISTANCE = 0x0102, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_MAXIMUM_TRACKING_DISTANCE = 0x0103, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_MAXIMUM_SCREEN_PLANE_WIDTH = 0x0104, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_MAXIMUM_SCREEN_PLANE_HEIGHT = 0x0105, // SV
+ // Reserved (0x0106 - 0x01FF)
+ HID_USAGE_EYE_AND_HEAD_TRACKER_DISPLAY_MANUFACTURER_ID = 0x0200, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_DISPLAY_PRODUCT_ID = 0x0201, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_DISPLAY_SERIAL_NUMBER = 0x0202, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_DISPLAY_MANUFACTURER_DATE = 0x0203, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_CALIBRATED_SCREEN_WIDTH = 0x0204, // SV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_CALIBRATED_SCREEN_HEIGHT = 0x0205, // SV
+ // Reserved (0x0206 - 0x02FF)
+ HID_USAGE_EYE_AND_HEAD_TRACKER_SAMPLING_FREQUENCY = 0x0300, // DV
+ HID_USAGE_EYE_AND_HEAD_TRACKER_CONFIGURATION_STATUS = 0x0301, // DV
+ // Reserved (0x0302 - 0x03FF)
+ HID_USAGE_EYE_AND_HEAD_TRACKER_DEVICE_MODE_REQUEST = 0x0400, // DV
+ // Reserved (0x0401 - 0xFFFF)
+};
+
+/// HID Usage Table - Auxiliary Display Page (0x14)
+enum {
+ HID_USAGE_AUX_DISPLAY_ALPHANUMERIC_DISPLAY = 0x01, // CA
+ HID_USAGE_AUX_DISPLAY_AUXILIARY_DISPLAY = 0x02, // CA
+ // Reserved (0x03 - 0x1F)
+ HID_USAGE_AUX_DISPLAY_DISPLAY_ATTRIBUTES_REPORT = 0x20, // CL
+ HID_USAGE_AUX_DISPLAY_ASCII_CHARACTER_SET = 0x21, // SF
+ HID_USAGE_AUX_DISPLAY_DATA_READ_BACK = 0x22, // SF
+ HID_USAGE_AUX_DISPLAY_FONT_READ_BACK = 0x23, // SF
+ HID_USAGE_AUX_DISPLAY_DISPLAY_CONTROL_REPORT = 0x24, // CL
+ HID_USAGE_AUX_DISPLAY_CLEAR_DISPLAY = 0x25, // DF
+ HID_USAGE_AUX_DISPLAY_DISPLAY_ENABLE = 0x26, // DF
+ HID_USAGE_AUX_DISPLAY_SCREEN_SAVER_DELAY = 0x27, // SV/DV
+ HID_USAGE_AUX_DISPLAY_SCREEN_SAVER_ENABLE = 0x28, // DF
+ HID_USAGE_AUX_DISPLAY_VERTICAL_SCROLL = 0x29, // SF/DF
+ HID_USAGE_AUX_DISPLAY_HORIZONTAL_SCROLL = 0x2A, // SF/DF
+ HID_USAGE_AUX_DISPLAY_CHARACTER_REPORT = 0x2B, // CL
+ HID_USAGE_AUX_DISPLAY_DISPLAY_DATA = 0x2C, // DV
+ HID_USAGE_AUX_DISPLAY_DISPLAY_STATUS = 0x2D, // CL
+ HID_USAGE_AUX_DISPLAY_STAT_NOT_READY = 0x2E, // Sel
+ HID_USAGE_AUX_DISPLAY_STAT_READY = 0x2F, // Sel
+ HID_USAGE_AUX_DISPLAY_ERR_NOT_A_LOADABLE_CHARACTER = 0x30, // Sel
+ HID_USAGE_AUX_DISPLAY_ERR_FONT_DATA_CANNOT_BE_READ = 0x31, // Sel
+ HID_USAGE_AUX_DISPLAY_CURSOR_POSITION_REPORT = 0x32, // Sel
+ HID_USAGE_AUX_DISPLAY_ROW = 0x33, // DV
+ HID_USAGE_AUX_DISPLAY_COLUMN = 0x34, // DV
+ HID_USAGE_AUX_DISPLAY_ROWS = 0x35, // SV
+ HID_USAGE_AUX_DISPLAY_COLUMNS = 0x36, // SV
+ HID_USAGE_AUX_DISPLAY_CURSOR_PIXEL_POSITIONING = 0x37, // SF
+ HID_USAGE_AUX_DISPLAY_CURSOR_MODE = 0x38, // DF
+ HID_USAGE_AUX_DISPLAY_CURSOR_ENABLE = 0x39, // DF
+ HID_USAGE_AUX_DISPLAY_CURSOR_BLINK = 0x3A, // DF
+ HID_USAGE_AUX_DISPLAY_FONT_REPORT = 0x3B, // CL
+ HID_USAGE_AUX_DISPLAY_FONT_DATA = 0x3C, // Buffered Bytes
+ HID_USAGE_AUX_DISPLAY_CHARACTER_WIDTH = 0x3D, // SV
+ HID_USAGE_AUX_DISPLAY_CHARACTER_HEIGHT = 0x3E, // SV
+ HID_USAGE_AUX_DISPLAY_CHARACTER_SPACING_HORIZONTAL = 0x3F, // SV
+ HID_USAGE_AUX_DISPLAY_CHARACTER_SPACING_VERTICAL = 0x40, // SV
+ HID_USAGE_AUX_DISPLAY_UNICODE_CHARACTER_SET = 0x41, // SF
+ HID_USAGE_AUX_DISPLAY_FONT_7_SEGMENT = 0x42, // SF
+ HID_USAGE_AUX_DISPLAY_7_SEGMENT_DIRECT_MAP = 0x43, // SF
+ HID_USAGE_AUX_DISPLAY_FONT_14_SEGMENT = 0x44, // SF
+ HID_USAGE_AUX_DISPLAY_14_SEGMENT_DIRECT_MAP = 0x45, // SF
+ HID_USAGE_AUX_DISPLAY_DISPLAY_BRIGHTNESS = 0x46, // DV
+ HID_USAGE_AUX_DISPLAY_DISPLAY_CONTRAST = 0x47, // DV
+ HID_USAGE_AUX_DISPLAY_CHARACTER_ATTRIBUTE = 0x48, // CL
+ HID_USAGE_AUX_DISPLAY_ATTRIBUTE_READBACK = 0x49, // SF
+ HID_USAGE_AUX_DISPLAY_ATTRIBUTE_DATA = 0x4A, // DV
+ HID_USAGE_AUX_DISPLAY_CHAR_ATTR_ENHANCE = 0x4B, // OOC
+ HID_USAGE_AUX_DISPLAY_CHAR_ATTR_UNDERLINE = 0x4C, // OOC
+ HID_USAGE_AUX_DISPLAY_CHAR_ATTR_BLINK = 0x4D, // OOC
+ // Reserved (0x4E - 0x7F)
+ HID_USAGE_AUX_DISPLAY_BITMAP_SIZE_X = 0x80, // SV
+ HID_USAGE_AUX_DISPLAY_BITMAP_SIZE_Y = 0x81, // SV
+ HID_USAGE_AUX_DISPLAY_MAX_BLIT_SIZE = 0x82, // SV
+ HID_USAGE_AUX_DISPLAY_BIT_DEPTH_FORMAT = 0x83, // SV
+ HID_USAGE_AUX_DISPLAY_DISPLAY_ORIENTATION = 0x84, // DV
+ HID_USAGE_AUX_DISPLAY_PALETTE_REPORT = 0x85, // CL
+ HID_USAGE_AUX_DISPLAY_PALETTE_DATA_SIZE = 0x86, // SV
+ HID_USAGE_AUX_DISPLAY_PALETTE_DATA_OFFSET = 0x87, // SV
+ HID_USAGE_AUX_DISPLAY_PALETTE_DATA = 0x88, // Buffered Bytes
+ // Reserved (0x89)
+ HID_USAGE_AUX_DISPLAY_BLIT_REPORT = 0x8A, // CL
+ HID_USAGE_AUX_DISPLAY_BLIT_RECTANGLE_X1 = 0x8B, // SV
+ HID_USAGE_AUX_DISPLAY_BLIT_RECTANGLE_Y1 = 0x8C, // SV
+ HID_USAGE_AUX_DISPLAY_BLIT_RECTANGLE_X2 = 0x8D, // SV
+ HID_USAGE_AUX_DISPLAY_BLIT_RECTANGLE_Y2 = 0x8E, // SV
+ HID_USAGE_AUX_DISPLAY_BLIT_DATA = 0x8F, // Buffered Bytes
+ HID_USAGE_AUX_DISPLAY_SOFT_BUTTON = 0x90, // CL
+ HID_USAGE_AUX_DISPLAY_SOFT_BUTTON_ID = 0x91, // SV
+ HID_USAGE_AUX_DISPLAY_SOFT_BUTTON_SIDE = 0x92, // SV
+ HID_USAGE_AUX_DISPLAY_SOFT_BUTTON_OFFSET_1 = 0x93, // SV
+ HID_USAGE_AUX_DISPLAY_SOFT_BUTTON_OFFSET_2 = 0x94, // SV
+ HID_USAGE_AUX_DISPLAY_SOFT_BUTTON_REPORT = 0x95, // SV
+ // Reserved (0x96 - 0xC1)
+ HID_USAGE_AUX_DISPLAY_SOFT_KEYS = 0xC2, // SV
+ // Reserved (0xC3 - 0xCB)
+ HID_USAGE_AUX_DISPLAY_DATA_EXTENSIONS = 0xCC, // SF
+ // Reserved (0xCD - 0xCE)
+ HID_USAGE_AUX_DISPLAY_CHARACTER_MAPPING = 0xCF, // SV
+ // Reserved (0xD0 - 0xDC)
+ HID_USAGE_AUX_DISPLAY_UNICODE_EQUIVALENT = 0xDD, // SV
+ // Reserved (0xDE)
+ HID_USAGE_AUX_DISPLAY_CHARACTER_PAGE_MAPPING = 0xDF, // SV
+ // Reserved (0xE0 - 0xFE)
+ HID_USAGE_AUX_DISPLAY_REQUEST_REPORT = 0xFF // DV
+ // Reserved (0x100 - 0xFFFF)
+};
+
+/// HID Usage Table - Medical Instrument Page (0x40)
+enum {
+ HID_USAGE_MEDICAL_INSTRUMENT_MEDICAL_ULTRASOUND = 0x01, // CA
+ // Reserved (0x02 - 0x1F)
+ HID_USAGE_MEDICAL_INSTRUMENT_VCR_ACQUISITION = 0x20, // OOC
+ HID_USAGE_MEDICAL_INSTRUMENT_FREEZE_THAW = 0x21, // OOC
+ HID_USAGE_MEDICAL_INSTRUMENT_CLIP_STORE = 0x22, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_UPDATE = 0x23, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_NEXT = 0x24, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_SAVE = 0x25, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_PRINT = 0x26, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_MICROPHONE_ENABLE = 0x27, // OSC
+ // Reserved (0x28 - 0x3F)
+ HID_USAGE_MEDICAL_INSTRUMENT_CINE = 0x40, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_TRANSMIT_POWER = 0x41, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_VOLUME = 0x42, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_FOCUS = 0x43, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_DEPTH = 0x44, // LC
+ // Reserved (0x45 - 0x5F)
+ HID_USAGE_MEDICAL_INSTRUMENT_SOFT_STEP_PRIMARY = 0x60, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_SOFT_STEP_SECONDARY = 0x61, // LC
+ // Reserved (0x62 - 0x6F)
+ HID_USAGE_MEDICAL_INSTRUMENT_DEPTH_GAIN_COMPENSATION = 0x70, // LC
+ // Reserved (0x71 - 0x7F)
+ HID_USAGE_MEDICAL_INSTRUMENT_ZOOM_SELECT = 0x80, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_ZOOM_ADJUST = 0x81, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_SPECTRAL_DOPPLER_MODE_SELECT = 0x82, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_SPECTRAL_DOPPLER_ADJUST = 0x83, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_COLOR_DOPPLER_MODE_SELECT = 0x84, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_COLOR_DOPPLER_ADJUST = 0x85, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_MOTION_MODE_SELECT = 0x86, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_MOTION_MODE_ADJUST = 0x87, // LC
+ HID_USAGE_MEDICAL_INSTRUMENT_2D_MODE_SELECT = 0x88, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_2D_MODE_ADJUST = 0x89, // LC
+ // Reserved (0x8A - 0x9F)
+ HID_USAGE_MEDICAL_INSTRUMENT_SOFT_CONTROL_SELECT = 0xA0, // OSC
+ HID_USAGE_MEDICAL_INSTRUMENT_SOFT_CONTROL_ADJUST = 0xA1, // LC
+ // Reserved (0xA2 - 0xFFFF)
};
/// HID Usage Table - Lighting And Illumination Page (0x59)
enum {
- HID_USAGE_LIGHTING_LAMP_ARRAY = 0x01,
- HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT = 0x02,
- HID_USAGE_LIGHTING_LAMP_COUNT = 0x03,
- HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS = 0x04,
- HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS = 0x05,
- HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS = 0x06,
- HID_USAGE_LIGHTING_LAMP_ARRAY_KIND = 0x07,
- HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS = 0x08,
- HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT = 0x20,
- HID_USAGE_LIGHTING_LAMP_ID = 0x21,
- HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT = 0x22,
- HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS = 0x23,
- HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS = 0x24,
- HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS = 0x25,
- HID_USAGE_LIGHTING_LAMP_PURPOSES = 0x26,
- HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS = 0x27,
- HID_USAGE_LIGHTING_RED_LEVEL_COUNT = 0x28,
- HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT = 0x29,
- HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT = 0x2A,
- HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT = 0x2B,
- HID_USAGE_LIGHTING_IS_PROGRAMMABLE = 0x2C,
- HID_USAGE_LIGHTING_INPUT_BINDING = 0x2D,
- HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT = 0x50,
- HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL = 0x51,
- HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL = 0x52,
- HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL = 0x53,
- HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL = 0x54,
- HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS = 0x55,
- HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT = 0x60,
- HID_USAGE_LIGHTING_LAMP_ID_START = 0x61,
- HID_USAGE_LIGHTING_LAMP_ID_END = 0x62,
- HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT = 0x70,
- HID_USAGE_LIGHTING_AUTONOMOUS_MODE = 0x71,
+ HID_USAGE_LIGHTING_LAMP_ARRAY = 0x01, // CA
+ HID_USAGE_LIGHTING_LAMP_ARRAY_ATTRIBUTES_REPORT = 0x02, // CL
+ HID_USAGE_LIGHTING_LAMP_COUNT = 0x03, // SV/DV
+ HID_USAGE_LIGHTING_BOUNDING_BOX_WIDTH_IN_MICROMETERS = 0x04, // SV
+ HID_USAGE_LIGHTING_BOUNDING_BOX_HEIGHT_IN_MICROMETERS = 0x05, // SV
+ HID_USAGE_LIGHTING_BOUNDING_BOX_DEPTH_IN_MICROMETERS = 0x06, // SV
+ HID_USAGE_LIGHTING_LAMP_ARRAY_KIND = 0x07, // SV
+ HID_USAGE_LIGHTING_MIN_UPDATE_INTERVAL_IN_MICROSECONDS = 0x08, // SV
+ // Reserved (0x09 - 0x1F)
+ HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_REQUEST_REPORT = 0x20, // CL
+ HID_USAGE_LIGHTING_LAMP_ID = 0x21, // SV/DV
+ HID_USAGE_LIGHTING_LAMP_ATTRIBUTES_RESPONSE_REPORT = 0x22, // CL
+ HID_USAGE_LIGHTING_POSITION_X_IN_MICROMETERS = 0x23, // DV
+ HID_USAGE_LIGHTING_POSITION_Y_IN_MICROMETERS = 0x24, // DV
+ HID_USAGE_LIGHTING_POSITION_Z_IN_MICROMETERS = 0x25, // DV
+ HID_USAGE_LIGHTING_LAMP_PURPOSES = 0x26, // DV
+ HID_USAGE_LIGHTING_UPDATE_LATENCY_IN_MICROSECONDS = 0x27, // DV
+ HID_USAGE_LIGHTING_RED_LEVEL_COUNT = 0x28, // DV
+ HID_USAGE_LIGHTING_GREEN_LEVEL_COUNT = 0x29, // DV
+ HID_USAGE_LIGHTING_BLUE_LEVEL_COUNT = 0x2A, // DV
+ HID_USAGE_LIGHTING_INTENSITY_LEVEL_COUNT = 0x2B, // DV
+ HID_USAGE_LIGHTING_IS_PROGRAMMABLE = 0x2C, // DV
+ HID_USAGE_LIGHTING_INPUT_BINDING = 0x2D, // DV
+ // Reserved (0x2E - 0x4F)
+ HID_USAGE_LIGHTING_LAMP_MULTI_UPDATE_REPORT = 0x50, // CL
+ HID_USAGE_LIGHTING_RED_UPDATE_CHANNEL = 0x51, // DV
+ HID_USAGE_LIGHTING_GREEN_UPDATE_CHANNEL = 0x52, // DV
+ HID_USAGE_LIGHTING_BLUE_UPDATE_CHANNEL = 0x53, // DV
+ HID_USAGE_LIGHTING_INTENSITY_UPDATE_CHANNEL = 0x54, // DV
+ HID_USAGE_LIGHTING_LAMP_UPDATE_FLAGS = 0x55, // DV
+ // Reserved (0x56 - 0x5F)
+ HID_USAGE_LIGHTING_LAMP_RANGE_UPDATE_REPORT = 0x60, // CL
+ HID_USAGE_LIGHTING_LAMP_ID_START = 0x61, // DV
+ HID_USAGE_LIGHTING_LAMP_ID_END = 0x62, // DV
+ // Reserved (0x63 - 0x6F)
+ HID_USAGE_LIGHTING_LAMP_ARRAY_CONTROL_REPORT = 0x70, // CL
+ HID_USAGE_LIGHTING_AUTONOMOUS_MODE = 0x71, // DV
+ // Reserved (0x72 - 0xFFFF)
+};
+
+/// HID Usage Table: Monitor Page (0x80)
+enum {
+ HID_USAGE_MONITOR_MONITOR_CONTROL = 0x01, // CA
+ HID_USAGE_MONITOR_EDID_INFORMATION = 0x02, // SV
+ HID_USAGE_MONITOR_VDIF_INFORMATION = 0x03, // SV
+ HID_USAGE_MONITOR_VESA_VERSION = 0x04 // SV
+ // Reserved (0x05 - 0xFFFF)
+};
+
+/// HID Usage Table: Monitor Enumerated Page (0x81)
+/// Intentionally skipped
+
+/// HID Usage Table: VESA Virtual Controls Page (0x82)
+enum {
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_DEGAUSS = 0x01, // DV
+ // Reserved (0x02 - 0x0F)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_BRIGHTNESS = 0x10, // DV
+ // Reserved (0x11)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_CONTRAST = 0x12, // DV
+ // Reserved (0x13 - 0x15)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_RED_VIDEO_GAIN = 0x16, // DV
+ // Reserved (0x17)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_GREEN_VIDEO_GAIN = 0x18, // DV
+ // Reserved (0x19)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_BLUE_VIDEO_GAIN = 0x1A, // DV
+ // Reserved (0x1B)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_FOCUS = 0x1C, // DV
+ // Reserved (0x1D - 0x1F)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_POSITION = 0x20, // DV
+ // Reserved (0x21)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_SIZE = 0x22, // DV
+ // Reserved (0x23)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_PINCUSHION = 0x24, // DV
+ // Reserved (0x25)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_PINCUSHION_BALANCE = 0x26, // DV
+ // Reserved (0x27)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_MISCONVERGENCE = 0x28, // DV
+ // Reserved (0x29)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_LINEARITY = 0x2A, // DV
+ // Reserved (0x2B)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_LINEARITY_BALANCE = 0x2C, // DV
+ // Reserved (0x2D - 0x2F)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_POSITION = 0x30, // DV
+ // Reserved (0x31)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_SIZE = 0x32, // DV
+ // Reserved (0x33)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_PINCUSHION = 0x34, // DV
+ // Reserved (0x35)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_PINCUSHION_BALANCE = 0x36, // DV
+ // Reserved (0x37)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_MISCONVERGENCE = 0x38, // DV
+ // Reserved (0x39)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_LINEARITY = 0x3A, // DV
+ // Reserved (0x3B)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_LINEARITY_BALANCE = 0x3C, // DV
+ // Reserved (0x3D - 0x3F)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_PARALLELOGRAM_DISTORTION = 0x40, // DV
+ // Reserved (0x41)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_TRAPEZOIDAL_DISTORTION = 0x42, // DV
+ // Reserved (0x43)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_TILT = 0x44, // DV
+ // Reserved (0x45)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_TOP_CORNER_DISTORTION_CONTROL = 0x46, // DV
+ // Reserved (0x47)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_TOP_CORNER_DISTORTION_BALANCE = 0x48, // DV
+ // Reserved (0x49)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_BOTTOM_CORNER_DISTORTION_CONTROL = 0x4A, // DV
+ // Reserved (0x4B)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_BOTTOM_CORNER_DISTORTION_BALANCE = 0x4C, // DV
+ // Reserved (0x4D - 0x55)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_MOIRE = 0x56, // DV
+ // Reserved (0x57)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_MOIRE = 0x58, // DV
+ // Reserved (0x59 - 0x5D)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_INPUT_LEVEL_SELECT = 0x5E, // NAry
+ // Reserved (0x5F)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_INPUT_SOURCE_SELECT = 0x60, // NAry
+ // Reserved (0x61 - 0x6B)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_RED_VIDEO_BLACK_LEVEL = 0x6C, // DV
+ // Reserved (0x6D)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_GREEN_VIDEO_BLACK_LEVEL = 0x6E, // DV
+ // Reserved (0x6F)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_BLUE_VIDEO_BLACK_LEVEL = 0x70, // DV
+ // Reserved (0x71 - 0xA1)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_AUTO_SIZE_CENTER = 0xA2, // NAry
+ // Reserved (0xA3)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_POLARITY_HORIZONTAL_SYNC = 0xA4, // NAry
+ // Reserved (0xA5)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_POLARITY_VERTICAL_SYNC = 0xA6, // NAry
+ // Reserved (0xA7)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_SYNC_TYPE = 0xA8, // NAry
+ // Reserved (0xA9)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_SCREEN_ORIENTATION = 0xAA, // NAry
+ // Reserved (0xAB)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_HORIZONTAL_FREQUENCY = 0xAC, // DV
+ // Reserved (0xAD)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_VERTICAL_FREQUENCY = 0xAE, // DV
+ // Reserved (0xAF)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_SETTINGS = 0xB0, // NAry
+ // Reserved (0xB1 - 0xC9)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_ON_SCREEN_DISPLAY = 0xCA, // NAry
+ // Reserved (0xCB - 0xD3)
+ HID_USAGE_VESA_VIRTUAL_CONTROLS_STEREO_MODE = 0xD4, // NAry
+ // Reserved (0xD5 - 0xFFFF)
};
/// HID Usage Table: Power Device Page (0x84)
@@ -1665,6 +2579,7 @@ enum {
HID_USAGE_POWER_I_MANUFACTURER = 0xFD,
HID_USAGE_POWER_I_PRODUCT = 0xFE,
HID_USAGE_POWER_I_SERIAL_NUMBER = 0xFF
+ // Reserved (0x100 - 0xFFFF)
};
/// HID Usage Table: Battery System Page (0x85)
@@ -1772,6 +2687,48 @@ enum {
// F4-FF Reserved
};
+/// HID Usage Table: Camera Control Page (0x90)
+enum {
+ // Reserved (0x01 - 0x1F)
+ HID_USAGE_CAMERA_CONTROL_CAMERA_AUTO_FOCUS = 0x20, // OSC
+ HID_USAGE_CAMERA_CONTROL_CAMERA_SHUTTER = 0x21 // OSC
+ // Reserved (0x22 - 0xFFFF)
+};
+
+/// HID Usage Table: Arcade Page (0x91)
+enum {
+ HID_USAGE_ARCADE_GENERAL_PURPOSE_IO_CARD = 0x01, // CA
+ HID_USAGE_ARCADE_COIN_DOOR = 0x02, // CA
+ HID_USAGE_ARCADE_WATCHDOG_TIMER = 0x03, // CA
+ // Reserved (0x04 - 0x2F)
+ HID_USAGE_ARCADE_GENERAL_PURPOSE_ANALOG_INPUT_STATE = 0x30, // DV
+ HID_USAGE_ARCADE_GENERAL_PURPOSE_DIGITAL_INPUT_STATE = 0x31, // DV
+ HID_USAGE_ARCADE_GENERAL_PURPOSE_OPTICAL_INPUT_STATE = 0x32, // DV
+ HID_USAGE_ARCADE_GENERAL_PURPOSE_DIGITAL_OUTPUT_STATE = 0x33, // DV
+ HID_USAGE_ARCADE_NUMBER_OF_COIN_DOORS = 0x34, // DV
+ HID_USAGE_ARCADE_COIN_DRAWER_DROP_COUNT = 0x35, // DV
+ HID_USAGE_ARCADE_COIN_DRAWER_START = 0x36, // OOC
+ HID_USAGE_ARCADE_COIN_DRAWER_SERVICE = 0x37, // OOC
+ HID_USAGE_ARCADE_COIN_DRAWER_TILT = 0x38, // OOC
+ HID_USAGE_ARCADE_COIN_DOOR_TEST = 0x39, // OOC
+ // Reserved (0x3A - 0x3F)
+ HID_USAGE_ARCADE_COIN_DOOR_LOCKOUT = 0x40, // OOC
+ HID_USAGE_ARCADE_WATCHDOG_TIMEOUT = 0x41, // DV
+ HID_USAGE_ARCADE_WATCHDOG_ACTION = 0x42, // NAry
+ HID_USAGE_ARCADE_WATCHDOG_REBOOT = 0x43, // Sel
+ HID_USAGE_ARCADE_WATCHDOG_RESTART = 0x44, // Sel
+ HID_USAGE_ARCADE_ALARM_INPUT = 0x45, // DV
+ HID_USAGE_ARCADE_COIN_DOOR_COUNTER = 0x46, // OOC
+ HID_USAGE_ARCADE_IO_DIRECTION_MAPPING = 0x47, // DV
+ HID_USAGE_ARCADE_SET_IO_DIRECTION_MAPPING = 0x48, // DV
+ HID_USAGE_ARCADE_EXTENDED_OPTICAL_INPUT_STATE = 0x49, // DV
+ HID_USAGE_ARCADE_PIN_PAD_INPUT_STATE = 0x4A, // DV
+ HID_USAGE_ARCADE_PIN_PAD_STATUS = 0x4B, // DV
+ HID_USAGE_ARCADE_PIN_PAD_OUTPUT = 0x4C, // OOC
+ HID_USAGE_ARCADE_PIN_PAD_COMMAND = 0x4D, // DV
+ // Reserved (0x4E - 0xFFFF)
+};
+
/// HID Usage Table: FIDO Alliance Page (0xF1D0)
enum {
HID_USAGE_FIDO_U2FHID = 0x01, // U2FHID usage for top-level collection
diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c
index 1d40a2efa..b0a9e2503 100644
--- a/src/class/midi/midi2_device.c
+++ b/src/class/midi/midi2_device.c
@@ -36,6 +36,9 @@ TU_ATTR_WEAK const char* tud_midi2_fb_name_cb(uint8_t itf, uint8_t fb_idx) {
TU_ATTR_WEAK tud_midi2_stream_result_t tud_midi2_stream_msg_cb(uint8_t itf, const uint32_t* ump_words) {
(void) itf; (void) ump_words; return MIDI2_STREAM_PASS;
}
+TU_ATTR_WEAK bool tud_midi2_device_identity_cb(uint8_t itf, tud_midi2_device_identity_t* identity) {
+ (void) itf; (void) identity; return false;
+}
//--------------------------------------------------------------------+
// Byte order note
@@ -59,6 +62,7 @@ enum {
enum {
STREAM_ENDPOINT_DISCOVERY = 0x000,
STREAM_ENDPOINT_INFO = 0x001,
+ STREAM_DEVICE_IDENTITY = 0x002,
STREAM_EP_NAME = 0x003,
STREAM_PROD_INSTANCE_ID = 0x004,
STREAM_CONFIG_REQUEST = 0x005,
@@ -103,6 +107,16 @@ typedef struct {
uint8_t protocol;
bool negotiated;
+ // Discovery reply bits waiting for TX FIFO room, drained on TX complete
+ uint8_t nego_pending_ep_filter;
+ uint8_t nego_pending_fb_filter;
+ uint8_t nego_pending_fb_num; // block requested by the pending discovery, 0xFF = all
+ uint8_t nego_pending_fb_next; // next block index to reply for
+ bool nego_pending_fb_restart; // restart after the active FB name when requests merge
+ uint16_t nego_text_status; // text reply owning nego_text_offset, 0 = none
+ uint16_t nego_text_offset; // progress into the text reply being sent
+ uint8_t nego_text_index; // Function Block index for an active FB name
+
/*------------- From this point, data is not cleared by bus reset -------------*/
struct {
midi2d_tx_t tx;
@@ -327,16 +341,20 @@ static void _nego_send_endpoint_info(midi2d_interface_t* p_midi) {
// index byte (the Function Block number for FB Name) and 13 chars fit per
// packet; otherwise the text starts there and 14 chars fit (Endpoint Name,
// Product Instance Id).
-static void _nego_send_stream_text(midi2d_interface_t* p_midi, uint16_t status,
- bool has_index, uint8_t index, const char* str) {
- if (!str || str[0] == '\0') return;
+// Sends a stream text from `offset` and returns how far it got. Resuming keeps
+// the End packet, which dropping the tail would lose.
+static uint16_t _nego_send_stream_text(midi2d_interface_t* p_midi, uint16_t status,
+ bool has_index, uint8_t index, const char* str,
+ uint16_t offset) {
+ if (!str || str[0] == '\0') return 0;
- uint16_t total_len = (uint16_t) strlen(str);
- uint16_t offset = 0;
+ const uint16_t total_len = (uint16_t) strlen(str);
const uint8_t per_pkt = has_index ? 13 : 14;
const uint8_t head_chars = has_index ? 1 : 2; // chars carried in word0
+ if (offset >= total_len) return total_len;
while (offset < total_len) {
+ if (tu_fifo_remaining(&p_midi->ep_stream.tx.ff) < 16) break;
uint16_t remaining = total_len - offset;
uint8_t n = (uint8_t)((remaining > per_pkt) ? per_pkt : remaining);
bool is_first = (offset == 0);
@@ -370,6 +388,7 @@ static void _nego_send_stream_text(midi2d_interface_t* p_midi, uint16_t status,
_nego_send_ump(p_midi, msg, 4);
offset += n;
}
+ return offset;
}
static void _nego_send_config_notify(midi2d_interface_t* p_midi, uint8_t protocol) {
@@ -380,6 +399,33 @@ static void _nego_send_config_notify(midi2d_interface_t* p_midi, uint8_t protoco
_nego_send_ump(p_midi, msg, 4);
}
+static void _nego_send_device_identity(midi2d_interface_t* p_midi) {
+ tud_midi2_device_identity_t id;
+ tu_memclr(&id, sizeof(id));
+ if (!tud_midi2_device_identity_cb(_itf_idx(p_midi), &id)) return;
+
+ // Every field is a run of bytes, each carrying 7 bits, laid out in the same
+ // order as the MIDI 1.0 Device Inquiry reply this message mirrors. A 1-byte
+ // manufacturer ID occupies the first of the three bytes, the other two stay
+ // zero, so the caller passes it as 0x7D0000 and not 0x00007D.
+ uint32_t msg[4] = {0};
+ msg[0] = ((uint32_t) MT_STREAM << 28)
+ | ((uint32_t) STREAM_DEVICE_IDENTITY << 16);
+ msg[1] = id.manufacturer & UINT32_C(0x7F7F7F);
+ // Family and model are 14-bit numbers sent least significant byte first,
+ // as in the Device Inquiry reply. Manufacturer above is a byte sequence
+ // rather than a number, so it keeps its own order.
+ msg[2] = ((uint32_t) (id.family & 0x7F) << 24)
+ | ((uint32_t) ((id.family >> 7) & 0x7F) << 16)
+ | ((uint32_t) (id.model & 0x7F) << 8)
+ | ((uint32_t) ((id.model >> 7) & 0x7F));
+ msg[3] = ((uint32_t) ((id.sw_revision >> 24) & 0x7F) << 24)
+ | ((uint32_t) ((id.sw_revision >> 16) & 0x7F) << 16)
+ | ((uint32_t) ((id.sw_revision >> 8) & 0x7F) << 8)
+ | ((uint32_t) (id.sw_revision & 0x7F));
+ _nego_send_ump(p_midi, msg, 4);
+}
+
static void _nego_send_fb_info(midi2d_interface_t* p_midi, uint8_t fb_idx) {
// Derive direction and group span for this block from the GTB descriptor.
uint16_t gtb_len = 0;
@@ -395,10 +441,122 @@ static void _nego_send_fb_info(midi2d_interface_t* p_midi, uint8_t fb_idx) {
| ((uint32_t) fb_idx << 8)
| _fb_dir_byte(type); // UI hint + bDirection from the GTB block type
msg[1] = ((uint32_t) first_group << 24)
- | ((uint32_t) num_groups << 16);
+ | ((uint32_t) num_groups << 16)
+ | ((uint32_t) (CFG_TUD_MIDI2_FB_CI_VERSION & 0xFF) << 8)
+ | ((uint32_t) (CFG_TUD_MIDI2_FB_SYSEX8_STREAMS & 0xFF));
_nego_send_ump(p_midi, msg, 4);
}
+static void _nego_clear_pending(midi2d_interface_t* p_midi) {
+ p_midi->nego_pending_ep_filter = 0;
+ p_midi->nego_pending_fb_filter = 0;
+ p_midi->nego_pending_fb_num = 0;
+ p_midi->nego_pending_fb_next = 0;
+ p_midi->nego_pending_fb_restart = false;
+ p_midi->nego_text_status = 0;
+ p_midi->nego_text_offset = 0;
+ p_midi->nego_text_index = 0;
+}
+
+static const char* _nego_text_cb(midi2d_interface_t* p_midi, uint16_t status, uint8_t index) {
+ const uint8_t itf = _itf_idx(p_midi);
+ switch (status) {
+ case STREAM_EP_NAME: return tud_midi2_ep_name_cb(itf);
+ case STREAM_PROD_INSTANCE_ID: return tud_midi2_product_id_cb(itf);
+ case STREAM_FB_NAME: return tud_midi2_fb_name_cb(itf, index);
+ default: return NULL;
+ }
+}
+
+// Send or resume one text reply. While it is incomplete, its status and index
+// identify the sole owner of nego_text_offset so another discovery request
+// cannot resume a different string from the same offset.
+static bool _nego_send_text(midi2d_interface_t* p_midi, uint16_t status, uint8_t index) {
+ const char* text = _nego_text_cb(p_midi, status, index);
+ const uint16_t len = text ? (uint16_t) strlen(text) : 0;
+
+ p_midi->nego_text_status = status;
+ p_midi->nego_text_index = index;
+ p_midi->nego_text_offset = _nego_send_stream_text(p_midi, status, status == STREAM_FB_NAME,
+ index, text, p_midi->nego_text_offset);
+ if (p_midi->nego_text_offset < len) return false;
+
+ p_midi->nego_text_status = 0;
+ p_midi->nego_text_offset = 0;
+ p_midi->nego_text_index = 0;
+ return true;
+}
+
+// Send pending discovery replies, one whole reply at a time and only when the
+// TX FIFO can take it. A full-filter Endpoint Discovery asks for more bytes
+// than the default FIFO holds; replies that do not fit stay pending and are
+// retried from the TX complete path, paced by the transfer flow.
+static void _nego_send_pending(midi2d_interface_t* p_midi) {
+ tu_fifo_t* tx_ff = &p_midi->ep_stream.tx.ff;
+
+ // An incomplete text sequence must finish before any newly arrived request
+ // is serviced; otherwise its Continue/End packets could be attached to a
+ // different Endpoint or Function Block string.
+ if (p_midi->nego_text_status) {
+ const uint16_t status = p_midi->nego_text_status;
+ const uint8_t index = p_midi->nego_text_index;
+ if (!_nego_send_text(p_midi, status, index)) return;
+
+ if (status == STREAM_FB_NAME) {
+ if (p_midi->nego_pending_fb_restart) {
+ p_midi->nego_pending_fb_next = 0;
+ p_midi->nego_pending_fb_restart = false;
+ } else {
+ p_midi->nego_pending_fb_next++;
+ }
+ } else {
+ const uint8_t bit = (status == STREAM_EP_NAME) ? 0x04 : 0x08;
+ p_midi->nego_pending_ep_filter &= (uint8_t) ~bit;
+ }
+ }
+
+ while (p_midi->nego_pending_ep_filter) {
+ const uint8_t bit = (uint8_t)(p_midi->nego_pending_ep_filter & (uint8_t)(-p_midi->nego_pending_ep_filter));
+ uint16_t status = 0;
+ switch (bit) {
+ case 0x04: status = STREAM_EP_NAME; break;
+ case 0x08: status = STREAM_PROD_INSTANCE_ID; break;
+ default: break;
+ }
+
+ if (status != 0) {
+ if (!_nego_send_text(p_midi, status, 0)) return;
+ } else {
+ if (tu_fifo_remaining(tx_ff) < 16) return;
+ switch (bit) {
+ case 0x01: _nego_send_endpoint_info(p_midi); break;
+ case 0x02: _nego_send_device_identity(p_midi); break;
+ case 0x10: _nego_send_config_notify(p_midi, p_midi->protocol); break;
+ default: break;
+ }
+ }
+ p_midi->nego_pending_ep_filter &= (uint8_t) ~bit;
+ }
+
+ const uint8_t fb_count = _gtb_block_count(p_midi);
+ while (p_midi->nego_pending_fb_filter && p_midi->nego_pending_fb_next < fb_count) {
+ const uint8_t f = p_midi->nego_pending_fb_next;
+ if (p_midi->nego_pending_fb_num != 0xFF && p_midi->nego_pending_fb_num != f) {
+ p_midi->nego_pending_fb_next++;
+ continue;
+ }
+ if ((p_midi->nego_pending_fb_filter & 0x01) && p_midi->nego_text_offset == 0) {
+ if (tu_fifo_remaining(tx_ff) < 16) return;
+ _nego_send_fb_info(p_midi, f);
+ }
+ if (p_midi->nego_pending_fb_filter & 0x02) {
+ if (!_nego_send_text(p_midi, STREAM_FB_NAME, f)) return;
+ }
+ p_midi->nego_pending_fb_next++;
+ }
+ if (p_midi->nego_pending_fb_next >= fb_count) p_midi->nego_pending_fb_filter = 0;
+}
+
static void _nego_handle_stream_msg(midi2d_interface_t* p_midi, const uint32_t* words) {
// Let the application override this message before the built-in responder.
switch (tud_midi2_stream_msg_cb(_itf_idx(p_midi), words)) {
@@ -421,9 +579,9 @@ static void _nego_handle_stream_msg(midi2d_interface_t* p_midi, const uint32_t*
switch (status) {
case STREAM_ENDPOINT_DISCOVERY:
- _nego_send_endpoint_info(p_midi);
- _nego_send_stream_text(p_midi, STREAM_EP_NAME, false, 0, tud_midi2_ep_name_cb(_itf_idx(p_midi)));
- _nego_send_stream_text(p_midi, STREAM_PROD_INSTANCE_ID, false, 0, tud_midi2_product_id_cb(_itf_idx(p_midi)));
+ // Filter bitmap: each bit set asks for one individual reply.
+ p_midi->nego_pending_ep_filter |= (uint8_t)(words[1] & 0x1F);
+ _nego_send_pending(p_midi);
break;
case STREAM_CONFIG_REQUEST: {
@@ -437,14 +595,23 @@ static void _nego_handle_stream_msg(midi2d_interface_t* p_midi, const uint32_t*
}
case STREAM_FB_DISCOVERY: {
- uint8_t fb_idx = (words[0] >> 8) & 0xFF;
- uint8_t filter = words[0] & 0xFF; // bit 0: FB Info, bit 1: FB Name
- uint8_t fb_count = _gtb_block_count(p_midi);
- for (uint8_t f = 0; f < fb_count; f++) {
- if (fb_idx != 0xFF && fb_idx != f) continue;
- if (filter & 0x01) _nego_send_fb_info(p_midi, f);
- if (filter & 0x02) _nego_send_stream_text(p_midi, STREAM_FB_NAME, true, f, tud_midi2_fb_name_cb(_itf_idx(p_midi), f));
+ const uint8_t req_num = (uint8_t)((words[0] >> 8) & 0xFF);
+ const uint8_t req_filter = (uint8_t)(words[0] & 0x03);
+ // Merge with a pending request: repeating a Function Block Info is allowed
+ // at any time, losing a requested one is not.
+ if (req_filter && p_midi->nego_pending_fb_filter) {
+ if (p_midi->nego_pending_fb_num != req_num) p_midi->nego_pending_fb_num = 0xFF;
+ if (p_midi->nego_text_status == STREAM_FB_NAME) {
+ p_midi->nego_pending_fb_restart = true;
+ } else {
+ p_midi->nego_pending_fb_next = 0;
+ }
+ } else if (!p_midi->nego_pending_fb_filter) {
+ p_midi->nego_pending_fb_num = req_num;
+ p_midi->nego_pending_fb_next = 0;
}
+ p_midi->nego_pending_fb_filter |= req_filter; // bit 0: FB Info, bit 1: FB Name
+ _nego_send_pending(p_midi);
break;
}
@@ -754,6 +921,7 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re
tu_edpt_stream_clear(&p_midi->ep_stream.rx);
tu_fifo_clear(&p_midi->ep_stream.tx.ff);
+ _nego_clear_pending(p_midi);
if (alt == 1) {
p_midi->negotiated = false;
@@ -824,6 +992,10 @@ bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
}
tu_edpt_stream_read_xfer(ep_rx);
} else if (ep_addr == ep_tx->ep_addr && result == XFER_RESULT_SUCCESS) {
+ // Completed transfer freed FIFO room: flush discovery replies still pending.
+ if (p_midi->alt_setting == 1) {
+ _nego_send_pending(p_midi);
+ }
uint16_t queued = _tx_start_xfer(p_midi);
// Send ZLP if no more data is queued but the last transfer was exactly mps
if (queued == 0 && tu_fifo_count(&ep_tx->ff) == 0 && xferred_bytes > 0 &&
diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h
index 171b404b7..e3eb084d9 100644
--- a/src/class/midi/midi2_device.h
+++ b/src/class/midi/midi2_device.h
@@ -58,6 +58,17 @@ extern "C" {
#define CFG_TUD_MIDI2_PRODUCT_ID "TinyUSB-MIDI2"
#endif
+// Function Block capabilities reported in Function Block Info Notification.
+// The GTB descriptor carries direction and group span, but not these: they
+// depend on what the application implements, so they default to "none".
+#ifndef CFG_TUD_MIDI2_FB_CI_VERSION
+ #define CFG_TUD_MIDI2_FB_CI_VERSION 0 // 0: none or unknown, 1 or higher: MIDI-CI version
+#endif
+
+#ifndef CFG_TUD_MIDI2_FB_SYSEX8_STREAMS
+ #define CFG_TUD_MIDI2_FB_SYSEX8_STREAMS 0 // 0: unsupported, 1: single, 2-255: simultaneous streams
+#endif
+
// String descriptor index for the Group Terminal Block (iBlockItem, Table 5-6).
// 0 = no string descriptor (default, spec-allowed).
#ifndef CFG_TUD_MIDI2_BLOCK_STRIDX
@@ -118,6 +129,17 @@ typedef enum {
MIDI2_STREAM_NEGOTIATED_MIDI2,
} tud_midi2_stream_result_t;
+// Device identity fields, as defined for the MIDI 1.0 Device Inquiry reply and
+// reused by the Device Identity Notification. Every byte carries 7 bits.
+// A 1-byte System Exclusive ID goes in the first of the three manufacturer
+// bytes, so 0x7D is passed as 0x7D0000.
+typedef struct {
+ uint32_t manufacturer; // 3 bytes, first byte is most significant
+ uint16_t family; // 2 bytes
+ uint16_t model; // 2 bytes
+ uint32_t sw_revision; // 4 bytes
+} tud_midi2_device_identity_t;
+
//--------------------------------------------------------------------+
// Application Callback API (weak, optional)
//--------------------------------------------------------------------+
@@ -138,6 +160,12 @@ const uint8_t* tud_midi2_gtb_desc_cb(uint8_t itf, uint16_t* len);
// discovery. Return NULL or "" for no name.
const char* tud_midi2_fb_name_cb(uint8_t itf, uint8_t fb_idx);
+// Optional device identity, sent as a Device Identity Notification when the
+// host sets the 'd' bit in the Endpoint Discovery filter. Same four fields as
+// the MIDI 1.0 Device Inquiry reply. Return false to skip the notification,
+// which is the default. All values are 7-bit per byte.
+bool tud_midi2_device_identity_cb(uint8_t itf, tud_midi2_device_identity_t* identity);
+
// Optional: intercept an incoming UMP Stream message (MT 0xF). Return PASS to
// let the built-in responder handle it, or HANDLED / NEGOTIATED_* if the app
// answered it (e.g. via tud_midi2_n_ump_write). Lets an app override a single
diff --git a/src/class/mtp/mtp_device.c b/src/class/mtp/mtp_device.c
index 7657899ec..275c9f858 100644
--- a/src/class/mtp/mtp_device.c
+++ b/src/class/mtp/mtp_device.c
@@ -437,8 +437,11 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
TU_LOG_DRV(" MTP Data %s CB: xferred_bytes=%lu, xferred_len/total_len=%lu/%lu, is_complete=%d\r\n",
is_data_in ? "IN" : "OUT", xferred_bytes, p_mtp->xferred_len, p_mtp->total_len, is_complete ? 1 : 0);
- // Send/queue ZLP if packet is full-sized but transfer is complete
- if (is_complete && xferred_bytes > 0 && !(xferred_bytes & (threshold - 1))) {
+ // Send/queue ZLP if packet is full-sized but transfer is complete.
+ // OUT must deliver this final payload to the application before receiving
+ // its terminating ZLP below.
+ const bool need_zlp = is_complete && xferred_bytes > 0 && !(xferred_bytes & (threshold - 1));
+ if (is_data_in && need_zlp) {
TU_LOG_DRV(" queue ZLP\r\n");
TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr));
TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, NULL, 0, false));
@@ -466,9 +469,16 @@ bool mtpd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
cb_data.io_container = headerless_packet;
cb_data.io_container.payload_bytes = xferred_bytes;
}
- tud_mtp_data_xfer_cb(&cb_data);
+ if (xferred_bytes > 0) {
+ tud_mtp_data_xfer_cb(&cb_data);
+ }
- if (is_complete) {
+ if (need_zlp) {
+ TU_LOG_DRV(" queue ZLP\r\n");
+ TU_VERIFY(usbd_edpt_claim(p_mtp->rhport, ep_addr));
+ TU_ASSERT(usbd_edpt_xfer(p_mtp->rhport, ep_addr, NULL, 0, false));
+ return true;
+ } else if (is_complete) {
// back to header + payload for response
cb_data.io_container = headered_packet;
cb_data.io_container.header->len = sizeof(mtp_container_header_t);
diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c
index 84a524f49..72b592787 100644
--- a/src/class/net/ncm_device.c
+++ b/src/class/net/ncm_device.c
@@ -800,31 +800,56 @@ static void tud_network_recv_renew_r(uint8_t rhport) {
} // tud_network_recv_renew
/**
- * Set the link state and send notification to host
+ * usbd-task trampoline for tud_network_link_state(), packing rhport and is_up
+ * into a single pointer-sized argument.
+ *
+ * Runs entirely in the usbd task context, so it cannot race the notify
+ * xfer-completion callback over the notification state machine. Re-arming
+ * notification_xmit_state and kicking notification_xmit() (rather than
+ * sending NETWORK_CONNECTION directly) means a state change that collides
+ * with an in-flight notification is picked up by the existing completion
+ * callback instead of being silently dropped - which would otherwise leave
+ * the host stuck at NO-CARRIER after a link-state change.
*/
-void tud_network_link_state(uint8_t rhport, bool is_up) {
- TU_LOG_DRV("tud_network_link_state(%d, %d)\n", rhport, is_up);
+static void ncm_link_state_task(void *param) {
+ uintptr_t const arg = (uintptr_t) param;
+ uint8_t const rhport = (uint8_t) (arg >> 1);
+ bool const is_up = (arg & 1u) != 0;
if (ncm_interface.link_is_up == is_up) {
- // No change in link state
- return;
+ return; // no change in link state
}
ncm_interface.link_is_up = is_up;
- // Only send notification if we have an active data interface
if (ncm_interface.itf_data_alt != 1) {
- TU_LOG_DRV(" link state notification skipped (interface not active)\n");
- return;
+ TU_LOG_DRV(" link state notification deferred (interface not active)\n");
+ return; // data interface not active yet; SET_INTERFACE(alt=1) will notify
}
- // Reset notification state to send speed change notification first, then link state notification
+ // A link toggle does not change the link speed, so strictly only the
+ // NETWORK_CONNECTION notification would need (re)sending. Re-running the
+ // speed-then-connection sequence keeps this on the same state machine the
+ // completion callback already drives, at the cost of a redundant speed
+ // notification on every toggle.
ncm_interface.notification_xmit_state = NOTIFICATION_SPEED;
-
- // Trigger notification transmission
notification_xmit(rhport, false);
}
+/**
+ * Set the link state and notify the host.
+ *
+ * Defers onto the usbd task so a caller running in a different task than
+ * tud_task() cannot race the notification state machine against the notify
+ * xfer-completion callback.
+ */
+void tud_network_link_state(uint8_t rhport, bool is_up) {
+ TU_LOG_DRV("tud_network_link_state(%d, %d)\n", rhport, is_up);
+
+ uintptr_t const arg = ((uintptr_t) rhport << 1) | (is_up ? 1u : 0u);
+ usbd_defer_func(ncm_link_state_task, (void *) arg, false);
+}
+
//-----------------------------------------------------------------------------
//
// all the netd_*() stuff (interface TinyUSB -> driver)
diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c
index 07190d89f..0e9978a81 100644
--- a/src/class/usbtmc/usbtmc_device.c
+++ b/src/class/usbtmc/usbtmc_device.c
@@ -497,9 +497,24 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
#if (CFG_TUD_USBTMC_ENABLE_488)
case USBTMC_MSGID_USB488_TRIGGER:
- // Spec says we halt the EP if we didn't declare we support it.
- TU_VERIFY(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger);
- TU_VERIFY(tud_usbtmc_msg_trigger_cb(msg));
+ // Unlike the messages above, TRIGGER is complete on arrival and has no response, so nothing else
+ // will move us out of STATE_IDLE. Do it here, otherwise the tud_usbtmc_start_bus_read() below (and
+ // any call the application makes from its callback) is a no-op and the bulk-OUT endpoint is left
+ // un-armed, silently timing out every subsequent host transfer.
+ TU_VERIFY(atomicChangeState(STATE_IDLE, STATE_NAK));
+
+ // Spec says we halt the EP if we didn't declare we support it; do the same when the application
+ // rejects the trigger. The callback result must not be wrapped in TU_VERIFY() here: returning
+ // early would skip both the stall and the re-arm below.
+ if (!usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger ||
+ !tud_usbtmc_msg_trigger_cb(msg)) {
+ usbd_edpt_stall(rhport, usbtmc_state.ep_bulk_out);
+ return false;
+ }
+ // Result deliberately ignored: false here means the endpoint is already armed - either the
+ // application re-armed it from its callback, or a transfer is still queued - not that arming
+ // failed. Stalling on it would halt a healthy endpoint.
+ tud_usbtmc_start_bus_read();
break;
#endif
diff --git a/src/class/usbtmc/usbtmc_device.h b/src/class/usbtmc/usbtmc_device.h
index 3dc700876..efda84f16 100644
--- a/src/class/usbtmc/usbtmc_device.h
+++ b/src/class/usbtmc/usbtmc_device.h
@@ -25,7 +25,6 @@
// * tud_usbtmc_open_cb
// * tud_usbtmc_msg_data_cb
// * tud_usbtmc_msgBulkIn_complete_cb
-// * tud_usbtmc_msg_trigger_cb
// * (successful) tud_usbtmc_check_abort_bulk_out_cb
// * (successful) tud_usbtmc_check_abort_bulk_in_cb
// * (successful) tud_usmtmc_bulkOut_clearFeature_cb
diff --git a/src/class/vendor/vendor_host.c b/src/class/vendor/vendor_host.c
deleted file mode 100644
index dd2c5ac5d..000000000
--- a/src/class/vendor/vendor_host.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * SPDX-FileCopyrightText: Copyright (c) 2019 Ha Thach (tinyusb.org)
- * SPDX-License-Identifier: MIT
- *
- * This file is part of the TinyUSB stack.
- */
-
-#include "tusb_option.h"
-
-#if (CFG_TUH_ENABLED && CFG_TUH_VENDOR)
-
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
-#include "host/usbh.h"
-#include "vendor_host.h"
-
-//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF
-//--------------------------------------------------------------------+
-
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
-custom_interface_info_t custom_interface[CFG_TUH_DEVICE_MAX];
-
-static tusb_error_t cush_validate_paras(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length)
-{
- if ( !tusbh_custom_is_mounted(dev_addr, vendor_id, product_id) )
- {
- return TUSB_ERROR_DEVICE_NOT_READY;
- }
-
- TU_ASSERT( p_buffer != NULL && length != 0, TUSB_ERROR_INVALID_PARA);
-
- return TUSB_ERROR_NONE;
-}
-//--------------------------------------------------------------------+
-// APPLICATION API (need to check parameters)
-//--------------------------------------------------------------------+
-tusb_error_t tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length)
-{
- TU_ASSERT_ERR( cush_validate_paras(dev_addr, vendor_id, product_id, p_buffer, length) );
-
- if ( !hcd_pipe_is_idle(custom_interface[dev_addr-1].pipe_in) )
- {
- return TUSB_ERROR_INTERFACE_IS_BUSY;
- }
-
- (void) usbh_edpt_xfer( custom_interface[dev_addr-1].pipe_in, p_buffer, length);
-
- return TUSB_ERROR_NONE;
-}
-
-tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length)
-{
- TU_ASSERT_ERR( cush_validate_paras(dev_addr, vendor_id, product_id, p_data, length) );
-
- if ( !hcd_pipe_is_idle(custom_interface[dev_addr-1].pipe_out) )
- {
- return TUSB_ERROR_INTERFACE_IS_BUSY;
- }
-
- (void) usbh_edpt_xfer( custom_interface[dev_addr-1].pipe_out, p_data, length);
-
- return TUSB_ERROR_NONE;
-}
-
-//--------------------------------------------------------------------+
-// USBH-CLASS API
-//--------------------------------------------------------------------+
-void cush_init(void)
-{
- tu_memclr(&custom_interface, sizeof(custom_interface_info_t) * CFG_TUH_DEVICE_MAX);
-}
-
-tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
-{
- // FIXME quick hack to test lpc1k custom class with 2 bulk endpoints
- uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
- p_desc = tu_desc_next(p_desc);
-
- //------------- Bulk Endpoints Descriptor -------------//
- for(uint32_t i=0; i<2; i++)
- {
- tusb_desc_endpoint_t const *p_endpoint = (tusb_desc_endpoint_t const *) p_desc;
- TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType, TUSB_ERROR_INVALID_PARA);
-
- pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ?
- &custom_interface[dev_addr-1].pipe_in : &custom_interface[dev_addr-1].pipe_out;
- *p_pipe_hdl = usbh_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
- TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED );
-
- p_desc = tu_desc_next(p_desc);
- }
-
- (*p_length) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
- return TUSB_ERROR_NONE;
-}
-
-void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event)
-{
-
-}
-
-void cush_close(uint8_t dev_addr)
-{
- tusb_error_t err1, err2;
- custom_interface_info_t * p_interface = &custom_interface[dev_addr-1];
-
- // TODO re-consider to check pipe valid before calling pipe_close
- if( pipehandle_is_valid( p_interface->pipe_in ) )
- {
- err1 = hcd_pipe_close( p_interface->pipe_in );
- }
-
- if ( pipehandle_is_valid( p_interface->pipe_out ) )
- {
- err2 = hcd_pipe_close( p_interface->pipe_out );
- }
-
- tu_memclr(p_interface, sizeof(custom_interface_info_t));
-
- TU_ASSERT(err1 == TUSB_ERROR_NONE && err2 == TUSB_ERROR_NONE, (void) 0 );
-}
-
-#endif
diff --git a/src/class/vendor/vendor_host.h b/src/class/vendor/vendor_host.h
deleted file mode 100644
index dc55663b9..000000000
--- a/src/class/vendor/vendor_host.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * SPDX-FileCopyrightText: Copyright (c) 2019 Ha Thach (tinyusb.org)
- * SPDX-License-Identifier: MIT
- *
- * This file is part of the TinyUSB stack.
- */
-
-#ifndef TUSB_VENDOR_HOST_H_
-#define TUSB_VENDOR_HOST_H_
-
-#include "common/tusb_common.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-typedef struct {
- pipe_handle_t pipe_in;
- pipe_handle_t pipe_out;
-}custom_interface_info_t;
-
-//--------------------------------------------------------------------+
-// USBH-CLASS DRIVER API
-//--------------------------------------------------------------------+
-static inline bool tusbh_custom_is_mounted(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id)
-{
- (void) vendor_id; // TODO check this later
- (void) product_id;
-// return (tusbh_device_get_mounted_class_flag(dev_addr) & TU_BIT(TUSB_CLASS_MAPPED_INDEX_END-1) ) != 0;
- return false;
-}
-
-bool tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length);
-bool tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length);
-
-//--------------------------------------------------------------------+
-// Internal Class Driver API
-//--------------------------------------------------------------------+
-void cush_init(void);
-bool cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length);
-void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event);
-void cush_close(uint8_t dev_addr);
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* TUSB_VENDOR_HOST_H_ */
diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c
index 3797e6b2b..770595178 100644
--- a/src/class/video/video_device.c
+++ b/src/class/video/video_device.c
@@ -1144,6 +1144,9 @@ static int handle_video_stm_cs_req(uint8_t rhport, uint8_t stage,
video_probe_and_commit_control_t *param = &stm->probe_commit_payload;
TU_VERIFY(_update_streaming_parameters(stm, param), VIDEO_ERROR_INVALID_VALUE_WITHIN_RANGE);
/* Set the negotiated value */
+ if (CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE < param->dwMaxPayloadTransferSize) {
+ param->dwMaxPayloadTransferSize = CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE;
+ }
stm->max_payload_transfer_size = param->dwMaxPayloadTransferSize;
int ret = tud_video_commit_cb(stm->index_vc, stm->index_vs, param);
if (VIDEO_ERROR_NONE == ret) {
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index b8d883dde..af43dfb12 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -126,6 +126,14 @@
#define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32
#endif
+ // Errata ERR050101, listed for RT1015/RT1020/RT1024/RT1050 (no fix scheduled) and for
+ // RT1060/RT1064 rev A (fixed in rev B); not listed for RT1010 or the RT11xx family.
+ #if defined(MIMXRT1015_SERIES) || defined(MIMXRT1021_SERIES) || defined(MIMXRT1024_SERIES) || \
+ defined(MIMXRT1051_SERIES) || defined(MIMXRT1052_SERIES) || defined(MIMXRT1061_SERIES) || \
+ defined(MIMXRT1062_SERIES) || defined(MIMXRT1064_SERIES)
+ #define CFG_TUSB_MIMXRT1XXX_ERRATA_ERR050101 1
+ #endif
+
#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K)
#define TUP_USBIP_CHIPIDEA_FS
#define TUP_USBIP_CHIPIDEA_FS_KINETIS
@@ -716,6 +724,14 @@
// Possible to share IN/OUT if only one direction is armed at any one time
#define CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY 1
+//--------------------------------------------------------------------+
+// Geehy
+//--------------------------------------------------------------------+
+#elif TU_CHECK_MCU(OPT_MCU_APM32F0XX)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_APM32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
+
#endif
// External USB controller
@@ -760,6 +776,17 @@
#define TUP_DCD_EDPT_ISO_ALLOC
#endif
+// Set by silicon whose isochronous IN endpoint can be unprimed by an IN token sent to that same
+// endpoint number on ANOTHER device sharing the host, taking one of this device's OUT endpoints
+// down with it - undetectable in software. Descriptors must then give an isochronous IN endpoint
+// a number no other device on the bus uses; a number is only safe while it stays unique, so two
+// affected boards on one hub must not pick the same one. Default 0 (no such conflict). Set it to
+// 0 by hand on RT1060/RT1064 rev B, which carry the fix - the revision cannot be told apart at
+// compile time, so the affected parts are assumed to be rev A.
+#ifndef CFG_TUSB_MIMXRT1XXX_ERRATA_ERR050101
+ #define CFG_TUSB_MIMXRT1XXX_ERRATA_ERR050101 0
+#endif
+
// Some USBIPs (SAMG, SAMX7X, PIC32, MAX3266x/MAX78002) cannot assign the same endpoint
// number to both IN and OUT. Default to 0 (same endpoint number may be used for IN and OUT).
#ifndef CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index d49d277ed..fa4d67df1 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -244,7 +244,7 @@ enum {
TUSB_DESC_CONFIG_ATT_SELF_POWERED = 1 << 6,
};
-#define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2)
+#define TUSB_DESC_CONFIG_POWER_MA(x) ((uint8_t)TU_MIN((x)/2, UINT8_MAX))
// USB 2.0 Spec Table 9-7: Test Mode Selectors
typedef enum {
diff --git a/src/device/dcd.h b/src/device/dcd.h
index f005e9620..a4006ae0c 100644
--- a/src/device/dcd.h
+++ b/src/device/dcd.h
@@ -20,19 +20,27 @@
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
+// Bus reset is reported as two edges. BUS_RESET_START is optional: a controller that
+// cannot tell the edges apart emits only BUS_RESET_END, which stays self-sufficient (it
+// performs the full teardown with or without a preceding START). Emit START when reset
+// signaling is detected - the link is unusable and the speed is not negotiated yet - so
+// the stack stops using endpoints immediately instead of at the end of the reset.
typedef enum {
- DCD_EVENT_INVALID = 0, // 0
- DCD_EVENT_BUS_RESET, // 1
- DCD_EVENT_UNPLUGGED, // 2
- DCD_EVENT_SOF, // 3
- DCD_EVENT_SUSPEND, // 4 TODO LPM Sleep L1 support
- DCD_EVENT_RESUME, // 5
- DCD_EVENT_SETUP_RECEIVED, // 6
- DCD_EVENT_XFER_COMPLETE, // 7
- USBD_EVENT_FUNC_CALL, // 8 Not an DCD event, just a convenient way to defer ISR function
+ DCD_EVENT_INVALID = 0, // 0
+ DCD_EVENT_BUS_RESET_START, // 1
+ DCD_EVENT_BUS_RESET_END, // 2 with negotiated speed
+ DCD_EVENT_UNPLUGGED, // 3
+ DCD_EVENT_SOF, // 4
+ DCD_EVENT_SUSPEND, // 5 TODO LPM Sleep L1 support
+ DCD_EVENT_RESUME, // 6
+ DCD_EVENT_SETUP_RECEIVED, // 7
+ DCD_EVENT_XFER_COMPLETE, // 8
+ USBD_EVENT_FUNC_CALL, // 9 Not an DCD event, just a convenient way to defer ISR function
DCD_EVENT_COUNT
} dcd_eventid_t;
+#define DCD_EVENT_BUS_RESET DCD_EVENT_BUS_RESET_END // backward compatibility
+
typedef struct TU_ATTR_ALIGNED(4) {
uint8_t rhport;
uint8_t event_id;
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 5471e132d..e84d72fa4 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -456,7 +456,8 @@ TU_ATTR_WEAK bool dcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
static char const *const _usbd_event_str[DCD_EVENT_COUNT] = {
"Invalid",
- "Bus Reset",
+ "Bus Reset Start",
+ "Bus Reset End",
"Unplugged",
"SOF",
"Suspend",
@@ -642,6 +643,8 @@ static void configuration_reset(uint8_t rhport) {
static void usbd_reset(uint8_t rhport) {
configuration_reset(rhport);
+ // discard any pre-reset SETUP still counted: a stale count skips post-reset SETUPs
+ _usbd_queued_setup = 0;
}
bool tud_task_event_ready(void) {
@@ -695,8 +698,15 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
#endif
switch (event.event_id) {
- case DCD_EVENT_BUS_RESET:
+ case DCD_EVENT_BUS_RESET_START:
+ TU_LOG_USBD("\r\n");
+ usbd_reset(event.rhport);
+ break;
+
+ case DCD_EVENT_BUS_RESET_END:
TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
+ // TODO a DCD that reports both edges pays for two teardowns: track a per-rhport
+ // "start seen" flag and skip this reset, keeping it for the single-event DCDs.
usbd_reset(event.rhport);
_usbd_dev.speed = event.bus_reset.speed;
break;
@@ -747,7 +757,14 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
_usbd_dev.ep_status[epnum][ep_dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
if (0 == epnum) {
- usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
+ // Not stalled on failure: a DCD refuses an EP0 prime when a newer setup is already
+ // latched, and EP0 stalls are cleared by hardware when that setup arrives - so a stall
+ // issued here lands after the auto-clear and would stall the transfer that superseded
+ // this one. The pending setup re-drives EP0 by itself.
+ if (!usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result,
+ event.xfer_complete.len)) {
+ TU_LOG_USBD(" Control stage not continued\r\n");
+ }
} else {
usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]);
TU_ASSERT(driver,);
@@ -865,10 +882,10 @@ bool tud_control_xfer(uint8_t rhport, const tusb_control_request_t* request, voi
if (ctrl_xfer->data_len > 0U) {
TU_ASSERT(buffer);
}
- TU_ASSERT(data_stage_xact(rhport));
+ TU_VERIFY(data_stage_xact(rhport));
} else {
// wLength == 0: Status stage is always IN per USB 2.0 §9.3.1
- TU_ASSERT(status_stage_xact(rhport, TU_EP0_IN));
+ TU_VERIFY(status_stage_xact(rhport, TU_EP0_IN));
}
return true;
@@ -919,7 +936,7 @@ static bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t
}
if (is_ok) {
- TU_ASSERT(status_stage_xact(rhport, ep_status));
+ TU_VERIFY(status_stage_xact(rhport, ep_status));
} else {
// Stall both IN and OUT control endpoint
dcd_edpt_stall(rhport, TU_EP0_OUT);
@@ -927,7 +944,7 @@ static bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t
}
} else {
// More data to transfer
- TU_ASSERT(data_stage_xact(rhport));
+ TU_VERIFY(data_stage_xact(rhport));
}
return true;
@@ -1473,8 +1490,18 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr)
break;
}
- if (send) {
- queue_event(event, in_isr);
+ if (send && !queue_event(event, in_isr)) {
+ // event dropped by a full queue: undo state that would otherwise wedge permanently
+ if (event->event_id == DCD_EVENT_SETUP_RECEIVED) {
+ // undo the increment, else every later SETUP is skipped as "other SETUP in queue"
+ // and EP0 is deaf until re-init
+ _usbd_queued_setup--;
+ } else if (event->event_id == DCD_EVENT_XFER_COMPLETE) {
+ // clear busy + claimed, else the endpoint can never be claimed or re-armed again
+ uint8_t const epnum = tu_edpt_number(event->xfer_complete.ep_addr);
+ uint8_t const ep_dir = tu_edpt_dir(event->xfer_complete.ep_addr);
+ _usbd_dev.ep_status[epnum][ep_dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
+ }
}
}
@@ -1588,10 +1615,12 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t
if (dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes, is_isr)) {
return true;
} else {
- // DCD error, mark endpoint as ready to allow next transfer
+ // Driver refused the transfer, mark endpoint as ready to allow next transfer. This is a
+ // recoverable condition (e.g. a new setup superseding a control response), not a bug, so
+ // do not break into the debugger - TU_BREAKPOINT() halts the CPU whenever a probe is
+ // attached, which on a test rig is always.
_usbd_dev.ep_status[epnum][dir] &= (uint8_t) ~(TU_EDPT_STATE_BUSY | TU_EDPT_STATE_CLAIMED);
TU_LOG_USBD("FAILED\r\n");
- TU_BREAKPOINT();
return false;
}
}
diff --git a/src/device/usbd.h b/src/device/usbd.h
index 9be12ed0a..2015d1869 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -229,7 +229,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
// Config number, interface count, string index, total length, attribute, power in mA
#define TUD_CONFIG_DESCRIPTOR(config_num, _itfcount, _stridx, _total_len, _attribute, _power_ma) \
- 9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, config_num, _stridx, TU_BIT(7) | _attribute, (_power_ma)/2
+ 9, TUSB_DESC_CONFIGURATION, U16_TO_U8S_LE(_total_len), _itfcount, config_num, _stridx, TU_BIT(7) | _attribute, (uint8_t)TU_MIN((_power_ma)/2, UINT8_MAX)
//--------------------------------------------------------------------+
// CDC Descriptor Templates
diff --git a/src/host/usbh.c b/src/host/usbh.c
index e307bb5e5..44819b016 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -306,17 +306,6 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
},
#endif
- #if CFG_TUH_VENDOR
- {
- .name = DRIVER_NAME("VENDOR"),
- .init = cush_init,
- .deinit = cush_deinit,
- .open = cush_open,
- .set_config = cush_set_config,
- .xfer_cb = cush_isr,
- .close = cush_close
- }
- #endif
};
// Additional class drivers implemented by application
diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
index f0f918fe2..8f0d6083e 100644
--- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
+++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
@@ -36,6 +36,9 @@ static const ci_hs_controller_t _ci_controller[] =
#define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base)
+// NXP recommends AHBBRST = INCR16 (remainder as unspecified-length bursts)
+#define CI_HS_SET_AHB_BURST(_p) (CI_HS_REG(_p)->SBUSCFG = SBUSCFG_AHBBRST_INCR16_UNSPEC)
+
//------------- DCD -------------//
#define CI_DCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum)
#define CI_DCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum)
diff --git a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h
index f2061bd7a..c7dc7e69f 100644
--- a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h
+++ b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h
@@ -34,4 +34,9 @@ static const ci_hs_controller_t _ci_controller[] =
#define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ ((IRQn_Type)_ci_controller[_p].irqnum)
#define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ((IRQn_Type)_ci_controller[_p].irqnum)
+// USB0 (high-speed) only: NXP recommends AHBBRST = INCR16 (remainder as
+// unspecified-length bursts)
+#define CI_HS_SET_AHB_BURST(_p) \
+ do { if ((_p) == 0) { CI_HS_REG(_p)->SBUSCFG = SBUSCFG_AHBBRST_INCR16_UNSPEC; } } while (0)
+
#endif
diff --git a/src/portable/chipidea/ci_hs/ci_hs_type.h b/src/portable/chipidea/ci_hs/ci_hs_type.h
index 70817a6e3..b3ef3b6af 100644
--- a/src/portable/chipidea/ci_hs/ci_hs_type.h
+++ b/src/portable/chipidea/ci_hs/ci_hs_type.h
@@ -29,6 +29,14 @@ enum {
USBCMD_INTR_THRESHOLD_MASK = 0x00FF0000u, // Interrupt Threshold bit 23:16
};
+// DEVICEADDR
+#define DEVICEADDR_USBADR_POS 25
+
+enum {
+ DEVICEADDR_USBADRA = TU_BIT(24), ///< Device Address Advance: stage USBADR until the next EP0 IN is ACKed
+ DEVICEADDR_USBADR_MASK = 0xFE000000u, ///< Device Address bit 31:25
+};
+
// PORTSC1
#define PORTSC1_PORT_SPEED_POS 26
@@ -36,10 +44,18 @@ enum {
PORTSC1_CURRENT_CONNECT_STATUS = TU_BIT(0),
PORTSC1_FORCE_PORT_RESUME = TU_BIT(6),
PORTSC1_SUSPEND = TU_BIT(7),
+ PORTSC1_PORT_RESET = TU_BIT(8), // read-only in device mode: a reset is being driven
PORTSC1_FORCE_FULL_SPEED = TU_BIT(24),
PORTSC1_PORT_SPEED = TU_BIT(26) | TU_BIT(27)
};
+// PORTSC1 PSPD field values, once shifted down by PORTSC1_PORT_SPEED_POS. 3 is undefined.
+enum {
+ PORTSC1_PORT_SPEED_FULL = 0,
+ PORTSC1_PORT_SPEED_LOW = 1,
+ PORTSC1_PORT_SPEED_HIGH = 2,
+};
+
// OTGSC
enum {
OTGSC_VBUS_DISCHARGE = TU_BIT(0),
@@ -71,11 +87,18 @@ enum {
USBMODE_VBUS_POWER_SELECT = TU_BIT(5), // Need to be enabled for LPC18XX/43XX in host mode
};
+// SBUSCFG
+enum {
+ SBUSCFG_AHBBRST_INCR16_UNSPEC = 7, // INCR16 burst, remainder as unspecified-length bursts
+};
+
// Device Registers
typedef struct
{
//------------- ID + HW Parameter Registers-------------//
- volatile uint32_t TU_RESERVED[64]; ///< For iMX RT10xx, but not used by LPC18XX/LPC43XX
+ volatile uint32_t TU_RESERVED[36]; ///< ID/HW parameter registers, not used by this driver
+ volatile uint32_t SBUSCFG; ///< System Bus Interface Configuration (not present on every MCU)
+ volatile uint32_t TU_RESERVED[27];
//------------- Capability Registers-------------//
volatile uint8_t CAPLENGTH; ///< Capability Registers Length
diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
index fa98d6882..f1c333280 100644
--- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
@@ -154,6 +154,14 @@ TU_VERIFY_STATIC(sizeof(dcd_qhd_t) == 64, "size is not correct");
#define QTD_NEXT_INVALID 0x01
+// Bounded spin for register waits. The longest legitimate wait is a flush held off by a packet
+// already in progress: ~50 us for a full-speed 64-byte packet, a low thousands of dependent
+// register reads, so healthy hardware never approaches this bound. Exceeding it means the
+// controller has stopped responding, and the spin then only serves to keep an ISR (or an
+// IRQ-masked caller) from hanging outright - the 3 ms reset-cleanup window of IMXRT1060RM 42.5.6.2.1 (p.2394)
+// is already unreachable in that state, and the manual's remedy there is a controller reset.
+#define CI_HS_BUSY_SPIN 10000u
+
typedef struct {
// Must be at 2K alignment
// Each endpoint with direction (IN/OUT) occupies a queue head
@@ -164,6 +172,17 @@ typedef struct {
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(2048) static dcd_data_t _dcd_data;
+// What the next Port Change Detect will be. Each one is preceded by the interrupt that causes it:
+// a reset interrupt for the end of a bus reset - where the speed first becomes final - or a
+// suspend interrupt for the resume that ends the suspend. A suspend itself raises no port change,
+// which is why there is no such value here. Indexed by rhport, which is 0 or 1 on every ci_hs
+// variant (NOT the controller count: mcx/rw61x map rhport 1 to controller 0).
+enum {
+ PORT_CHANGE_REASON_RESET = 0,
+ PORT_CHANGE_REASON_RESUME = 1,
+};
+static volatile uint8_t _port_change_reason[2];
+
//--------------------------------------------------------------------+
// Prototypes and Helper Functions
//--------------------------------------------------------------------+
@@ -172,12 +191,37 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t ci_ep_count(const ci_hs_regs_t *dcd_
return dcd_reg->DCCPARAMS & DCCPARAMS_DEN_MASK;
}
+static bool controller_reset(uint8_t rhport);
+
//--------------------------------------------------------------------+
// Controller API
//--------------------------------------------------------------------+
-/// follows LPC43xx User Manual 23.10.3
-static void bus_reset(uint8_t rhport) {
+// Flush endpoint buffers, following IMXRT1060RM 42.5.6.6.5 Flushing/De-priming an Endpoint
+// (p.2413): write ENDPTFLUSH, wait for the controller
+// to acknowledge, then confirm ENDPTSTAT went to zero. The controller refuses the flush when a
+// packet is in progress, and the manual requires the procedure be repeated until it takes.
+// Callers proceed regardless of the result; the bound only prevents an ISR-context hang on dead
+// hardware.
+static bool flush_endpoints(ci_hs_regs_t *dcd_reg, uint32_t mask) {
+ uint32_t guard = CI_HS_BUSY_SPIN;
+ do {
+ dcd_reg->ENDPTFLUSH = mask;
+ while (dcd_reg->ENDPTFLUSH & mask) {
+ if (!guard--) {
+ return false;
+ }
+ }
+ } while ((dcd_reg->ENDPTSTAT & mask) && guard--);
+
+ return !(dcd_reg->ENDPTSTAT & mask);
+}
+
+/// Everything the manual asks of the DCD when a reset is detected, in its order: clear the setup
+/// and completion semaphores, cancel every prime, check the reset is still being driven, and free
+/// the dTDs. All of it belongs inside the reset window (IMXRT1060RM 42.5.6.2.1, p.2394); nothing
+/// is left for the port change that ends the reset, which only reports the negotiated speed.
+static void bus_reset_begin(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
// The reset value for all endpoint types is the control endpoint. If one endpoint
@@ -193,17 +237,24 @@ static void bus_reset(uint8_t rhport) {
//------------- Clear All Registers -------------//
dcd_reg->ENDPTNAK = dcd_reg->ENDPTNAK;
dcd_reg->ENDPTNAKEN = 0;
- dcd_reg->USBSTS = dcd_reg->USBSTS;
dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;
dcd_reg->ENDPTCOMPLETE = dcd_reg->ENDPTCOMPLETE;
- while (dcd_reg->ENDPTPRIME) {}
- dcd_reg->ENDPTFLUSH = 0xFFFFFFFF;
- while (dcd_reg->ENDPTFLUSH) {}
+ uint32_t guard = CI_HS_BUSY_SPIN;
+ while (dcd_reg->ENDPTPRIME && guard--) {}
+ dcd_reg->ENDPTFLUSH = 0xFFFFFFFFUL;
- // read reset bit in portsc
+ // All of the above must land while the reset is still being driven - it lasts at least 3 ms.
+ // Arriving late leaves the controller in an undefined state, and the manual's remedy is to
+ // hardware-reset it. That clears Run/Stop, so the device detaches and the host will drive a
+ // fresh reset and enumeration - which is why nothing below this point is worth doing here.
+ if (!(dcd_reg->PORTSC1 & PORTSC1_PORT_RESET)) {
+ TU_LOG1("ci_hs: reset cleanup ran past the end of the reset, resetting controller\r\n");
+ controller_reset(rhport);
+ return; // the controller detached; the host's next reset redoes everything below
+ }
- //------------- Queue Head & Queue TD -------------//
+ //------------- Free all allocated dTDs: the controller will not execute them again -------------//
tu_memclr(&_dcd_data, sizeof(dcd_data_t));
//------------- Set up Control Endpoints (0 OUT, 1 IN) -------------//
@@ -216,27 +267,29 @@ static void bus_reset(uint8_t rhport) {
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
}
-bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
- (void)rh_init;
- tu_memclr(&_dcd_data, sizeof(dcd_data_t));
-
+/// Reset the controller and bring it back up in device mode. Also the manual's remedy when the
+/// reset cleanup misses its window: the controller reset clears Run/Stop and detaches the device,
+/// so it must be re-initialised completely afterwards (IMXRT1060RM 42.5.6.2.1, p.2394).
+static bool controller_reset(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
- TU_ASSERT(ci_ep_count(dcd_reg) <= TUP_DCD_ENDPOINT_MAX);
-
- #if TU_CHECK_MCU(OPT_MCU_HPM)
- usb_phy_init((USB_Type *)dcd_reg, false);
- #endif
+ tu_memclr(&_dcd_data, sizeof(dcd_data_t));
// Reset controller
dcd_reg->USBCMD |= USBCMD_RESET;
- while (dcd_reg->USBCMD & USBCMD_RESET) {}
+ uint32_t guard = CI_HS_BUSY_SPIN;
+ while ((dcd_reg->USBCMD & USBCMD_RESET) && guard--) {}
+ TU_VERIFY(!(dcd_reg->USBCMD & USBCMD_RESET)); // reached from the ISR too, so never halt here
// Set mode to device, must be set immediately after reset
uint32_t usbmode = dcd_reg->USBMODE & ~USBMOD_CM_MASK;
usbmode |= USBMODE_CM_DEVICE;
dcd_reg->USBMODE = usbmode;
+ #ifdef CI_HS_SET_AHB_BURST
+ CI_HS_SET_AHB_BURST(rhport);
+ #endif
+
#ifdef CFG_TUD_CI_HS_VBUS_CHARGE
dcd_reg->OTGSC = OTGSC_VBUS_CHARGE | OTGSC_OTG_TERMINATION;
#else
@@ -253,9 +306,11 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
+ _port_change_reason[rhport] = PORT_CHANGE_REASON_RESET;
+
dcd_reg->ENDPTLISTADDR = (uint32_t)_dcd_data.qhd; // Endpoint List Address has to be 2K alignment
dcd_reg->USBSTS = dcd_reg->USBSTS;
- dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_SUSPEND;
+ dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND;
uint32_t usbcmd = dcd_reg->USBCMD;
usbcmd &= ~USBCMD_INTR_THRESHOLD_MASK; // Interrupt Threshold Interval = 0
@@ -266,8 +321,22 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
return true;
}
+bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
+ (void)rh_init;
+ ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
+
+ TU_ASSERT(ci_ep_count(dcd_reg) <= TUP_DCD_ENDPOINT_MAX);
+
+ #if TU_CHECK_MCU(OPT_MCU_HPM)
+ usb_phy_init((USB_Type *)dcd_reg, false);
+ #endif
+
+ return controller_reset(rhport);
+}
+
bool dcd_deinit(uint8_t rhport) {
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
+ _port_change_reason[rhport] = PORT_CHANGE_REASON_RESET;
// disable all interrupt
dcd_reg->USBINTR = 0;
@@ -276,9 +345,9 @@ bool dcd_deinit(uint8_t rhport) {
dcd_reg->USBCMD &= ~USBCMD_RUN_STOP;
// flush all endpoints
- while (dcd_reg->ENDPTPRIME) {}
- dcd_reg->ENDPTFLUSH = 0xFFFFFFFF;
- while (dcd_reg->ENDPTFLUSH) {}
+ uint32_t guard = CI_HS_BUSY_SPIN;
+ while (dcd_reg->ENDPTPRIME && guard--) {}
+ flush_endpoints(dcd_reg, 0xFFFFFFFF);
return true;
}
@@ -292,11 +361,18 @@ void dcd_int_disable(uint8_t rhport) {
}
void dcd_set_address(uint8_t rhport, uint8_t dev_addr) {
- // Response with status first before changing device address
- dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false);
+ ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
+ const uint32_t prev = dcd_reg->DEVICEADDR & DEVICEADDR_USBADR_MASK;
- ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
- dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24);
+ // IMXRT1060RM 42.7.23 / UM10503 Table 478: stage the address before priming the status stage so
+ // hardware loads USBADR at the status ACK. Priming first races that ACK against this write.
+ dcd_reg->DEVICEADDR = ((uint32_t)dev_addr << DEVICEADDR_USBADR_POS) | DEVICEADDR_USBADRA;
+
+ if (!dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false)) {
+ // USB 2.0 9.4.6: the address changes only after the status stage completes successfully. The
+ // status never went out, so drop the stage - USBADRA=0 takes effect instantly.
+ dcd_reg->DEVICEADDR = prev;
+ }
}
void dcd_remote_wakeup(uint8_t rhport) {
@@ -464,9 +540,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep)
// dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
// Flush EP
- const uint32_t flush_mask = TU_BIT(epnum + (dir ? 16 : 0));
- dcd_reg->ENDPTFLUSH = flush_mask;
- while (dcd_reg->ENDPTFLUSH & flush_mask) {}
+ flush_endpoints(dcd_reg, TU_BIT(epnum + (dir ? 16 : 0)));
// disable to change max packet size
ep_ctrl_clear(endptctrl, dir, ENDPTCTRL_ENABLE);
@@ -492,7 +566,7 @@ void dcd_edpt_close_all(uint8_t rhport) {
}
}
-static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) {
+static bool qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir];
@@ -505,13 +579,22 @@ static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) {
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
if (epnum == 0) {
- // follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism
- // wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
- while (dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {}
+ // Setup lockout (IMXRT1060RM 42.5.6.4.2.1 Setup Phase, p.2403): never prime EP0 while a new
+ // SETUP is pending. The ISR
+ // normally consumes ENDPTSETUPSTAT quickly; if the guard trips, fail the transfer so usbd
+ // releases the endpoint (a pending SETUP supersedes this response anyway; without one, usbd
+ // stalls EP0 and the host recovers with a fresh control transfer).
+ uint32_t guard = CI_HS_BUSY_SPIN;
+ while (dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {
+ if (!guard--) {
+ return false;
+ }
+ }
}
// start transfer
dcd_reg->ENDPTPRIME = TU_BIT(epnum + (dir ? 16 : 0));
+ return true;
}
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) {
@@ -527,9 +610,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
// Start qhd transfer
p_qhd->ff = NULL;
- qhd_start_xfer(rhport, epnum, dir);
-
- return true;
+ return qhd_start_xfer(rhport, epnum, dir);
}
#if !CFG_TUD_MEM_DCACHE_ENABLE
@@ -580,9 +661,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t
// Start qhd transfer
p_qhd->ff = ff;
- qhd_start_xfer(rhport, epnum, dir);
-
- return true;
+ return qhd_start_xfer(rhport, epnum, dir);
}
#endif
@@ -630,43 +709,43 @@ void dcd_int_handler(uint8_t rhport) {
return;
}
- // Set if the port controller enters the full or high-speed operational state.
- // either from Bus Reset or Suspended state
- if (int_status & INTR_PORT_CHANGE) {
- // TU_LOG2("PortChange %08lx\r\n", dcd_reg->PORTSC1);
+ const uint8_t pci_reason = _port_change_reason[rhport]; // save current pci_reason
- // Reset interrupt is not enabled, we manually check if Port Change is due
- // to connection / disconnection
- if (dcd_reg->USBSTS & INTR_RESET) {
- dcd_reg->USBSTS = INTR_RESET;
-
- if (dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) {
- const uint32_t speed = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS;
- bus_reset(rhport);
- dcd_event_bus_reset(rhport, (tusb_speed_t)speed, true);
- } else {
- dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
- }
- } else {
- // Triggered by resuming from suspended state
- if (!(dcd_reg->PORTSC1 & PORTSC1_SUSPEND)) {
- dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
- }
- }
+ if (int_status & INTR_SUSPEND) {
+ _port_change_reason[rhport] = PORT_CHANGE_REASON_RESUME; // next PCI is resume
+ dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
}
- if (int_status & INTR_SUSPEND) {
- // TU_LOG2("Suspend %08lx\r\n", dcd_reg->PORTSC1);
+ // USB Reset Received: register cleanup runs here within the reset window (IMXRT1060RM 42.5.6.2.1, p.2394)
+ // and BUS_RESET_START fires now; BUS_RESET_END, with the final speed, is triggered later by PCI.
+ if (int_status & INTR_RESET) {
+ _port_change_reason[rhport] = PORT_CHANGE_REASON_RESET;
+ bus_reset_begin(rhport);
+ dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET_START, true);
+ }
- if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) {
- // Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration.
- // Skip suspend event if we are not addressed
- if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) {
- dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
- }
+ // Port entered the full/high-speed operational state: the end of a bus reset, or a resume.
+ if (int_status & INTR_PORT_CHANGE) {
+ if (pci_reason == PORT_CHANGE_REASON_RESUME) {
+ dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
+ } else {
+ // the undefined encoding falls back to full speed
+ const uint32_t pspd = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS;
+ const tusb_speed_t speed = (pspd == PORTSC1_PORT_SPEED_LOW) ? TUSB_SPEED_LOW :
+ (pspd == PORTSC1_PORT_SPEED_HIGH) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL;
+ dcd_event_bus_reset(rhport, speed, true);
+ // This reset is over, so the next port change is a resume. Leaving it at RESET instead would
+ // dispatch every later resume as another end-of-reset, clearing the queue heads mid-session.
+ _port_change_reason[rhport] = PORT_CHANGE_REASON_RESUME;
}
}
+ // No unplug detection yet, by the manual rather than by omission: IMXRT1060RM 42.7.31 (p.2470) says a zero
+ // Current Connect Status means the device "did not attach successfully or was forcibly
+ // disconnected by the software writing a zero to the Run bit ... It does not state the device
+ // being disconnected or suspended", so a cable pull raises no port change at all. VBUS via
+ // OTGSC BSV is the manual's disconnect indicator, and it is board dependent.
+
if (int_status & INTR_USB) {
// Make sure we read the latest version of _dcd_data.
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
@@ -674,7 +753,7 @@ void dcd_int_handler(uint8_t rhport) {
const uint32_t edpt_complete = dcd_reg->ENDPTCOMPLETE;
dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge
- // 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set
+ // 42.5.6.6.4 Transfer Completion (p.2413): a failed dTD also sets ENDPTCOMPLETE
// nothing to do, we will submit xfer as error to usbd
// if (int_status & INTR_ERROR) { }
@@ -690,12 +769,39 @@ void dcd_int_handler(uint8_t rhport) {
}
// Set up Received
- // 23.10.10.2 Operational model for setup transfers
+ // 42.5.6.4.2 Control Endpoint Operation Model (p.2403)
// Must be after normal transfer complete since it is possible to have both previous control status + new setup
// in the same frame and we should handle previous status first.
if (dcd_reg->ENDPTSETUPSTAT) {
+ // 42.5.6.4.2.1 Setup Phase (p.2403) steps 1-2: duplicate the setup payload BEFORE clearing
+ // ENDPTSETUPSTAT -
+ // the clear releases the setup lockout and a back-to-back SETUP (usbtest case 10) can
+ // overwrite the queue-head buffer immediately after. The copy is read through the volatile
+ // qualifier rather than memcpy'd because C orders volatile accesses only against each
+ // other: a plain copy may legally be sunk past the lockout-releasing store below.
+ union {
+ tusb_control_request_t request;
+ uint8_t byte[8];
+ } setup;
+ const volatile uint8_t *setup_src = (const volatile uint8_t *)&_dcd_data.qhd[0][0].setup_request;
+ for (uint8_t i = 0; i < sizeof(setup.request); i++) {
+ setup.byte[i] = setup_src[i];
+ }
dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;
- dcd_event_setup_received(rhport, (uint8_t *)(uintptr_t)&_dcd_data.qhd[0][0].setup_request, true);
+
+ // Retire a status/handshake phase left primed by the previous control sequence
+ // (IMXRT1060RM 42.5.6.4.2.1, p.2403), which would otherwise retire the response the task is about to
+ // prime for this setup. Skipped when EP0 has nothing primed or priming, since the manual
+ // does not want the flush wait in an interrupt handler when it has nothing to do.
+ // One volatile read per statement: C leaves their order unspecified within a single
+ // expression, which IAR rejects outright (Pa082).
+ const uint32_t ep0_mask = TU_BIT(0) | TU_BIT(16);
+ const uint32_t ep0_stat = dcd_reg->ENDPTSTAT;
+ const uint32_t ep0_prime = dcd_reg->ENDPTPRIME;
+ if ((ep0_stat | ep0_prime) & ep0_mask) {
+ flush_endpoints(dcd_reg, ep0_mask);
+ }
+ dcd_event_setup_received(rhport, setup.byte, true);
}
}
diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
index 3cb69acfa..0f24f5bb6 100644
--- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
@@ -82,6 +82,10 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
hcd_reg->USBMODE = USBMODE_CM_HOST;
#endif
+ #ifdef CI_HS_SET_AHB_BURST
+ CI_HS_SET_AHB_BURST(rhport);
+ #endif
+
#if !TUH_OPT_HIGH_SPEED
hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
#endif
diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
index d5b03e4b1..42f6750b1 100644
--- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
+++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
@@ -87,6 +87,10 @@ enum {
DEVCMDSTAT_SUSPEND_CHANGE_MASK = TU_BIT(25),
DEVCMDSTAT_RESET_CHANGE_MASK = TU_BIT(26),
DEVCMDSTAT_VBUS_DEBOUNCED_MASK = TU_BIT(28),
+
+ // write-1-to-clear latches
+ DEVCMDSTAT_W1C_MASK = DEVCMDSTAT_SETUP_RECEIVED_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK |
+ DEVCMDSTAT_SUSPEND_CHANGE_MASK | DEVCMDSTAT_RESET_CHANGE_MASK,
};
enum {
@@ -171,7 +175,9 @@ typedef struct
ep_cmd_sts_t ep[2*MAX_EP_PAIRS][2];
xfer_dma_t dma[2*MAX_EP_PAIRS];
- TU_ATTR_ALIGNED(64) uint8_t setup_packet[8];
+ // volatile: the controller DMAs a new setup packet into this buffer as soon as the SETUP
+ // latch is cleared, so reads of it must stay ordered against the register accesses around them
+ TU_ATTR_ALIGNED(64) volatile uint8_t setup_packet[8];
}dcd_data_t;
// EP list must be 256-byte aligned
@@ -180,8 +186,12 @@ typedef struct
// Use CFG_TUD_MEM_SECTION to place it accordingly.
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd;
-// Dummy buffer to fix ZLPs overwriting the buffer (probably an USB/DMA controller bug)
-// TODO find way to save memory
+// Dummy buffer to fix ZLPs overwriting the buffer: Errata LPC55S6x USB.5 / LPC55S2x USB.4 - the
+// HS device controller always DMA-writes OUT data in 8-byte units, so up to 7 bytes land past the
+// received length. This redirects the ZLP case; the general short-OUT case is unhandled here
+// (TinyUSB's own endpoint buffers are sized/aligned so the spill stays inside them, but a tight
+// caller buffer can be overrun by up to 7 bytes - the SDK's documented workaround is a bounce
+// buffer). TODO find way to save memory
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
//--------------------------------------------------------------------+
@@ -221,7 +231,7 @@ static const dcd_controller_t _dcd_controller[] = {
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-TU_ATTR_ALWAYS_INLINE static inline uint16_t get_buf_offset(void const * buffer) {
+TU_ATTR_ALWAYS_INLINE static inline uint16_t get_buf_offset(void const volatile * buffer) {
uint32_t addr = (uint32_t) buffer;
TU_ASSERT( (addr & 0x3f) == 0, 0 );
return ( (addr >> 6) & 0xFFFFUL ) ;
@@ -247,6 +257,16 @@ TU_ATTR_ALWAYS_INLINE static inline bool rhport_is_highspeed(uint8_t rhport) {
return _dcd_controller[rhport].is_highspeed;
}
+
+// DEVCMDSTAT mixes RW fields with write-1-to-clear latches (SETUP + the 3 change bits): a blind
+// RMW writes a pending latch back as 1 and silently clears it (a SETUP eaten this way strands
+// EP0). Mask the latches on every update; pass one in set_mask only to clear it.
+TU_ATTR_ALWAYS_INLINE static inline void devcmdstat_update(dcd_registers_t* dcd_reg,
+ uint32_t clear_mask, uint32_t set_mask) {
+ const uint32_t v = dcd_reg->DEVCMDSTAT & ~(DEVCMDSTAT_W1C_MASK | clear_mask);
+ dcd_reg->DEVCMDSTAT = v | set_mask;
+}
+
//--------------------------------------------------------------------+
// CONTROLLER API
//--------------------------------------------------------------------+
@@ -284,8 +304,10 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
dcd_reg->DATABUFSTART = tu_align((uint32_t) &_dcd, TU_BIT(22)); // 22-bit alignment
dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt
dcd_reg->INTEN = INT_DEVICE_STATUS_MASK;
- dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_ENABLE_MASK | DEVCMDSTAT_DEVICE_CONNECT_MASK |
- DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK;
+ // deliberately clear every latch (incl. a SETUP left by a bootloader/warm start) for a
+ // deterministic init state
+ devcmdstat_update(dcd_reg, 0, DEVCMDSTAT_DEVICE_ENABLE_MASK | DEVCMDSTAT_DEVICE_CONNECT_MASK |
+ DEVCMDSTAT_W1C_MASK);
NVIC_ClearPendingIRQ(_dcd_controller[rhport].irqnum);
@@ -309,8 +331,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
// Response with status first before changing device address
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false);
- dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_ADDR_MASK;
- dcd_reg->DEVCMDSTAT |= dev_addr;
+ devcmdstat_update(dcd_reg, DEVCMDSTAT_DEVICE_ADDR_MASK, dev_addr);
}
void dcd_remote_wakeup(uint8_t rhport)
@@ -321,13 +342,13 @@ void dcd_remote_wakeup(uint8_t rhport)
void dcd_connect(uint8_t rhport)
{
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
- dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_DEVICE_CONNECT_MASK;
+ devcmdstat_update(dcd_reg, 0, DEVCMDSTAT_DEVICE_CONNECT_MASK);
}
void dcd_disconnect(uint8_t rhport)
{
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
- dcd_reg->DEVCMDSTAT &= ~DEVCMDSTAT_DEVICE_CONNECT_MASK;
+ devcmdstat_update(dcd_reg, DEVCMDSTAT_DEVICE_CONNECT_MASK, 0);
}
void dcd_sof_enable(uint8_t rhport, bool en)
@@ -380,9 +401,17 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
uint8_t const ep_id = ep_addr2id(ep_addr);
+ // Preserve rf_tv: for non-control endpoints it is a TYPE bit, not the toggle value (UM11126:
+ // T=1 + RF 1/0 = interrupt/iso). Zeroing it here turned HS periodic interrupt endpoints into
+ // isochronous - no handshake on OUT, dead IN (usbtest cases 25/26 on lpc55 HS port).
+ // TODO implement the Errata LPC546xx USB.13 work-around (same semantics in UM11126): with RF/TV preserved at 1, TR
+ // loads the toggle from TV, so an HS interrupt endpoint restarts on DATA1 after clear-halt and
+ // the host discards one packet as a retransmission. The documented workaround needs an
+ // interrupt-on-NAK state machine (park as generic TR=1/TV=0, wait for a NAKed token to latch
+ // toggle 0 via EPTOGGLE, restore the type) - deferred; one lost packet beats the fully broken
+ // endpoint the old rf_tv clear caused.
_dcd.ep[ep_id][0].cmd_sts.stall = 0;
_dcd.ep[ep_id][0].cmd_sts.toggle_reset = 1;
- _dcd.ep[ep_id][0].cmd_sts.rf_tv = 0;
}
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
@@ -432,7 +461,7 @@ void dcd_edpt_close_all (uint8_t rhport)
{
for (uint8_t ep_id = 0; ep_id < 2*_dcd_controller[rhport].ep_pairs; ++ep_id)
{
- _dcd.ep[ep_id][0].cmd_sts.active = _dcd.ep[ep_id][0].cmd_sts.active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual)
+ _dcd.ep[ep_id][0].cmd_sts.active = _dcd.ep[ep_id][1].cmd_sts.active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual)
_dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1;
}
}
@@ -538,7 +567,7 @@ static void bus_reset(uint8_t rhport)
dcd_reg->EPSKIP = 0xFFFFFFFF;
dcd_reg->INTSTAT = dcd_reg->INTSTAT; // clear all pending interrupt
- dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK; // clear setup received interrupt
+ devcmdstat_update(dcd_reg, 0, DEVCMDSTAT_SETUP_RECEIVED_MASK); // clear setup received interrupt
dcd_reg->INTEN = INT_DEVICE_STATUS_MASK | TU_BIT(0) | TU_BIT(1); // enable device status & control endpoints
}
@@ -597,18 +626,25 @@ void dcd_int_handler(uint8_t rhport)
{
dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs;
- uint32_t const cmd_stat = dcd_reg->DEVCMDSTAT;
-
uint32_t int_status = dcd_reg->INTSTAT;
- int_status &= dcd_reg->INTEN;
+ int_status &= dcd_reg->INTEN;
dcd_reg->INTSTAT = int_status; // Acknowledge handled interrupt
if (int_status == 0) return;
+ // Snapshot after the INTSTAT ack: latch bits persist (RWC) so nothing is lost, while the reverse
+ // order could consume INTSTAT bit0 for a SETUP not yet visible in the snapshot - stranding the
+ // SETUP (INTSTAT is edge-latched) and feeding bit0 to process_xfer_isr as a bogus completion.
+ uint32_t const cmd_stat = dcd_reg->DEVCMDSTAT;
+
//------------- Device Status -------------//
if ( int_status & INT_DEVICE_STATUS_MASK )
{
- dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK;
+ // clear only the change latches observed in the snapshot: one latched by hardware between the
+ // snapshot and this write would be acknowledged unseen (its DEV_INT re-latches and dispatches
+ // next pass instead)
+ devcmdstat_update(dcd_reg, 0, cmd_stat &
+ (DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK));
if ( cmd_stat & DEVCMDSTAT_RESET_CHANGE_MASK) // bus reset
{
@@ -653,15 +689,43 @@ void dcd_int_handler(uint8_t rhport)
_dcd.ep[0][0].cmd_sts.active = _dcd.ep[1][0].cmd_sts.active = 0;
_dcd.ep[0][0].cmd_sts.stall = _dcd.ep[1][0].cmd_sts.stall = 0;
- dcd_reg->DEVCMDSTAT |= DEVCMDSTAT_SETUP_RECEIVED_MASK;
+ // UM flow: ack the latch FIRST, then read the payload. This IP has no setup lockout, so a
+ // back-to-back SETUP can overwrite _dcd.setup_packet at any time - but with the latch already
+ // released, any such overwrite re-latches SETUP_RECEIVED and is redelivered (worst case a
+ // superseded duplicate, absorbed by usbd's queued-setup counter). The reverse order can
+ // consume the newer SETUP's latch unseen and lose it.
+ devcmdstat_update(dcd_reg, 0, DEVCMDSTAT_SETUP_RECEIVED_MASK);
+
+ // UM11126 Fig 163 (control EP0 flowchart) requires clearing the EP0IN interrupt here: a
+ // control IN completion latched before this SETUP must not reach usbd after it, where it
+ // would be applied to the new request and arm its status stage early. EP0OUT goes with it -
+ // bit0 is set by SETUP reception too, and left set it would replay next pass as a phantom
+ // completion. Neither can discard live work: the SETUP latch NAKs all EP0 traffic until the
+ // update above, and both EP0 Active bits were cleared a few lines up.
+ dcd_reg->INTSTAT = TU_BIT(0) | TU_BIT(1);
- dcd_event_setup_received(rhport, _dcd.setup_packet, true);
+ // Copied a byte at a time rather than with memcpy: C orders volatile accesses only against
+ // each other, so a non-volatile copy of this buffer may be sunk below the guard read that
+ // follows - gcc does exactly that at -O2 and -O3, leaving only -Os correct.
+ uint8_t setup_copy[8];
+ for (uint8_t i = 0; i < sizeof(setup_copy); i++) {
+ setup_copy[i] = _dcd.setup_packet[i];
+ }
+
+ // a SETUP that raced in after the acks (its bit0 consumed above) makes this copy suspect:
+ // its latch is visible again, so re-raise the endpoint interrupt and let the next pass
+ // deliver the newer payload rather than passing up bytes that may be torn between the two
+ if (dcd_reg->DEVCMDSTAT & DEVCMDSTAT_SETUP_RECEIVED_MASK) {
+ dcd_reg->INTSETSTAT = TU_BIT(0);
+ } else {
+ dcd_event_setup_received(rhport, setup_copy, true);
+ }
// keep waiting for next setup
prepare_setup_packet(rhport);
- // clear bit0
- int_status = tu_bit_clear(int_status, 0);
+ // drop both EP0 bits: acked above, and neither belongs to the request this SETUP starts
+ int_status &= ~(TU_BIT(0) | TU_BIT(1));
}
// Endpoint transfer complete interrupt
diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c
index e2c5956b3..2a174e46c 100644
--- a/src/portable/ohci/ohci.c
+++ b/src/portable/ohci/ohci.c
@@ -378,7 +378,7 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr) {
ohci_ed_t* p_prev = p_head;
while (p_prev->next) {
- ohci_ed_t* ed = (ohci_ed_t*)_virt_addr((void*)p_prev->next);
+ ohci_ed_t* ed = hcd_dcache_uncached((ohci_ed_t*)_virt_addr((void*)p_prev->next));
if (ed->w0.dev_addr == dev_addr) {
// Prevent Host Controller from processing this ED while we remove it
@@ -387,12 +387,28 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr) {
// unlink ed, will also move up p_prev
p_prev->next = ed->next;
- // point the removed ED's next pointer to list head to make sure HC can always safely move away from this ED
- ed->next = (uint32_t)_phys_addr(p_head);
- ed->w0.used = 0;
- ed->w0.skip = 0;
+ // Control endpoints (EP number 0) are statically allocated with the device which are only reused
+ // after connection of another device long after HC has finished with them now, these can be freed immediately.
+ if (ed->w0.ep_number != 0) {
+ // Wait until the next frame before reclaiming the ED and its TDs. Set the deadline before
+ // publishing is_reclaiming so a pending SOF IRQ cannot use an older deadline for this ED.
+ ohci_data.reclaim_frame = (uint16_t)(OHCI_REG->frame_number + 1);
+ ed->w0.is_reclaiming = 1;
+
+ // 5.2.7.1.2 Removing. Disable list processing for bulk
+ if (p_head == p_ed_head[TUSB_XFER_BULK]) {
+ OHCI_REG->control &= ~OHCI_CONTROL_LIST_BULK_ENABLE_MASK;
+ }
+
+ // Temporarily enable SOF IRQ. Clear any pending SOF first to wait for the next frame.
+ OHCI_REG->interrupt_status = OHCI_INT_SOF_MASK;
+ OHCI_REG->interrupt_enable = OHCI_INT_SOF_MASK;
+ } else {
+ ed->w0.used = 0;
+ ed->w0.skip = 0;
+ }
} else {
- p_prev = (ohci_ed_t*)_virt_addr((void*)p_prev->next);
+ p_prev = ed;
}
}
}
@@ -400,6 +416,7 @@ static void ed_list_remove_by_addr(ohci_ed_t * p_head, uint8_t dev_addr) {
static ohci_gtd_t* gtd_find_free(void) {
for (uint8_t i = 0; i < GTD_MAX; i++) {
if (!ohci_data.gtd_pool[i].used) {
+ ohci_data.gtd_pool[i].used = 1;
return &ohci_data.gtd_pool[i];
}
}
@@ -652,6 +669,60 @@ void hcd_int_handler(uint8_t hostid, bool in_isr) {
// Disable MIE as per OHCI spec 5.3
OHCI_REG->interrupt_disable = OHCI_INT_MASTER_ENABLE_MASK;
+ // Start of frame (SOF). Signed subtraction handles frame number rollover and delayed interrupts.
+ if ((int_status & OHCI_INT_SOF_MASK) &&
+ ((int16_t)((uint16_t)OHCI_REG->frame_number - ohci_data.reclaim_frame) >= 0)) {
+ OHCI_REG->interrupt_disable = OHCI_INT_SOF_MASK;
+
+ bool re_enable_lists = false;
+
+ for (size_t i = 0; i < ED_MAX; i++) {
+ ohci_ed_t* ed = hcd_dcache_uncached(&ohci_data.ed_pool[i]);
+ if (ed->w0.used && ed->w0.is_reclaiming) {
+ TU_ASSERT(ed->w0.skip == 1, );
+ TU_ASSERT(ed->w0.ep_number != 0, );
+
+ // Reclaim orphaned TDs
+ uint32_t td_addr = ed->td_head.address & ~0x0F;
+ while (td_addr) {
+ if (!ed->w0.is_iso) {
+ ohci_gtd_t *gtd = (ohci_gtd_t*)_virt_addr((void*)(uintptr_t)td_addr);
+ gtd->used = 0;
+ } else {
+ // TODO: Free ITD once implemented
+ }
+
+ if (td_addr == ed->td_tail) {
+ break;
+ }
+ td_addr = ((ohci_td_item_t*)_virt_addr((void*)(uintptr_t)td_addr))->next;
+ }
+
+ ed->w0.is_reclaiming = 0;
+ ed->w0.used = 0;
+ ed->w0.skip = 0;
+
+ re_enable_lists = true;
+ }
+ }
+
+ if (re_enable_lists) {
+ // 5.2.7.1.2 Removing
+ // Reset current ED pointers and re-enable lists
+ // Once the next frame has started, the HcControlCurrentED or HcBulkCurrentED register should be adjusted so
+ // that it does not point to the Endpoint Descriptor being removed (for simplicity you may just write
+ // a zero to the register);
+ if (!(OHCI_REG->control & OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK)) {
+ OHCI_REG->control_current_ed = 0;
+ OHCI_REG->control |= OHCI_CONTROL_LIST_CONTROL_ENABLE_MASK;
+ }
+ if (!(OHCI_REG->control & OHCI_CONTROL_LIST_BULK_ENABLE_MASK)) {
+ OHCI_REG->bulk_current_ed = 0;
+ OHCI_REG->control |= OHCI_CONTROL_LIST_BULK_ENABLE_MASK;
+ }
+ }
+ }
+
// Frame number overflow
if (int_status & OHCI_INT_FRAME_OVERFLOW_MASK) {
ohci_data.frame_number_hi++;
diff --git a/src/portable/ohci/ohci.h b/src/portable/ohci/ohci.h
index 84ae04b0f..e28c6404f 100644
--- a/src/portable/ohci/ohci.h
+++ b/src/portable/ohci/ohci.h
@@ -107,7 +107,8 @@ typedef union {
// HCD: make use of 5 reserved bits
uint32_t used : 1;
uint32_t is_interrupt_xfer : 1;
- uint32_t : 3;
+ uint32_t is_reclaiming : 1;
+ uint32_t : 2;
};
uint32_t value;
} ohci_ed_word0_t;
@@ -182,6 +183,7 @@ typedef struct TU_ATTR_ALIGNED(256) {
gtd_extra_data_t gtd_extra[GTD_MAX];
volatile uint16_t frame_number_hi;
+ volatile uint16_t reclaim_frame;
} ohci_data_t;
//--------------------------------------------------------------------+
diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
index a0d312b8f..564ded535 100644
--- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
@@ -387,6 +387,9 @@ bool dcd_deinit(uint8_t rhport) {
reset_block(RESETS_RESET_USBCTRL_BITS);
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
+ // Release allocated resources
+ rp2usb_deinit();
+
return true;
}
diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
index 28dc7f93c..a04890835 100644
--- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
@@ -427,6 +427,10 @@ bool hcd_deinit(uint8_t rhport) {
irq_remove_handler(USBCTRL_IRQ, hcd_rp2040_irq);
reset_block(RESETS_RESET_USBCTRL_BITS);
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
+
+ // Release allocated resources
+ rp2usb_deinit();
+
return true;
}
diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c
index 5421b9b2b..96b335bd3 100644
--- a/src/portable/raspberrypi/rp2040/rp2040_usb.c
+++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c
@@ -85,6 +85,10 @@ void rp2usb_init(void) {
critical_section_init(&rp2usb_lock);
}
+void rp2usb_deinit(void) {
+ critical_section_deinit(&rp2usb_lock);
+}
+
void __tusb_irq_path_func(rp2usb_reset_transfer)(hw_endpoint_t *ep) {
ep->state = EPSTATE_IDLE;
ep->remaining_len = 0;
diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.h b/src/portable/raspberrypi/rp2040/rp2040_usb.h
index f4e85764d..e5a54007c 100644
--- a/src/portable/raspberrypi/rp2040/rp2040_usb.h
+++ b/src/portable/raspberrypi/rp2040/rp2040_usb.h
@@ -147,6 +147,7 @@ extern volatile uint32_t e15_last_sof;
#endif
void rp2usb_init(void);
+void rp2usb_deinit(void);
// if usb hardware is in host mode
TU_ATTR_ALWAYS_INLINE static inline bool rp2usb_is_host_mode(void) {
diff --git a/src/portable/st/stm32_fsdev/fsdev_apm32.h b/src/portable/st/stm32_fsdev/fsdev_apm32.h
new file mode 100644
index 000000000..5031445e8
--- /dev/null
+++ b/src/portable/st/stm32_fsdev/fsdev_apm32.h
@@ -0,0 +1,77 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024, hathach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#ifndef TUSB_FSDEV_APM32_H
+#define TUSB_FSDEV_APM32_H
+
+#include "common/tusb_compiler.h"
+
+#if CFG_TUSB_MCU == OPT_MCU_APM32F0XX
+ #include "apm32f0xx.h"
+#endif
+
+#define FSDEV_USE_SBUF_ISO 0
+#define FSDEV_REG_BASE ((uint32_t)(USBD_BASE))
+#define FSDEV_PMA_BASE ((uint32_t)(USBD_BASE + 0x400UL))
+
+#ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP
+ #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0
+#endif
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+static const IRQn_Type fsdev_irq[] = {
+ USBD_IRQn
+};
+enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
+
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) {
+ (void)rhport;
+ for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) {
+ NVIC_EnableIRQ(fsdev_irq[i]);
+ }
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) {
+ (void)rhport;
+ for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) {
+ NVIC_DisableIRQ(fsdev_irq[i]);
+ }
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
+ (void) rhport;
+ FSDEV_REG->CNTR |= U_CNTR_PDWN;
+ FSDEV_REG->BCDR &= ~U_BCDR_DPPU;
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
+ (void) rhport;
+ FSDEV_REG->CNTR &= ~U_CNTR_PDWN;
+ FSDEV_REG->BCDR |= U_BCDR_DPPU;
+}
+
+#endif
diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h
index ebde44bf7..00d9b513a 100644
--- a/src/portable/st/stm32_fsdev/fsdev_common.h
+++ b/src/portable/st/stm32_fsdev/fsdev_common.h
@@ -284,6 +284,8 @@ typedef struct {
#include "fsdev_ch32.h"
#elif defined(TUP_USBIP_FSDEV_AT32)
#include "fsdev_at32.h"
+#elif defined(TUP_USBIP_FSDEV_APM32)
+ #include "fsdev_apm32.h"
#else
#error "Unknown USB IP"
#endif
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index 86aa54510..b2f1a93a4 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -1143,7 +1143,12 @@ static void handle_incomplete_iso_in(uint8_t rhport) {
xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
if (xfer->iso_retry > 0) {
xfer->iso_retry--;
- // Restart ISO transfe: re-write TSIZ and CTL
+ // Restart ISO transfer: re-write DMA address, TSIZ, and CTL
+ #if CFG_TUD_DWC2_DMA_ENABLE
+ if (dma_device_enabled(dwc2)) {
+ epin->diepdma = (uintptr_t) xfer->buffer;
+ }
+ #endif
dwc2_ep_tsize_t deptsiz = {.value = 0};
deptsiz.xfer_size = xfer->total_len;
deptsiz.packet_count = tu_div_ceil(xfer->total_len, xfer->max_size);
diff --git a/src/tinyusb.mk b/src/tinyusb.mk
index 365043927..941791670 100644
--- a/src/tinyusb.mk
+++ b/src/tinyusb.mk
@@ -26,4 +26,3 @@ TINYUSB_SRC_C += \
src/class/midi/midi_host.c \
src/class/midi/midi2_host.c \
src/class/msc/msc_host.c \
- src/class/vendor/vendor_host.c \
diff --git a/src/tusb.h b/src/tusb.h
index 6a30f7c13..cdf6f8171 100644
--- a/src/tusb.h
+++ b/src/tusb.h
@@ -48,9 +48,6 @@
#include "class/midi/midi2_host.h"
#endif
- #if CFG_TUH_VENDOR
- #include "class/vendor/vendor_host.h"
- #endif
#else
#ifndef tuh_int_handler
#define tuh_int_handler(...)
diff --git a/src/tusb_option.h b/src/tusb_option.h
index b5e910fca..1eb23fb00 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -207,6 +207,9 @@
// Puya
#define OPT_MCU_PY32F0 2700 ///< Puya PY32F0
+// Geehy
+#define OPT_MCU_APM32F0XX 2800 ///< Geehy APM32F0xx
+
// Check if configured MCU is one of listed
// Apply TU_MCU_IS_EQUAL with || as separator to list of input
#define TU_MCU_IS_EQUAL(_m) (CFG_TUSB_MCU == (_m))
@@ -891,9 +894,6 @@
#define CFG_TUH_MSC 0
#endif
-#ifndef CFG_TUH_VENDOR
- #define CFG_TUH_VENDOR 0
-#endif
#ifndef CFG_TUH_API_EDPT_XFER
#define CFG_TUH_API_EDPT_XFER 0