wip: incorporate new hid descriptor building

This commit is contained in:
Dan Halbert 2021-04-12 23:42:48 -04:00
parent 3e5bc5a05d
commit 2a58b667aa
3 changed files with 24 additions and 489 deletions

View File

@ -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(

View File

@ -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