wip: incorporate new hid descriptor building
This commit is contained in:
parent
3e5bc5a05d
commit
2a58b667aa
@ -337,7 +337,7 @@ if include_msc:
|
||||
|
||||
if include_hid:
|
||||
# When there's only one hid_device, it shouldn't have a report id.
|
||||
# Otherwise, report ids are assigned sequentially:
|
||||
# Otherwise, report ids are assigned sequentially, starting at 1.
|
||||
# args.hid_devices[0] has report_id 1
|
||||
# args.hid_devices[1] has report_id 2
|
||||
# etc.
|
||||
@ -346,24 +346,19 @@ if include_hid:
|
||||
|
||||
if len(args.hid_devices) == 1:
|
||||
name = args.hid_devices[0]
|
||||
combined_hid_report_descriptor = hid.ReportDescriptor(
|
||||
description=name,
|
||||
report_descriptor=bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](0)),
|
||||
)
|
||||
hid_descriptor = hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](None)
|
||||
concatenated_hid_report_descriptors = bytes(
|
||||
hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id=0))
|
||||
report_ids[name] = 0
|
||||
else:
|
||||
report_id = 1
|
||||
concatenated_descriptors = bytearray()
|
||||
concatenated_hid_report_descriptors = bytearray()
|
||||
# Sort HID devices by preferred order.
|
||||
for name in sorted(args.hid_devices, key=ALL_HID_DEVICES_ORDER.get):
|
||||
concatenated_descriptors.extend(
|
||||
bytes(hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id))
|
||||
)
|
||||
hid_report_descriptor = hid_report_descriptors.REPORT_DESCRIPTOR_FUNCTIONS[name](report_id)
|
||||
concatenated_hid_report_descriptors.extend(bytes(hid_report_descriptor))
|
||||
report_ids[name] = report_id
|
||||
report_id += 1
|
||||
combined_hid_report_descriptor = hid.ReportDescriptor(
|
||||
description="MULTIDEVICE", report_descriptor=bytes(concatenated_descriptors)
|
||||
)
|
||||
|
||||
# ASF4 expects keyboard and generic devices to have both in and out endpoints,
|
||||
# and will fail (possibly silently) if both are not supplied.
|
||||
@ -390,7 +385,7 @@ if include_hid:
|
||||
iInterface=StringIndex.index("{} HID".format(args.interface_name)),
|
||||
subdescriptors=[
|
||||
hid.HIDDescriptor(
|
||||
description="HID", wDescriptorLength=len(bytes(combined_hid_report_descriptor))
|
||||
description="HID", wDescriptorLength=len(concatenated_hid_report_descriptors)
|
||||
),
|
||||
hid_endpoint_in_descriptor,
|
||||
hid_endpoint_out_descriptor,
|
||||
@ -780,9 +775,9 @@ c_file.write(
|
||||
c_file.write("\n")
|
||||
|
||||
if include_hid:
|
||||
hid_descriptor_length = len(bytes(combined_hid_report_descriptor))
|
||||
hid_report_descriptors_length = len(concatenated_hid_report_descriptors)
|
||||
else:
|
||||
hid_descriptor_length = 0
|
||||
hid_report_descriptors_length = 0
|
||||
|
||||
# Now the values we need for the .h file.
|
||||
h_file.write(
|
||||
@ -809,7 +804,7 @@ extern uint16_t const * const string_desc_arr [{string_descriptor_length}];
|
||||
serial_number_length=len(bytes(serial_number_descriptor)) // 2,
|
||||
device_length=len(bytes(device)),
|
||||
configuration_length=descriptor_length,
|
||||
max_configuration_length=max(hid_descriptor_length, descriptor_length),
|
||||
max_configuration_length=max(hid_report_descriptors_length, descriptor_length),
|
||||
string_descriptor_length=len(pointers_to_strings),
|
||||
rhport0_mode="OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED"
|
||||
if args.highspeed
|
||||
@ -826,7 +821,7 @@ extern const uint8_t hid_report_descriptor[{hid_report_descriptor_length}];
|
||||
|
||||
#define USB_HID_NUM_DEVICES {hid_num_devices}
|
||||
""".format(
|
||||
hid_report_descriptor_length=len(bytes(combined_hid_report_descriptor)),
|
||||
hid_report_descriptor_length=len(concatenated_hid_report_descriptors),
|
||||
hid_num_devices=len(args.hid_devices),
|
||||
)
|
||||
)
|
||||
@ -859,13 +854,13 @@ if include_hid:
|
||||
# Write out the report descriptor and info
|
||||
c_file.write(
|
||||
"""\
|
||||
const uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{
|
||||
const uint8_t hid_report_descriptor[{HID_REPORT_DESCRIPTORS_LENGTH}] = {{
|
||||
""".format(
|
||||
HID_DESCRIPTOR_LENGTH=hid_descriptor_length
|
||||
HID_REPORT_DESCRIPTORS_LENGTH=hid_report_descriptors_length
|
||||
)
|
||||
)
|
||||
|
||||
for b in bytes(combined_hid_report_descriptor):
|
||||
for b in bytes(concatenated_hid_report_descriptors):
|
||||
c_file.write("0x{:02x}, ".format(b))
|
||||
|
||||
c_file.write(
|
||||
|
@ -48,474 +48,14 @@ HID_DEVICE_DATA = {
|
||||
), # Vendor 0xFFAF "Adafruit", 0xAF
|
||||
}
|
||||
|
||||
|
||||
def keyboard_hid_descriptor(report_id):
|
||||
data = HID_DEVICE_DATA["KEYBOARD"]
|
||||
return hid.ReportDescriptor(
|
||||
description="KEYBOARD",
|
||||
report_descriptor=bytes(
|
||||
# Regular keyboard
|
||||
(
|
||||
0x05,
|
||||
data.usage_page, # Usage Page (Generic Desktop)
|
||||
0x09,
|
||||
data.usage, # Usage (Keyboard)
|
||||
0xA1,
|
||||
0x01, # Collection (Application)
|
||||
)
|
||||
+ ((0x85, report_id) if report_id != 0 else ())
|
||||
+ (
|
||||
0x05,
|
||||
0x07, # Usage Page (Keyboard)
|
||||
0x19,
|
||||
224, # Usage Minimum (224)
|
||||
0x29,
|
||||
231, # Usage Maximum (231)
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0)
|
||||
0x25,
|
||||
0x01, # Logical Maximum (1)
|
||||
0x75,
|
||||
0x01, # Report Size (1)
|
||||
0x95,
|
||||
0x08, # Report Count (8)
|
||||
0x81,
|
||||
0x02, # Input (Data, Variable, Absolute)
|
||||
0x81,
|
||||
0x01, # Input (Constant)
|
||||
0x19,
|
||||
0x00, # Usage Minimum (0)
|
||||
0x29,
|
||||
0xDD, # Usage Maximum (221)
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0)
|
||||
0x25,
|
||||
0xDD, # Logical Maximum (221)
|
||||
0x75,
|
||||
0x08, # Report Size (8)
|
||||
0x95,
|
||||
0x06, # Report Count (6)
|
||||
0x81,
|
||||
0x00, # Input (Data, Array)
|
||||
0x05,
|
||||
0x08, # Usage Page (LED)
|
||||
0x19,
|
||||
0x01, # Usage Minimum (1)
|
||||
0x29,
|
||||
0x05, # Usage Maximum (5)
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0)
|
||||
0x25,
|
||||
0x01, # Logical Maximum (1)
|
||||
0x75,
|
||||
0x01, # Report Size (1)
|
||||
0x95,
|
||||
0x05, # Report Count (5)
|
||||
0x91,
|
||||
0x02, # Output (Data, Variable, Absolute)
|
||||
0x95,
|
||||
0x03, # Report Count (3)
|
||||
0x91,
|
||||
0x01, # Output (Constant)
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def mouse_hid_descriptor(report_id):
|
||||
data = HID_DEVICE_DATA["MOUSE"]
|
||||
return hid.ReportDescriptor(
|
||||
description="MOUSE",
|
||||
report_descriptor=bytes(
|
||||
# Regular mouse
|
||||
(
|
||||
0x05,
|
||||
data.usage_page, # Usage Page (Generic Desktop)
|
||||
0x09,
|
||||
data.usage, # Usage (Mouse)
|
||||
0xA1,
|
||||
0x01, # Collection (Application)
|
||||
0x09,
|
||||
0x01, # Usage (Pointer)
|
||||
0xA1,
|
||||
0x00, # Collection (Physical)
|
||||
)
|
||||
+ ((0x85, report_id) if report_id != 0 else ())
|
||||
+ (
|
||||
0x05,
|
||||
0x09, # Usage Page (Button)
|
||||
0x19,
|
||||
0x01, # Usage Minimum (0x01)
|
||||
0x29,
|
||||
0x05, # Usage Maximum (0x05)
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0)
|
||||
0x25,
|
||||
0x01, # Logical Maximum (1)
|
||||
0x95,
|
||||
0x05, # Report Count (5)
|
||||
0x75,
|
||||
0x01, # Report Size (1)
|
||||
0x81,
|
||||
0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x95,
|
||||
0x01, # Report Count (1)
|
||||
0x75,
|
||||
0x03, # Report Size (3)
|
||||
0x81,
|
||||
0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05,
|
||||
0x01, # Usage Page (Generic Desktop Ctrls)
|
||||
0x09,
|
||||
0x30, # Usage (X)
|
||||
0x09,
|
||||
0x31, # Usage (Y)
|
||||
0x15,
|
||||
0x81, # Logical Minimum (-127)
|
||||
0x25,
|
||||
0x7F, # Logical Maximum (127)
|
||||
0x75,
|
||||
0x08, # Report Size (8)
|
||||
0x95,
|
||||
0x02, # Report Count (2)
|
||||
0x81,
|
||||
0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x09,
|
||||
0x38, # Usage (Wheel)
|
||||
0x15,
|
||||
0x81, # Logical Minimum (-127)
|
||||
0x25,
|
||||
0x7F, # Logical Maximum (127)
|
||||
0x75,
|
||||
0x08, # Report Size (8)
|
||||
0x95,
|
||||
0x01, # Report Count (1)
|
||||
0x81,
|
||||
0x06, # Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, # End Collection
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def consumer_hid_descriptor(report_id):
|
||||
data = HID_DEVICE_DATA["CONSUMER"]
|
||||
return hid.ReportDescriptor(
|
||||
description="CONSUMER",
|
||||
report_descriptor=bytes(
|
||||
# Consumer ("multimedia") keys
|
||||
(
|
||||
0x05,
|
||||
data.usage_page, # Usage Page (Consumer)
|
||||
0x09,
|
||||
data.usage, # Usage (Consumer Control)
|
||||
0xA1,
|
||||
0x01, # Collection (Application)
|
||||
)
|
||||
+ ((0x85, report_id) if report_id != 0 else ())
|
||||
+ (
|
||||
0x75,
|
||||
0x10, # Report Size (16)
|
||||
0x95,
|
||||
0x01, # Report Count (1)
|
||||
0x15,
|
||||
0x01, # Logical Minimum (1)
|
||||
0x26,
|
||||
0x8C,
|
||||
0x02, # Logical Maximum (652)
|
||||
0x19,
|
||||
0x01, # Usage Minimum (Consumer Control)
|
||||
0x2A,
|
||||
0x8C,
|
||||
0x02, # Usage Maximum (AC Send)
|
||||
0x81,
|
||||
0x00, # Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def sys_control_hid_descriptor(report_id):
|
||||
data = HID_DEVICE_DATA["SYS_CONTROL"]
|
||||
return hid.ReportDescriptor(
|
||||
description="SYS_CONTROL",
|
||||
report_descriptor=bytes(
|
||||
# Power controls
|
||||
(
|
||||
0x05,
|
||||
data.usage_page, # Usage Page (Generic Desktop Ctrls)
|
||||
0x09,
|
||||
data.usage, # Usage (Sys Control)
|
||||
0xA1,
|
||||
0x01, # Collection (Application)
|
||||
)
|
||||
+ ((0x85, report_id) if report_id != 0 else ())
|
||||
+ (
|
||||
0x75,
|
||||
0x02, # Report Size (2)
|
||||
0x95,
|
||||
0x01, # Report Count (1)
|
||||
0x15,
|
||||
0x01, # Logical Minimum (1)
|
||||
0x25,
|
||||
0x03, # Logical Maximum (3)
|
||||
0x09,
|
||||
0x82, # Usage (Sys Sleep)
|
||||
0x09,
|
||||
0x81, # Usage (Sys Power Down)
|
||||
0x09,
|
||||
0x83, # Usage (Sys Wake Up)
|
||||
0x81,
|
||||
0x60, # Input (Data,Array,Abs,No Wrap,Linear,No Preferred State,Null State)
|
||||
0x75,
|
||||
0x06, # Report Size (6)
|
||||
0x81,
|
||||
0x03, # Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def gamepad_hid_descriptor(report_id):
|
||||
data = HID_DEVICE_DATA["GAMEPAD"]
|
||||
return hid.ReportDescriptor(
|
||||
description="GAMEPAD",
|
||||
report_descriptor=bytes(
|
||||
# Gamepad with 16 buttons and two joysticks
|
||||
(
|
||||
0x05,
|
||||
data.usage_page, # Usage Page (Generic Desktop Ctrls)
|
||||
0x09,
|
||||
data.usage, # Usage (Game Pad)
|
||||
0xA1,
|
||||
0x01, # Collection (Application)
|
||||
)
|
||||
+ ((0x85, report_id) if report_id != 0 else ())
|
||||
+ (
|
||||
0x05,
|
||||
0x09, # Usage Page (Button)
|
||||
0x19,
|
||||
0x01, # Usage Minimum (Button 1)
|
||||
0x29,
|
||||
0x10, # Usage Maximum (Button 16)
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0)
|
||||
0x25,
|
||||
0x01, # Logical Maximum (1)
|
||||
0x75,
|
||||
0x01, # Report Size (1)
|
||||
0x95,
|
||||
0x10, # Report Count (16)
|
||||
0x81,
|
||||
0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05,
|
||||
0x01, # Usage Page (Generic Desktop Ctrls)
|
||||
0x15,
|
||||
0x81, # Logical Minimum (-127)
|
||||
0x25,
|
||||
0x7F, # Logical Maximum (127)
|
||||
0x09,
|
||||
0x30, # Usage (X)
|
||||
0x09,
|
||||
0x31, # Usage (Y)
|
||||
0x09,
|
||||
0x32, # Usage (Z)
|
||||
0x09,
|
||||
0x35, # Usage (Rz)
|
||||
0x75,
|
||||
0x08, # Report Size (8)
|
||||
0x95,
|
||||
0x04, # Report Count (4)
|
||||
0x81,
|
||||
0x02, # Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def digitizer_hid_descriptor(report_id):
|
||||
data = HID_DEVICE_DATA["DIGITIZER"]
|
||||
return hid.ReportDescriptor(
|
||||
description="DIGITIZER",
|
||||
report_descriptor=bytes(
|
||||
# Digitizer (used as an absolute pointer)
|
||||
(
|
||||
0x05,
|
||||
data.usage_page, # Usage Page (Digitizers)
|
||||
0x09,
|
||||
data.usage, # Usage (Pen)
|
||||
0xA1,
|
||||
0x01, # Collection (Application)
|
||||
)
|
||||
+ ((0x85, report_id) if report_id != 0 else ())
|
||||
+ (
|
||||
0x09,
|
||||
0x01, # Usage (Stylus)
|
||||
0xA1,
|
||||
0x00, # Collection (Physical)
|
||||
0x09,
|
||||
0x32, # Usage (In-Range)
|
||||
0x09,
|
||||
0x42, # Usage (Tip Switch)
|
||||
0x09,
|
||||
0x44, # Usage (Barrel Switch)
|
||||
0x09,
|
||||
0x45, # Usage (Eraser Switch)
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0)
|
||||
0x25,
|
||||
0x01, # Logical Maximum (1)
|
||||
0x75,
|
||||
0x01, # Report Size (1)
|
||||
0x95,
|
||||
0x04, # Report Count (4)
|
||||
0x81,
|
||||
0x02, # Input (Data,Var,Abs)
|
||||
0x75,
|
||||
0x04, # Report Size (4) -- Filler
|
||||
0x95,
|
||||
0x01, # Report Count (1) -- Filler
|
||||
0x81,
|
||||
0x01, # Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||
0x05,
|
||||
0x01, # Usage Page (Generic Desktop Ctrls)
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0)
|
||||
0x26,
|
||||
0xFF,
|
||||
0x7F, # Logical Maximum (32767)
|
||||
0x09,
|
||||
0x30, # Usage (X)
|
||||
0x09,
|
||||
0x31, # Usage (Y)
|
||||
0x75,
|
||||
0x10, # Report Size (16)
|
||||
0x95,
|
||||
0x02, # Report Count (2)
|
||||
0x81,
|
||||
0x02, # Input (Data,Var,Abs)
|
||||
0xC0, # End Collection
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def xac_compatible_gamepad_hid_descriptor(report_id):
|
||||
data = HID_DEVICE_DATA["XAC_COMPATIBLE_GAMEPAD"]
|
||||
return hid.ReportDescriptor(
|
||||
description="XAC",
|
||||
report_descriptor=bytes(
|
||||
# This descriptor mimics the simple joystick from PDP that the XBox likes
|
||||
(
|
||||
0x05,
|
||||
data.usage_page, # Usage Page (Desktop),
|
||||
0x09,
|
||||
data.usage, # Usage (Gamepad),
|
||||
0xA1,
|
||||
0x01, # Collection (Application),
|
||||
)
|
||||
+ ((0x85, report_id) if report_id != 0 else ())
|
||||
+ (
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0),
|
||||
0x25,
|
||||
0x01, # Logical Maximum (1),
|
||||
0x35,
|
||||
0x00, # Physical Minimum (0),
|
||||
0x45,
|
||||
0x01, # Physical Maximum (1),
|
||||
0x75,
|
||||
0x01, # Report Size (1),
|
||||
0x95,
|
||||
0x08, # Report Count (8),
|
||||
0x05,
|
||||
0x09, # Usage Page (Button),
|
||||
0x19,
|
||||
0x01, # Usage Minimum (01h),
|
||||
0x29,
|
||||
0x08, # Usage Maximum (08h),
|
||||
0x81,
|
||||
0x02, # Input (Variable),
|
||||
0x05,
|
||||
0x01, # Usage Page (Desktop),
|
||||
0x26,
|
||||
0xFF,
|
||||
0x00, # Logical Maximum (255),
|
||||
0x46,
|
||||
0xFF,
|
||||
0x00, # Physical Maximum (255),
|
||||
0x09,
|
||||
0x30, # Usage (X),
|
||||
0x09,
|
||||
0x31, # Usage (Y),
|
||||
0x75,
|
||||
0x08, # Report Size (8),
|
||||
0x95,
|
||||
0x02, # Report Count (2),
|
||||
0x81,
|
||||
0x02, # Input (Variable),
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def raw_hid_descriptor(report_id):
|
||||
if report_id != 0:
|
||||
raise ValueError("raw hid must not have a report id")
|
||||
data = HID_DEVICE_DATA["RAW"]
|
||||
return hid.ReportDescriptor(
|
||||
description="RAW",
|
||||
report_descriptor=bytes(
|
||||
# Provide vendor-defined
|
||||
# This is a two-byte page value.
|
||||
(
|
||||
0x06,
|
||||
data.usage_page & 0xFF,
|
||||
(data.usage_page >> 8) & 0xFF, # Usage Page (Vendor 0xFFAF "Adafruit"),
|
||||
0x09,
|
||||
data.usage, # Usage (AF),
|
||||
0xA1,
|
||||
0x01, # Collection (Application),
|
||||
0x75,
|
||||
0x08, # Report Size (8),
|
||||
0x15,
|
||||
0x00, # Logical Minimum (0),
|
||||
0x26,
|
||||
0xFF,
|
||||
0x00, # Logical Maximum (255),
|
||||
0x95,
|
||||
0x08, # Report Count (8),
|
||||
0x09,
|
||||
0x01, # Usage(xxx)
|
||||
0x81,
|
||||
0x02, # Input (Variable)
|
||||
0x95,
|
||||
0x08, # Report Count (8),
|
||||
0x09,
|
||||
0x02, # Usage(xxx)
|
||||
0x91,
|
||||
0x02, # Input (Variable)
|
||||
0xC0, # End Collection
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# Function to call for each kind of HID descriptor.
|
||||
REPORT_DESCRIPTOR_FUNCTIONS = {
|
||||
"KEYBOARD": keyboard_hid_descriptor,
|
||||
"MOUSE": mouse_hid_descriptor,
|
||||
"CONSUMER": consumer_hid_descriptor,
|
||||
"SYS_CONTROL": sys_control_hid_descriptor,
|
||||
"GAMEPAD": gamepad_hid_descriptor,
|
||||
"DIGITIZER": digitizer_hid_descriptor,
|
||||
"XAC_COMPATIBLE_GAMEPAD": xac_compatible_gamepad_hid_descriptor,
|
||||
"RAW": raw_hid_descriptor,
|
||||
"KEYBOARD": hid.ReportDescriptor.keyboard,
|
||||
"MOUSE": hid.ReportDescriptor.mouse,
|
||||
"CONSUMER": hid.ReportDescriptor.consumer_control,
|
||||
"SYS_CONTROL": hid.ReportDescriptor.sys_control,
|
||||
"GAMEPAD": hid.ReportDescriptor.gamepad,
|
||||
"DIGITIZER": hid.ReportDescriptor.digitizer,
|
||||
"XAC_COMPATIBLE_GAMEPAD": hid.ReportDescriptor.xac_compatible_gamepad,
|
||||
"RAW": hid.ReportDescriptor.raw,
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 7ca9377687cc8bd367bd6401dcc4361a71a9d6cf
|
||||
Subproject commit 727530692805bb1c9d9d20d7477804a1799e358d
|
Loading…
x
Reference in New Issue
Block a user