Skip to content

HID gamepad support #776

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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