Skip to content

Commit

Permalink
Merge pull request #776 from dhalbert/hid_gamepad
Browse files Browse the repository at this point in the history
HID gamepad support
  • Loading branch information
dhalbert authored Apr 24, 2018
2 parents 58ba741 + 48f595e commit 8cadcc8
Show file tree
Hide file tree
Showing 4 changed files with 325 additions and 16 deletions.
58 changes: 58 additions & 0 deletions ports/atmel-samd/common-hal/usb_hid/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,27 @@
#include "genhdr/autogen_usb_descriptor.h"

// Buffers are report size + 1 to include the Report ID prefix byte if needed.
#ifdef USB_HID_REPORT_LENGTH_KEYBOARD
static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD + 1];
#endif
#ifdef USB_HID_REPORT_ID_MOUSE
static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE + 1];
#endif
#ifdef USB_HID_REPORT_ID_CONSUMER
static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER + 1];
#endif
#ifdef USB_HID_REPORT_ID_SYS_CONTROL
static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL + 1];
#endif
#ifdef USB_HID_REPORT_ID_GAMEPAD
static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD + 1];
#endif
#ifdef USB_HID_REPORT_ID_DIGITIZER
static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER + 1];
#endif

usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
#ifdef USB_HID_REPORT_LENGTH_KEYBOARD
{
.base = { .type = &usb_hid_device_type },
.report_buffer = keyboard_report_buffer,
Expand All @@ -50,6 +65,8 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
.usage_page = 0x01,
.usage = 0x06,
},
#endif
#ifdef USB_HID_REPORT_ID_MOUSE
{
.base = { .type = &usb_hid_device_type },
.report_buffer = mouse_report_buffer,
Expand All @@ -59,6 +76,8 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
.usage_page = 0x01,
.usage = 0x02,
},
#endif
#ifdef USB_HID_REPORT_ID_CONSUMER
{
.base = { .type = &usb_hid_device_type },
.report_buffer = consumer_report_buffer,
Expand All @@ -68,6 +87,8 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
.usage_page = 0x0C,
.usage = 0x01,
},
#endif
#ifdef USB_HID_REPORT_ID_SYS_CONTROL
{
.base = { .type = &usb_hid_device_type },
.report_buffer = sys_control_report_buffer,
Expand All @@ -77,6 +98,29 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
.usage_page = 0x01,
.usage = 0x80,
},
#endif
#ifdef USB_HID_REPORT_ID_GAMEPAD
{
.base = { .type = &usb_hid_device_type },
.report_buffer = gamepad_report_buffer,
.endpoint = USB_HID_ENDPOINT_IN,
.report_id = USB_HID_REPORT_ID_GAMEPAD,
.report_length = USB_HID_REPORT_LENGTH_GAMEPAD,
.usage_page = 0x01,
.usage = 0x05,
},
#endif
#ifdef USB_HID_REPORT_ID_DIGITIZER
{
.base = { .type = &usb_hid_device_type },
.report_buffer = digitizer_report_buffer,
.endpoint = USB_HID_ENDPOINT_IN,
.report_id = USB_HID_REPORT_ID_DIGITIZER,
.report_length = USB_HID_REPORT_LENGTH_DIGITIZER,
.usage_page = 0x0D,
.usage = 0x02,
},
#endif
};


Expand All @@ -86,9 +130,23 @@ mp_obj_tuple_t common_hal_usb_hid_devices = {
},
.len = USB_HID_NUM_DEVICES,
.items = {
#if USB_HID_NUM_DEVICES >= 1
(mp_obj_t) &usb_hid_devices[0],
#endif
#if USB_HID_NUM_DEVICES >= 2
(mp_obj_t) &usb_hid_devices[1],
#endif
#if USB_HID_NUM_DEVICES >= 3
(mp_obj_t) &usb_hid_devices[2],
#endif
#if USB_HID_NUM_DEVICES >= 4
(mp_obj_t) &usb_hid_devices[3],
#endif
#if USB_HID_NUM_DEVICES >= 5
(mp_obj_t) &usb_hid_devices[4],
#endif
#if USB_HID_NUM_DEVICES >= 6
(mp_obj_t) &usb_hid_devices[5],
#endif
}
};
42 changes: 27 additions & 15 deletions ports/atmel-samd/tools/gen_usb_descriptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
sys.path.append("../../tools/usb_descriptor")

from adafruit_usb_descriptor import cdc, hid, msc, standard, util
import hid_report_descriptors

