WIP
This commit is contained in:
parent
1d973a0803
commit
42f5edbd33
@ -3,6 +3,9 @@ USB_VID = 0x239A
|
||||
USB_PID = 0x8019
|
||||
USB_PRODUCT = "CircuitPlayground Express"
|
||||
USB_MANUFACTURER = "Adafruit Industries LLC"
|
||||
#USB_HID_DEVICES = KEYBOARD,XAC_COMPATIBLE_GAMEPAD
|
||||
USB_HID_DEVICES = XAC_COMPATIBLE_GAMEPAD
|
||||
|
||||
|
||||
CHIP_VARIANT = SAMD21G18A
|
||||
CHIP_FAMILY = samd21
|
||||
|
@ -1,12 +1,16 @@
|
||||
LD_FILE = boards/samd21x18-bootloader.ld
|
||||
USB_VID = 0x239A
|
||||
USB_PID = 0x801F
|
||||
|
||||
USB_HID_DEVICES=MOUSE,KEYBOARD,XAC_COMPATIBLE_GAMEPAD
|
||||
|
||||
USB_PRODUCT = "Trinket M0"
|
||||
USB_MANUFACTURER = "Adafruit Industries LLC"
|
||||
|
||||
CHIP_VARIANT = SAMD21E18A
|
||||
CHIP_FAMILY = samd21
|
||||
|
||||
|
||||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
LONGINT_IMPL = NONE
|
||||
CIRCUITPY_SMALL_BUILD = 1
|
||||
|
@ -48,9 +48,7 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t*
|
||||
// Wait until interface is ready, timeout = 2 seconds
|
||||
uint64_t end_ticks = ticks_ms + 2000;
|
||||
while ( (ticks_ms < end_ticks) && !tud_hid_ready() ) {
|
||||
#ifdef MICROPY_VM_HOOK_LOOP
|
||||
MICROPY_VM_HOOK_LOOP;
|
||||
#endif
|
||||
RUN_BACKGROUND_TASKS;
|
||||
}
|
||||
|
||||
if ( !tud_hid_ready() ) {
|
||||
|
@ -53,6 +53,10 @@ static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL];
|
||||
static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD];
|
||||
#endif
|
||||
|
||||
#ifdef USB_HID_REPORT_ID_XAC_COMPATIBLE_GAMEPAD
|
||||
static uint8_t xac_compatible_gamepad_report_buffer[USB_HID_REPORT_LENGTH_XAC_COMPATIBLE_GAMEPAD];
|
||||
#endif
|
||||
|
||||
#ifdef USB_HID_REPORT_ID_DIGITIZER
|
||||
static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER];
|
||||
#endif
|
||||
@ -113,6 +117,17 @@ usb_hid_device_obj_t usb_hid_devices[] = {
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef USB_HID_REPORT_ID_XAC_COMPATIBLE_GAMEPAD
|
||||
{
|
||||
.base = { .type = &usb_hid_device_type } ,
|
||||
.report_buffer = xac_compatible_gamepad_report_buffer ,
|
||||
.report_id = USB_HID_REPORT_ID_XAC_COMPATIBLE_GAMEPAD ,
|
||||
.report_length = USB_HID_REPORT_LENGTH_XAC_COMPATIBLE_GAMEPAD ,
|
||||
.usage_page = HID_USAGE_PAGE_DESKTOP ,
|
||||
.usage = HID_USAGE_DESKTOP_GAMEPAD ,
|
||||
},
|
||||
#endif
|
||||
|
||||
#ifdef USB_HID_REPORT_ID_DIGITIZER
|
||||
{
|
||||
.base = { .type = &usb_hid_device_type } ,
|
||||
@ -149,6 +164,9 @@ mp_obj_tuple_t common_hal_usb_hid_devices = {
|
||||
#endif
|
||||
#if USB_HID_NUM_DEVICES >= 6
|
||||
(mp_obj_t) &usb_hid_devices[5],
|
||||
#endif
|
||||
#if USB_HID_NUM_DEVICES >= 7
|
||||
#error "Too many USB HID devices"
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
@ -81,6 +81,14 @@ else
|
||||
CFLAGS += -DUSB_AVAILABLE
|
||||
endif
|
||||
|
||||
ifndef USB_DEVICES
|
||||
USB_DEVICES = "CDC,MSC,AUDIO,HID"
|
||||
endif
|
||||
|
||||
ifndef USB_HID_DEVICES
|
||||
USB_HID_DEVICES = "KEYBOARD,MOUSE,CONSUMER,GAMEPAD"
|
||||
endif
|
||||
|
||||
SUPERVISOR_O = $(addprefix $(BUILD)/, $(SRC_SUPERVISOR:.c=.o)) $(BUILD)/autogen_display_resources.o
|
||||
|
||||
$(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h
|
||||
@ -98,6 +106,8 @@ autogen_usb_descriptor.intermediate: ../../tools/gen_usb_descriptor.py Makefile
|
||||
--vid $(USB_VID)\
|
||||
--pid $(USB_PID)\
|
||||
--serial_number_length $(USB_SERIAL_NUMBER_LENGTH)\
|
||||
--devices $(USB_DEVICES) \
|
||||
--hid_devices $(USB_HID_DEVICES) \
|
||||
--output_c_file $(BUILD)/autogen_usb_descriptor.c\
|
||||
--output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h
|
||||
|
||||
|
@ -8,6 +8,15 @@ sys.path.append("../../tools/usb_descriptor")
|
||||
from adafruit_usb_descriptor import audio, audio10, cdc, hid, midi, msc, standard, util
|
||||
import hid_report_descriptors
|
||||
|
||||
ALL_DEVICES='CDC,MSC,AUDIO,HID'
|
||||
ALL_DEVICES_SET=frozenset(ALL_DEVICES.split(','))
|
||||
DEFAULT_DEVICES='CDC,MSC,AUDIO,HID'
|
||||
|
||||
ALL_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,SYS_CONTROL,GAMEPAD,DIGITIZER,XAC_COMPATIBLE_GAMEPAD'
|
||||
ALL_HID_DEVICES_SET=frozenset(ALL_HID_DEVICES.split(','))
|
||||
# Digitizer works on Linux but conflicts with mouse, so omit it.
|
||||
DEFAULT_HID_DEVICES='KEYBOARD,MOUSE,CONSUMER,GAMEPAD'
|
||||
|
||||
parser = argparse.ArgumentParser(description='Generate USB descriptors.')
|
||||
parser.add_argument('--manufacturer', type=str,
|
||||
help='manufacturer of the device')
|
||||
@ -19,11 +28,24 @@ parser.add_argument('--pid', type=lambda x: int(x, 16),
|
||||
help='product id')
|
||||
parser.add_argument('--serial_number_length', type=int, default=32,
|
||||
help='length needed for the serial number in digits')
|
||||
parser.add_argument('--devices', type=lambda l: frozenset(l.split(',')), default=DEFAULT_DEVICES,
|
||||
help='devices to include in descriptor (AUDIO includes MIDI support)')
|
||||
parser.add_argument('--hid_devices', type=lambda l: frozenset(l.split(',')), default=DEFAULT_HID_DEVICES,
|
||||
help='HID devices to include in HID report descriptor')
|
||||
parser.add_argument('--output_c_file', type=argparse.FileType('w'), required=True)
|
||||
parser.add_argument('--output_h_file', type=argparse.FileType('w'), required=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
unknown_devices = list(args.devices - ALL_DEVICES_SET)
|
||||
if unknown_devices:
|
||||
raise ValueError("Unknown device(s)", unknown_devices)
|
||||
|
||||
unknown_hid_devices = list(args.hid_devices - ALL_HID_DEVICES_SET)
|
||||
if unknown_hid_devices:
|
||||
raise ValueError("Unknown HID devices(s)", unknown_hid_devices)
|
||||
|
||||
|
||||
class StringIndex:
|
||||
"""Assign a monotonically increasing index to each unique string. Start with 0."""
|
||||
string_to_index = {}
|
||||
@ -138,16 +160,27 @@ msc_interfaces = [
|
||||
)
|
||||
]
|
||||
|
||||
# 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")
|
||||
# Sort by Report ID for consistency.
|
||||
hid_devices = sorted(args.hid_devices, key=lambda name: hid_report_descriptors.REPORT_IDS[name])
|
||||
|
||||
combined_hid_report_descriptor = hid.ReportDescriptor(
|
||||
# When there's only one hid_device, it can't be in a composite descriptor.
|
||||
# It has no report id (indicated by 0), so remove the existing one.
|
||||
|
||||
#if len(hid_devices) == 1:
|
||||
if False:
|
||||
name = hid_devices[0]
|
||||
combined_hid_report_descriptor = hid.ReportDescriptor(
|
||||
description=name,
|
||||
report_descriptor=hid_report_descriptors.remove_report_id(
|
||||
hid_report_descriptors.REPORT_DESCRIPTORS[name].report_descriptor))
|
||||
hid_report_ids_dict = { name : 0 }
|
||||
else:
|
||||
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_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())
|
||||
|
||||
@ -271,19 +304,27 @@ cdc_iad = standard.InterfaceAssociationDescriptor(
|
||||
bFunctionProtocol=cdc.CDC_PROTOCOL_NONE)
|
||||
|
||||
descriptor_list = []
|
||||
descriptor_list.append(cdc_iad)
|
||||
descriptor_list.extend(cdc_interfaces)
|
||||
descriptor_list.extend(msc_interfaces)
|
||||
# Only add the control interface because other audio interfaces are managed by it to ensure the
|
||||
# correct ordering.
|
||||
descriptor_list.append(audio_control_interface)
|
||||
# Put the CDC IAD just before the CDC interfaces.
|
||||
# There appears to be a bug in the Windows composite USB driver that requests the
|
||||
# HID report descriptor with the wrong interface number if the HID interface is not given
|
||||
# first. However, it still fetches the descriptor anyway. We could reorder the interfaces but
|
||||
# the Windows 7 Adafruit_usbser.inf file thinks CDC is at Interface 0, so we'll leave it
|
||||
# there for backwards compatibility.
|
||||
descriptor_list.extend(hid_interfaces)
|
||||
|
||||
if 'CDC' in args.devices:
|
||||
# Put the CDC IAD just before the CDC interfaces.
|
||||
# There appears to be a bug in the Windows composite USB driver that requests the
|
||||
# HID report descriptor with the wrong interface number if the HID interface is not given
|
||||
# first. However, it still fetches the descriptor anyway. We could reorder the interfaces but
|
||||
# the Windows 7 Adafruit_usbser.inf file thinks CDC is at Interface 0, so we'll leave it
|
||||
# there for backwards compatibility.
|
||||
descriptor_list.append(cdc_iad)
|
||||
descriptor_list.extend(cdc_interfaces)
|
||||
|
||||
if 'MSC' in args.devices:
|
||||
descriptor_list.extend(msc_interfaces)
|
||||
|
||||
if 'AUDIO' in args.devices:
|
||||
# Only add the control interface because other audio interfaces are managed by it to ensure the
|
||||
# correct ordering.
|
||||
descriptor_list.append(audio_control_interface)
|
||||
|
||||
if 'HID' in args.devices:
|
||||
descriptor_list.extend(hid_interfaces)
|
||||
|
||||
configuration = standard.ConfigurationDescriptor(
|
||||
description="Composite configuration",
|
||||
|
@ -31,6 +31,11 @@ HID specific descriptors
|
||||
|
||||
from adafruit_usb_descriptor import hid
|
||||
|
||||
def remove_report_id(report_descriptor_bytes):
|
||||
#return report_descriptor_bytes
|
||||
report_id_pos = report_descriptor_bytes.index(0x85)
|
||||
return report_descriptor_bytes[:report_id_pos] + report_descriptor_bytes[report_id_pos + 2:]
|
||||
|
||||
REPORT_IDS = {
|
||||
"KEYBOARD" : 1,
|
||||
"MOUSE" : 2,
|
||||
@ -38,6 +43,9 @@ REPORT_IDS = {
|
||||
"SYS_CONTROL" : 4,
|
||||
"GAMEPAD" : 5,
|
||||
"DIGITIZER" : 6,
|
||||
"XAC_COMPATIBLE_GAMEPAD" : 7,
|
||||
# RAW must not have a report ID, so it can't be used with other devices.
|
||||
"RAW" : 0,
|
||||
}
|
||||
|
||||
# Byte count for each kind of report. Length does not include report ID in first byte.
|
||||
@ -48,6 +56,8 @@ REPORT_LENGTHS = {
|
||||
"SYS_CONTROL" : 1,
|
||||
"GAMEPAD" : 6,
|
||||
"DIGITIZER" : 5,
|
||||
"XAC_COMPATIBLE_GAMEPAD" : 3,
|
||||
"RAW" : 64,
|
||||
}
|
||||
|
||||
KEYBOARD_WITH_ID = hid.ReportDescriptor(
|
||||
@ -228,6 +238,54 @@ DIGITIZER_WITH_ID = hid.ReportDescriptor(
|
||||
0xC0, # End Collection
|
||||
]))
|
||||
|
||||
XAC_COMPATIBLE_GAMEPAD_WITH_ID = hid.ReportDescriptor(
|
||||
description="XAC",
|
||||
report_descriptor=bytes([
|
||||
# This descriptor mimics the simple joystick from PDP that the XBox likes
|
||||
0x05, 0x01, # Usage Page (Desktop),
|
||||
0x09, 0x05, # Usage (Gamepad),
|
||||
0xA1, 0x01, # Collection (Application),
|
||||
0x85, REPORT_IDS["XAC_COMPATIBLE_GAMEPAD"], # Report ID (n)
|
||||
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
|
||||
]))
|
||||
|
||||
RAW = hid.ReportDescriptor(
|
||||
description="RAW",
|
||||
report_descriptor=bytes([
|
||||
# Provide vendor-defined
|
||||
0x06, 0xAF, 0xFF, # Usage Page (Vendor 0xFFAF "Adafruit"),
|
||||
0x09, 0xAF, # 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
|
||||
]))
|
||||
|
||||
# Byte count for each kind of report. Length does not include report ID in first byte.
|
||||
REPORT_DESCRIPTORS = {
|
||||
"KEYBOARD" : KEYBOARD_WITH_ID,
|
||||
@ -236,4 +294,6 @@ REPORT_DESCRIPTORS = {
|
||||
"SYS_CONTROL" : SYS_CONTROL_WITH_ID,
|
||||
"GAMEPAD" : GAMEPAD_WITH_ID,
|
||||
"DIGITIZER" : DIGITIZER_WITH_ID,
|
||||
"XAC_COMPATIBLE_GAMEPAD" : XAC_COMPATIBLE_GAMEPAD_WITH_ID,
|
||||
"RAW" : RAW_WITH_ID,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user