Skip to content

Commit 8cadcc8

Browse files
authored
Merge pull request #776 from dhalbert/hid_gamepad
HID gamepad support
2 parents 58ba741 + 48f595e commit 8cadcc8

File tree

4 files changed

+325
-16
lines changed

4 files changed

+325
-16
lines changed

ports/atmel-samd/common-hal/usb_hid/__init__.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,27 @@
3535
#include "genhdr/autogen_usb_descriptor.h"
3636

3737
// Buffers are report size + 1 to include the Report ID prefix byte if needed.
38+
#ifdef USB_HID_REPORT_LENGTH_KEYBOARD
3839
static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD + 1];
40+
#endif
41+
#ifdef USB_HID_REPORT_ID_MOUSE
3942
static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE + 1];
43+
#endif
44+
#ifdef USB_HID_REPORT_ID_CONSUMER
4045
static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER + 1];
46+
#endif
47+
#ifdef USB_HID_REPORT_ID_SYS_CONTROL
4148
static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL + 1];
49+
#endif
50+
#ifdef USB_HID_REPORT_ID_GAMEPAD
51+
static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD + 1];
52+
#endif
53+
#ifdef USB_HID_REPORT_ID_DIGITIZER
54+
static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER + 1];
55+
#endif
4256

4357
usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
58+
#ifdef USB_HID_REPORT_LENGTH_KEYBOARD
4459
{
4560
.base = { .type = &usb_hid_device_type },
4661
.report_buffer = keyboard_report_buffer,
@@ -50,6 +65,8 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
5065
.usage_page = 0x01,
5166
.usage = 0x06,
5267
},
68+
#endif
69+
#ifdef USB_HID_REPORT_ID_MOUSE
5370
{
5471
.base = { .type = &usb_hid_device_type },
5572
.report_buffer = mouse_report_buffer,
@@ -59,6 +76,8 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
5976
.usage_page = 0x01,
6077
.usage = 0x02,
6178
},
79+
#endif
80+
#ifdef USB_HID_REPORT_ID_CONSUMER
6281
{
6382
.base = { .type = &usb_hid_device_type },
6483
.report_buffer = consumer_report_buffer,
@@ -68,6 +87,8 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
6887
.usage_page = 0x0C,
6988
.usage = 0x01,
7089
},
90+
#endif
91+
#ifdef USB_HID_REPORT_ID_SYS_CONTROL
7192
{
7293
.base = { .type = &usb_hid_device_type },
7394
.report_buffer = sys_control_report_buffer,
@@ -77,6 +98,29 @@ usb_hid_device_obj_t usb_hid_devices[USB_HID_NUM_DEVICES] = {
7798
.usage_page = 0x01,
7899
.usage = 0x80,
79100
},
101+
#endif
102+
#ifdef USB_HID_REPORT_ID_GAMEPAD
103+
{
104+
.base = { .type = &usb_hid_device_type },
105+
.report_buffer = gamepad_report_buffer,
106+
.endpoint = USB_HID_ENDPOINT_IN,
107+
.report_id = USB_HID_REPORT_ID_GAMEPAD,
108+
.report_length = USB_HID_REPORT_LENGTH_GAMEPAD,
109+
.usage_page = 0x01,
110+
.usage = 0x05,
111+
},
112+
#endif
113+
#ifdef USB_HID_REPORT_ID_DIGITIZER
114+
{
115+
.base = { .type = &usb_hid_device_type },
116+
.report_buffer = digitizer_report_buffer,
117+
.endpoint = USB_HID_ENDPOINT_IN,
118+
.report_id = USB_HID_REPORT_ID_DIGITIZER,
119+
.report_length = USB_HID_REPORT_LENGTH_DIGITIZER,
120+
.usage_page = 0x0D,
121+
.usage = 0x02,
122+
},
123+
#endif
80124
};
81125

82126

@@ -86,9 +130,23 @@ mp_obj_tuple_t common_hal_usb_hid_devices = {
86130
},
87131
.len = USB_HID_NUM_DEVICES,
88132
.items = {
133+
#if USB_HID_NUM_DEVICES >= 1
89134
(mp_obj_t) &usb_hid_devices[0],
135+
#endif
136+
#if USB_HID_NUM_DEVICES >= 2
90137
(mp_obj_t) &usb_hid_devices[1],
138+
#endif
139+
#if USB_HID_NUM_DEVICES >= 3
91140
(mp_obj_t) &usb_hid_devices[2],
141+
#endif
142+
#if USB_HID_NUM_DEVICES >= 4
92143
(mp_obj_t) &usb_hid_devices[3],
144+
#endif
145+
#if USB_HID_NUM_DEVICES >= 5
146+
(mp_obj_t) &usb_hid_devices[4],
147+
#endif
148+
#if USB_HID_NUM_DEVICES >= 6
149+
(mp_obj_t) &usb_hid_devices[5],
150+
#endif
93151
}
94152
};

ports/atmel-samd/tools/gen_usb_descriptor.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
sys.path.append("../../tools/usb_descriptor")
88

99
from adafruit_usb_descriptor import cdc, hid, msc, standard, util
10+
import hid_report_descriptors
1011