parser = argparse.ArgumentParser(description='Generate USB descriptors.')
parser.add_argument('--manufacturer', type=str,
Expand Down Expand Up @@ -122,32 +123,43 @@ def strings_in_order(cls):
standard.EndpointDescriptor(
description="MSC in",
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
bInterval=0),
standard.EndpointDescriptor(
description="MSC out",
bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK)
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
bInterval=0)
]
)
]

hid_report_descriptor = hid.ReportDescriptor.MOUSE_KEYBOARD_CONSUMER_SYS_CONTROL_REPORT
hid_report_ids = hid.ReportDescriptor.REPORT_IDS
hid_report_lengths = hid.ReportDescriptor.REPORT_LENGTHS
hid_max_report_length = max(hid_report_lengths.values())
# Include only these HID devices.
# DIGITIZER works on Linux but conflicts with MOUSE, so leave it out for now.
hid_devices = ("KEYBOARD", "MOUSE", "CONSUMER", "GAMEPAD")

combined_hid_report_descriptor = hid.ReportDescriptor(
description="MULTIDEVICE",
report_descriptor=b''.join(
hid_report_descriptors.REPORT_DESCRIPTORS[name].report_descriptor for name in hid_devices ))

hid_report_ids_dict = { name: hid_report_descriptors.REPORT_IDS[name] for name in hid_devices }
hid_report_lengths_dict = { name: hid_report_descriptors.REPORT_LENGTHS[name] for name in hid_devices }
hid_max_report_length = max(hid_report_lengths_dict.values())

# ASF4 expects keyboard and generic devices to have both in and out endpoints,
# and will fail (possibly silently) if both are not supplied.
hid_endpoint_in_descriptor = standard.EndpointDescriptor(
description="HID in",
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
bInterval=0x02)
bInterval=10)

hid_endpoint_out_descriptor = standard.EndpointDescriptor(
description="HID out",
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT)
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
bInterval=10)

hid_interfaces = [
standard.InterfaceDescriptor(
Expand All @@ -159,7 +171,7 @@ def strings_in_order(cls):
subdescriptors=[
hid.HIDDescriptor(
description="HID",
wDescriptorLength=len(bytes(hid_report_descriptor))),
wDescriptorLength=len(bytes(combined_hid_report_descriptor))),
hid_endpoint_in_descriptor,
hid_endpoint_out_descriptor,
]
Expand Down Expand Up @@ -274,7 +286,7 @@ def strings_in_order(cls):
"""
.format(SERIAL_NUMBER_OFFSET=serial_number_offset,
SERIAL_NUMBER_LENGTH=args.serial_number_length,
HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(hid_report_descriptor)),
HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor)),
HID_ENDPOINT_IN_ADDRESS=hex(hid_endpoint_in_descriptor.bEndpointAddress),
HID_ENDPOINT_OUT_ADDRESS=hex(hid_endpoint_out_descriptor.bEndpointAddress)))

Expand All @@ -294,7 +306,7 @@ def strings_in_order(cls):
h_file.write("\n")

# #define the report ID's used in the combined HID descriptor
for name, id in hid_report_ids.items():
for name, id in hid_report_ids_dict.items():
h_file.write("""\
#define USB_HID_REPORT_ID_{NAME} {ID}
""".format(NAME=name,
Expand All @@ -303,7 +315,7 @@ def strings_in_order(cls):
h_file.write("\n")

# #define the report sizes used in the combined HID descriptor
for name, length in hid_report_lengths.items():
for name, length in hid_report_lengths_dict.items():
h_file.write("""\
#define USB_HID_REPORT_LENGTH_{NAME} {LENGTH}
""".format(NAME=name,
Expand All @@ -314,17 +326,17 @@ def strings_in_order(cls):
h_file.write("""\
#define USB_HID_NUM_DEVICES {NUM_DEVICES}
#define USB_HID_MAX_REPORT_LENGTH {MAX_LENGTH}
""".format(NUM_DEVICES=len(hid_report_lengths),
""".format(NUM_DEVICES=len(hid_report_lengths_dict),
MAX_LENGTH=hid_max_report_length))



# Write out the report descriptor and info
c_file.write("""\
uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{
""".format(HID_DESCRIPTOR_LENGTH=len(bytes(hid_report_descriptor))))
""".format(HID_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor))))

for b in bytes(hid_report_descriptor):
for b in bytes(combined_hid_report_descriptor):
c_file.write("0x{:02x}, ".format(b))
c_file.write("""
};
Expand Down
Loading

0 comments on commit 8cadcc8

Please sign in to comment.