diff options
author | deadprogram <[email protected]> | 2022-07-12 22:31:23 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2022-07-14 07:20:50 +0200 |
commit | 3c2d2a93d324fd7de127a7bdd09fabde90acd471 (patch) | |
tree | b02f49f767721f97cee4aaf3676e04bb0dbe1ece /src/machine/usb | |
parent | ea36fea5a9382589a31e35e6a12b56f3bea290c7 (diff) | |
download | tinygo-3c2d2a93d324fd7de127a7bdd09fabde90acd471.tar.gz tinygo-3c2d2a93d324fd7de127a7bdd09fabde90acd471.zip |
machine/usb: refactorings to move functionality under machine/usb package
Signed-off-by: deadprogram <[email protected]>
Diffstat (limited to 'src/machine/usb')
-rw-r--r-- | src/machine/usb/cdc/usbcdc.go | 3 | ||||
-rw-r--r-- | src/machine/usb/descriptor.go | 117 | ||||
-rw-r--r-- | src/machine/usb/hid/hid.go | 3 | ||||
-rw-r--r-- | src/machine/usb/usb.go | 121 |
4 files changed, 242 insertions, 2 deletions
diff --git a/src/machine/usb/cdc/usbcdc.go b/src/machine/usb/cdc/usbcdc.go index a21089688..b341f4948 100644 --- a/src/machine/usb/cdc/usbcdc.go +++ b/src/machine/usb/cdc/usbcdc.go @@ -3,6 +3,7 @@ package cdc import ( "errors" "machine" + "machine/usb" "runtime/interrupt" ) @@ -128,7 +129,7 @@ func cdcCallbackRx(b []byte) { } } -func cdcSetup(setup machine.USBSetup) bool { +func cdcSetup(setup usb.Setup) bool { if setup.BmRequestType == usb_REQUEST_DEVICETOHOST_CLASS_INTERFACE { if setup.BRequest == usb_CDC_GET_LINE_CODING { var b [cdcLineInfoSize]byte diff --git a/src/machine/usb/descriptor.go b/src/machine/usb/descriptor.go new file mode 100644 index 000000000..6435c2b5d --- /dev/null +++ b/src/machine/usb/descriptor.go @@ -0,0 +1,117 @@ +package usb + +import "runtime/volatile" + +// DeviceDescBank is the USB device endpoint descriptor. +type DeviceDescBank struct { + ADDR volatile.Register32 + PCKSIZE volatile.Register32 + EXTREG volatile.Register16 + STATUS_BK volatile.Register8 + _reserved [5]volatile.Register8 +} + +type DeviceDescriptor struct { + DeviceDescBank [2]DeviceDescBank +} + +type Descriptor struct { + Device []byte + Configuration []byte + HID map[uint16][]byte +} + +func (d *Descriptor) Configure(idVendor, idProduct uint16) { + d.Device[8] = byte(idVendor) + d.Device[9] = byte(idVendor >> 8) + d.Device[10] = byte(idProduct) + d.Device[11] = byte(idProduct >> 8) + + d.Configuration[2] = byte(len(d.Configuration)) + d.Configuration[3] = byte(len(d.Configuration) >> 8) +} + +var DescriptorCDC = Descriptor{ + Device: []byte{ + 0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, + }, + Configuration: []byte{ + 0x09, 0x02, 0x4b, 0x00, 0x02, 0x01, 0x00, 0xa0, 0x32, + 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, + 0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, + 0x05, 0x24, 0x00, 0x10, 0x01, + 0x04, 0x24, 0x02, 0x06, + 0x05, 0x24, 0x06, 0x00, 0x01, + 0x05, 0x24, 0x01, 0x01, 0x01, + 0x07, 0x05, 0x81, 0x03, 0x10, 0x00, 0x10, + 0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, + 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, + 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, + }, +} + +var DescriptorCDCHID = Descriptor{ + Device: []byte{ + 0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, + }, + Configuration: []byte{ + 0x09, 0x02, 0x64, 0x00, 0x03, 0x01, 0x00, 0xa0, 0x32, + 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, + 0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, + 0x05, 0x24, 0x00, 0x10, 0x01, + 0x04, 0x24, 0x02, 0x06, + 0x05, 0x24, 0x06, 0x00, 0x01, + 0x05, 0x24, 0x01, 0x01, 0x01, + 0x07, 0x05, 0x81, 0x03, 0x10, 0x00, 0x10, + 0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, + 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, + 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, + 0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x09, 0x21, 0x01, 0x01, 0x00, 0x01, 0x22, 0x65, 0x00, + 0x07, 0x05, 0x84, 0x03, 0x40, 0x00, 0x01, + }, + HID: map[uint16][]byte{ + 2: []byte{ + // keyboard and mouse + 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x85, 0x02, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, + 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x03, 0x95, 0x06, + 0x75, 0x08, 0x15, 0x00, 0x25, 0x73, 0x05, 0x07, 0x19, 0x00, 0x29, 0x73, 0x81, 0x00, 0xc0, 0x05, + 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x85, 0x01, 0x05, 0x09, 0x19, 0x01, 0x29, + 0x03, 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, + 0x03, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, + 0x03, 0x81, 0x06, 0xc0, 0xc0, + }, + }, +} + +var DescriptorCDCMIDI = Descriptor{ + Device: []byte{ + 0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, + }, + Configuration: []byte{ + 0x09, 0x02, 0xaf, 0x00, 0x04, 0x01, 0x00, 0xa0, 0x32, + 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, + 0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, + 0x05, 0x24, 0x00, 0x10, 0x01, + 0x04, 0x24, 0x02, 0x06, + 0x05, 0x24, 0x06, 0x00, 0x01, + 0x05, 0x24, 0x01, 0x01, 0x01, + 0x07, 0x05, 0x81, 0x03, 0x10, 0x00, 0x10, + 0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, + 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, + 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, + 0x08, 0x0b, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, + 0x09, 0x04, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x03, + 0x09, 0x04, 0x03, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, + 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, + 0x06, 0x24, 0x02, 0x01, 0x01, 0x00, + 0x06, 0x24, 0x02, 0x02, 0x02, 0x00, + 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, + 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x01, 0x01, 0x00, + 0x09, 0x05, 0x05, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x25, 0x01, 0x01, 0x01, + 0x09, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x25, 0x01, 0x01, 0x03, + }, +} diff --git a/src/machine/usb/hid/hid.go b/src/machine/usb/hid/hid.go index dd8db2047..4f4072419 100644 --- a/src/machine/usb/hid/hid.go +++ b/src/machine/usb/hid/hid.go @@ -3,6 +3,7 @@ package hid import ( "errors" "machine" + "machine/usb" ) // from usb-hid.go @@ -48,7 +49,7 @@ func handler() { } } -func setupHandler(setup machine.USBSetup) bool { +func setupHandler(setup usb.Setup) bool { ok := false if setup.BmRequestType == usb_SET_REPORT_TYPE && setup.BRequest == usb_SET_IDLE { machine.SendZlp() diff --git a/src/machine/usb/usb.go b/src/machine/usb/usb.go new file mode 100644 index 000000000..592b32beb --- /dev/null +++ b/src/machine/usb/usb.go @@ -0,0 +1,121 @@ +package usb + +var ( + // TODO: allow setting these + STRING_LANGUAGE = [2]uint16{(3 << 8) | (2 + 2), 0x0409} // English +) + +const ( + DescriptorConfigCDC = 1 << iota + DescriptorConfigHID + DescriptorConfigMIDI +) + +const ( + IMANUFACTURER = 1 + IPRODUCT = 2 + ISERIAL = 3 + + ENDPOINT_TYPE_DISABLE = 0xFF + ENDPOINT_TYPE_CONTROL = 0x00 + ENDPOINT_TYPE_ISOCHRONOUS = 0x01 + ENDPOINT_TYPE_BULK = 0x02 + ENDPOINT_TYPE_INTERRUPT = 0x03 + + DEVICE_DESCRIPTOR_TYPE = 1 + CONFIGURATION_DESCRIPTOR_TYPE = 2 + STRING_DESCRIPTOR_TYPE = 3 + INTERFACE_DESCRIPTOR_TYPE = 4 + ENDPOINT_DESCRIPTOR_TYPE = 5 + DEVICE_QUALIFIER = 6 + OTHER_SPEED_CONFIGURATION = 7 + SET_REPORT_TYPE = 33 + HID_REPORT_TYPE = 34 + + EndpointOut = 0x00 + EndpointIn = 0x80 + + NumberOfEndpoints = 8 + EndpointPacketSize = 64 // 64 for Full Speed, EPT size max is 1024 + + // standard requests + GET_STATUS = 0 + CLEAR_FEATURE = 1 + SET_FEATURE = 3 + SET_ADDRESS = 5 + GET_DESCRIPTOR = 6 + SET_DESCRIPTOR = 7 + GET_CONFIGURATION = 8 + SET_CONFIGURATION = 9 + GET_INTERFACE = 10 + SET_INTERFACE = 11 + + // non standard requests + SET_IDLE = 10 + + DEVICE_CLASS_COMMUNICATIONS = 0x02 + DEVICE_CLASS_HUMAN_INTERFACE = 0x03 + DEVICE_CLASS_STORAGE = 0x08 + DEVICE_CLASS_VENDOR_SPECIFIC = 0xFF + + CONFIG_POWERED_MASK = 0x40 + CONFIG_BUS_POWERED = 0x80 + CONFIG_SELF_POWERED = 0xC0 + CONFIG_REMOTE_WAKEUP = 0x20 + + // Interface + NumberOfInterfaces = 3 + CDC_ACM_INTERFACE = 0 // CDC ACM + CDC_DATA_INTERFACE = 1 // CDC Data + CDC_FIRST_ENDPOINT = 1 + HID_INTERFACE = 2 // HID + + // Endpoint + CONTROL_ENDPOINT = 0 + CDC_ENDPOINT_ACM = 1 + CDC_ENDPOINT_OUT = 2 + CDC_ENDPOINT_IN = 3 + HID_ENDPOINT_IN = 4 + MIDI_ENDPOINT_OUT = 5 + MIDI_ENDPOINT_IN = 6 + + // bmRequestType + REQUEST_HOSTTODEVICE = 0x00 + REQUEST_DEVICETOHOST = 0x80 + REQUEST_DIRECTION = 0x80 + + REQUEST_STANDARD = 0x00 + REQUEST_CLASS = 0x20 + REQUEST_VENDOR = 0x40 + REQUEST_TYPE = 0x60 + + REQUEST_DEVICE = 0x00 + REQUEST_INTERFACE = 0x01 + REQUEST_ENDPOINT = 0x02 + REQUEST_OTHER = 0x03 + REQUEST_RECIPIENT = 0x1F + + REQUEST_DEVICETOHOST_CLASS_INTERFACE = (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE) + REQUEST_HOSTTODEVICE_CLASS_INTERFACE = (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE) + REQUEST_DEVICETOHOST_STANDARD_INTERFACE = (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE) +) + +type Setup struct { + BmRequestType uint8 + BRequest uint8 + WValueL uint8 + WValueH uint8 + WIndex uint16 + WLength uint16 +} + +func NewSetup(data []byte) Setup { + u := Setup{} + u.BmRequestType = uint8(data[0]) + u.BRequest = uint8(data[1]) + u.WValueL = uint8(data[2]) + u.WValueH = uint8(data[3]) + u.WIndex = uint16(data[4]) | (uint16(data[5]) << 8) + u.WLength = uint16(data[6]) | (uint16(data[7]) << 8) + return u +} |