1112
parser = argparse.ArgumentParser(description='Generate USB descriptors.')
1213
parser.add_argument('--manufacturer', type=str,
@@ -122,32 +123,43 @@ def strings_in_order(cls):
122123
standard.EndpointDescriptor(
123124
description="MSC in",
124125
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
125-
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
126+
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
127+
bInterval=0),
126128
standard.EndpointDescriptor(
127129
description="MSC out",
128130
bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT,
129-
bmAttributes=standard.EndpointDescriptor.TYPE_BULK)
131+
bmAttributes=standard.EndpointDescriptor.TYPE_BULK,
132+
bInterval=0)
130133
]
131134
)
132135
]
133136

134-
hid_report_descriptor = hid.ReportDescriptor.MOUSE_KEYBOARD_CONSUMER_SYS_CONTROL_REPORT
135-
hid_report_ids = hid.ReportDescriptor.REPORT_IDS
136-
hid_report_lengths = hid.ReportDescriptor.REPORT_LENGTHS
137-
hid_max_report_length = max(hid_report_lengths.values())
137+
# Include only these HID devices.
138+
# DIGITIZER works on Linux but conflicts with MOUSE, so leave it out for now.
139+
hid_devices = ("KEYBOARD", "MOUSE", "CONSUMER", "GAMEPAD")
140+
141+
combined_hid_report_descriptor = hid.ReportDescriptor(
142+
description="MULTIDEVICE",
143+
report_descriptor=b''.join(
144+
hid_report_descriptors.REPORT_DESCRIPTORS[name].report_descriptor for name in hid_devices ))
145+
146+
hid_report_ids_dict = { name: hid_report_descriptors.REPORT_IDS[name] for name in hid_devices }
147+
hid_report_lengths_dict = { name: hid_report_descriptors.REPORT_LENGTHS[name] for name in hid_devices }
148+
hid_max_report_length = max(hid_report_lengths_dict.values())
138149

139150
# ASF4 expects keyboard and generic devices to have both in and out endpoints,
140151
# and will fail (possibly silently) if both are not supplied.
141152
hid_endpoint_in_descriptor = standard.EndpointDescriptor(
142153
description="HID in",
143154
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
144155
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
145-
bInterval=0x02)
156+
bInterval=10)
146157

147158
hid_endpoint_out_descriptor = standard.EndpointDescriptor(
148159
description="HID out",
149160
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT,
150-
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT)
161+
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
162+
bInterval=10)
151163

152164
hid_interfaces = [
153165
standard.InterfaceDescriptor(
@@ -159,7 +171,7 @@ def strings_in_order(cls):
159171
subdescriptors=[
160172
hid.HIDDescriptor(
161173
description="HID",
162-
wDescriptorLength=len(bytes(hid_report_descriptor))),
174+
wDescriptorLength=len(bytes(combined_hid_report_descriptor))),
163175
hid_endpoint_in_descriptor,
164176
hid_endpoint_out_descriptor,
165177
]
@@ -274,7 +286,7 @@ def strings_in_order(cls):
274286
"""
275287
.format(SERIAL_NUMBER_OFFSET=serial_number_offset,
276288
SERIAL_NUMBER_LENGTH=args.serial_number_length,
277-
HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(hid_report_descriptor)),
289+
HID_REPORT_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor)),
278290
HID_ENDPOINT_IN_ADDRESS=hex(hid_endpoint_in_descriptor.bEndpointAddress),
279291
HID_ENDPOINT_OUT_ADDRESS=hex(hid_endpoint_out_descriptor.bEndpointAddress)))
280292

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

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

305317
# #define the report sizes used in the combined HID descriptor
306-
for name, length in hid_report_lengths.items():
318+
for name, length in hid_report_lengths_dict.items():
307319
h_file.write("""\
308320
#define USB_HID_REPORT_LENGTH_{NAME} {LENGTH}
309321
""".format(NAME=name,
@@ -314,17 +326,17 @@ def strings_in_order(cls):
314326
h_file.write("""\
315327
#define USB_HID_NUM_DEVICES {NUM_DEVICES}
316328
#define USB_HID_MAX_REPORT_LENGTH {MAX_LENGTH}
317-
""".format(NUM_DEVICES=len(hid_report_lengths),
329+
""".format(NUM_DEVICES=len(hid_report_lengths_dict),
318330
MAX_LENGTH=hid_max_report_length))
319331

320332

321333

322334
# Write out the report descriptor and info
323335
c_file.write("""\
324336
uint8_t hid_report_descriptor[{HID_DESCRIPTOR_LENGTH}] = {{
325-
""".format(HID_DESCRIPTOR_LENGTH=len(bytes(hid_report_descriptor))))
337+
""".format(HID_DESCRIPTOR_LENGTH=len(bytes(combined_hid_report_descriptor))))
326338

327-
for b in bytes(hid_report_descriptor):
339+
for b in bytes(combined_hid_report_descriptor):
328340
c_file.write("0x{:02x}, ".format(b))
329341
c_file.write("""
330342
};

0 commit comments

Comments
 (0)