tools: Switch to using separate usb_descriptor repo.

This commit is contained in:
Scott Shawcroft 2017-11-02 13:00:50 -07:00
parent 7b393bc406
commit a49200d5cb
5 changed files with 33 additions and 270 deletions

3
.gitmodules vendored
View File

@ -37,3 +37,6 @@
path = ports/atmel-samd/asf4
url = https://github.com/adafruit/asf4.git
branch = circuitpython
[submodule "tools/usb_descriptor"]
path = tools/usb_descriptor
url = https://github.com/adafruit/usb_descriptor.git

View File

@ -4,10 +4,9 @@ import os
import sys
# path hacking
sys.path.append("../../tools")
sys.path.append("../../tools/usb_descriptor")
from usb_descriptor import core
from usb_descriptor import cdc
from adafruit_usb_descriptor import cdc, standard, util
parser = argparse.ArgumentParser(description='Generate USB descriptors.')
parser.add_argument('--manufacturer', type=str,
@ -24,16 +23,16 @@ parser.add_argument('output_file', type=argparse.FileType('w'))
args = parser.parse_args()
langid = core.StringDescriptor("\u0409")
manufacturer = core.StringDescriptor(args.manufacturer)
product = core.StringDescriptor(args.product)
serial_number = core.StringDescriptor("serial number. you should fill in a unique serial number here."[:args.serial_number_length])
langid = standard.StringDescriptor("\u0409")
manufacturer = standard.StringDescriptor(args.manufacturer)
product = standard.StringDescriptor(args.product)
serial_number = standard.StringDescriptor("serial number. you should fill in a unique serial number here."[:args.serial_number_length])
strings = [langid, manufacturer, product, serial_number]
# vid = 0x239A
# pid = 0x8021
device = core.DeviceDescriptor(
device = standard.DeviceDescriptor(
idVendor=args.vid,
idProduct=args.pid,
iManufacturer=strings.index(manufacturer),
@ -43,7 +42,7 @@ device = core.DeviceDescriptor(
# Interface numbers are interface set local and endpoints are interface local
# until core.join_interfaces renumbers them.
cdc_interfaces = [
core.InterfaceDescriptor(
standard.InterfaceDescriptor(
bInterfaceClass=0x2, # Communications Device Class
bInterfaceSubClass=0x02, # Abstract control model
bInterfaceProtocol=0x01, # Common AT Commands
@ -59,53 +58,53 @@ cdc_interfaces = [
cdc.AbstractControlManagement(bmCapabilities=0x02),
cdc.Union(bMasterInterface=0x00,
bSlaveInterface=[0x01]),
core.EndpointDescriptor(
bEndpointAddress=0x0 | core.EndpointDescriptor.DIRECTION_IN,
bmAttributes=core.EndpointDescriptor.TYPE_INTERRUPT,
standard.EndpointDescriptor(
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
wMaxPacketSize=0x8,
bInterval=10)
]
),
core.InterfaceDescriptor(
standard.InterfaceDescriptor(
bInterfaceClass=0x0a,
subdescriptors=[
core.EndpointDescriptor(
bEndpointAddress=0x0 | core.EndpointDescriptor.DIRECTION_IN,
bmAttributes=core.EndpointDescriptor.TYPE_BULK),
core.EndpointDescriptor(
bEndpointAddress=0x0 | core.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=core.EndpointDescriptor.TYPE_BULK)
standard.EndpointDescriptor(
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
standard.EndpointDescriptor(
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK)
]
)
]
msc_interfaces = [
core.InterfaceDescriptor(
standard.InterfaceDescriptor(
bInterfaceClass=0x08,
bInterfaceSubClass=0x06,
bInterfaceProtocol=0x50,
subdescriptors=[
core.EndpointDescriptor(
bEndpointAddress=0x0 | core.EndpointDescriptor.DIRECTION_IN,
bmAttributes=core.EndpointDescriptor.TYPE_BULK),
core.EndpointDescriptor(
bEndpointAddress=0x1 | core.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=core.EndpointDescriptor.TYPE_BULK)
standard.EndpointDescriptor(
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK),
standard.EndpointDescriptor(
bEndpointAddress=0x1 | standard.EndpointDescriptor.DIRECTION_OUT,
bmAttributes=standard.EndpointDescriptor.TYPE_BULK)
]
)
]
interfaces = core.join_interfaces(cdc_interfaces, msc_interfaces)
interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces)
cdc_function = core.InterfaceAssociationDescriptor(
cdc_function = standard.InterfaceAssociationDescriptor(
bFirstInterface=interfaces.index(cdc_interfaces[0]),
bInterfaceCount=len(cdc_interfaces),
bFunctionClass=0x2, # Communications Device Class
bFunctionSubClass=0x2, # Abstract control model
bFunctionProtocol=0x1) # Common AT Commands
configuration = core.ConfigurationDescriptor(
wTotalLength=(core.ConfigurationDescriptor.bLength +
configuration = standard.ConfigurationDescriptor(
wTotalLength=(standard.ConfigurationDescriptor.bLength +
cdc_function.bLength +
sum([len(bytes(x)) for x in interfaces])),
bNumInterfaces=len(interfaces))

1
tools/usb_descriptor Submodule

@ -0,0 +1 @@
Subproject commit a04341153b41b4728f9b42a77cbd51c495362287

View File

@ -1,53 +0,0 @@
from . import core
import struct
class FunctionalDescriptor(core.Descriptor):
bDescriptorType = 0x24
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fmt = "<BBB" + self.fmt[3:]
def __bytes__(self):
return struct.pack(self.fmt, self.bLength, self.bDescriptorType, self.bDescriptorSubtype, *self.data)
class Header(FunctionalDescriptor):
fields = [('bcdCDC', "H", None)]
bLength = 0x05
bDescriptorSubtype = 0x0
class CallManagement(FunctionalDescriptor):
fields = [('bmCapabilities', "b", None),
('bDataInterface', "b", None)]
bLength = 0x05
bDescriptorSubtype = 0x01
class AbstractControlManagement(FunctionalDescriptor):
fields = [('bmCapabilities', "b", None)]
bLength = 0x04
bDescriptorSubtype = 0x02
class DirectLineManagement(FunctionalDescriptor):
fields = [('bmCapabilities', "b", None)]
bLength = 0x04
bDescriptorSubtype = 0x03
class Union(FunctionalDescriptor):
fields = [('bMasterInterface', "b", None)]
bDescriptorSubtype = 0x06
def __init__(self, *args, **kwargs):
self.bSlaveInterface = kwargs["bSlaveInterface"]
super().__init__(*args, **kwargs)
def __bytes__(self):
return super().__bytes__() + bytes(self.bSlaveInterface)
@property
def bLength(self):
return 0x4 + len(self.bSlaveInterface)

View File

@ -1,187 +0,0 @@
import struct
def join_interfaces(*args):
interfaces = []
base_endpoint_number = 1
for interface_set in args:
base_interface_number = len(interfaces)
for i, interface in enumerate(interface_set):
interfaces.append(interface)
interface.bInterfaceNumber = interfaces.index(interface)
max_endpoint_address = base_endpoint_number
for subdescriptor in interface.subdescriptors:
if subdescriptor.bDescriptorType == EndpointDescriptor.bDescriptorType:
subdescriptor.bEndpointAddress += base_endpoint_number
max_endpoint_address = max(max_endpoint_address, subdescriptor.bEndpointAddress & 0xf)
base_endpoint_number = max_endpoint_address + 1
return interfaces
class Descriptor:
def __init__(self, *args, **kwargs):
self.fmt = ["<B", "B"]
for field in self.fields:
self.fmt.append(field[1])
self.fmt = "".join(self.fmt)
if len(args) == 1:
self.data = struct.unpack(self.fmt, args[0])
if self.data[1] != self.bDescriptorType:
raise RuntimeError("Descriptor type doesn't match.")
return
elif len(args) > 1:
raise TypeError("Only one arg or keyword args expected.")
elif len(kwargs) == 0:
raise TypeError("Only one arg or keyword args expected.")
self.data = []
for field, _, default in self.fields:
if field in kwargs:
self.data.append(kwargs[field])
elif default is not None:
self.data.append(default)
else:
raise ValueError("Missing {} argument.".format(field))
def __bytes__(self):
return struct.pack(self.fmt, self.bLength, self.bDescriptorType, *self.data)
@property
def bDescriptorType(self):
return self._bDescriptorType
class EndpointDescriptor(Descriptor):
fields = [('bEndpointAddress', "B", None),
('bmAttributes', "B", None),
('wMaxPacketSize', "H", 0x40),
('bInterval', "B", 0)]
bLength = 0x07
bDescriptorType = 0x5
TYPE_CONTROL = 0b00
TYPE_ISOCHRONOUS = 0b01
TYPE_BULK = 0b10
TYPE_INTERRUPT = 0b11
DIRECTION_IN = 0x80
DIRECTION_OUT = 0x00
@property
def bEndpointAddress(self):
return self.data[0]
@bEndpointAddress.setter
def bEndpointAddress(self, value):
self.data[0] = value
class InterfaceDescriptor(Descriptor):
fields = [('bInterfaceNumber', "B", 0),
('bAlternateSetting', "B", 0),
('bNumEndpoints', "B", 0),
('bInterfaceClass', "B", None),
('bInterfaceSubClass', "B", 0),
('bInterfaceProtocol', "B", 0),
('iInterface', "B", 0)]
bLength = 0x09
bDescriptorType = 0x4
def __init__(self, *args, **kwargs):
self.subdescriptors = []
if "subdescriptors" in kwargs:
self.subdescriptors = kwargs["subdescriptors"]
super().__init__(*args, **kwargs)
def __bytes__(self):
endpoint_count = 0
subdescriptor_bytes = []
for desc in self.subdescriptors:
subdescriptor_bytes.append(bytes(desc))
if desc.bDescriptorType == EndpointDescriptor.bDescriptorType:
endpoint_count += 1
subdescriptor_bytes = b"".join(subdescriptor_bytes)
self.data[2] = endpoint_count
return super().__bytes__() + subdescriptor_bytes
@property
def bInterfaceNumber(self):
return self.data[0]
@bInterfaceNumber.setter
def bInterfaceNumber(self, value):
self.data[0] = value
class InterfaceAssociationDescriptor(Descriptor):
fields = [('bFirstInterface', "B", None),
('bInterfaceCount', "B", None),
('bFunctionClass', "B", None),
('bFunctionSubClass', "B", None),
('bFunctionProtocol', "B", None),
('iFunction', "B", 0)]
bLength = 0x08
bDescriptorType = 0xB
class ConfigurationDescriptor(Descriptor):
fields = [('wTotalLength', "H", None),
('bNumInterfaces', "B", None),
('bConfigurationValue', "B", 0x1),
('iConfiguration', "B", 0),
# bus powered (bit 6), no remote wakeup (bit 5), bit 7 is always 1 and 0-4 are always 0
('bmAttributes', "B", 0x80),
# 100 mA by default
('bMaxPower', "B", 50)]
bLength = 0x09
bDescriptorType = 0x2
class DeviceDescriptor(Descriptor):
fields = [('bcdUSB', "H", 0x200),
('bDeviceClass', "B", 0xef),
('bDeviceSubClass', "B", 0x02),
('bDeviceProtocol', "B", 0x01),
('bMaxPacketSize0', "B", 0x40),
('idVendor', "H", None),
('idProduct', "H", None),
('bcdDevice', "H", 0x100),
('iManufacturer', "B", None),
('iProduct', "B", None),
('iSerialNumber', "B", None),
('bNumConfigurations', "B", 1)]
bLength = 0x12
bDescriptorType = 0x1
class StringDescriptor:
def __init__(self, value):
if type(value) == str:
self._bString = value.encode("utf-16-le")
self._bLength = len(self._bString) + 2
elif len(value) > 1:
self._bLength = value[0]
if value[1] != 3:
raise ValueError("Sequence not a StringDescriptor")
self._bString = value[2:2+self.bLength]
def __bytes__(self):
return struct.pack("BB{}s".format(len(self._bString)), self.bLength, self.bDescriptorType, self._bString)
@property
def bString(self):
return self._bString.decode("utf-16-le")
@bString.setter
def bString(self, value):
self._bString = value.encode("utf-16-le")
self._bLength = len(self.encoded) + 2
@property
def bDescriptorType(self):
return 3
@property
def bLength(self):
return self._bLength