aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/machine/usb
diff options
context:
space:
mode:
authordeadprogram <[email protected]>2022-07-12 22:31:23 +0200
committerRon Evans <[email protected]>2022-07-14 07:20:50 +0200
commit3c2d2a93d324fd7de127a7bdd09fabde90acd471 (patch)
treeb02f49f767721f97cee4aaf3676e04bb0dbe1ece /src/machine/usb
parentea36fea5a9382589a31e35e6a12b56f3bea290c7 (diff)
downloadtinygo-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.go3
-rw-r--r--src/machine/usb/descriptor.go117
-rw-r--r--src/machine/usb/hid/hid.go3
-rw-r--r--src/machine/usb/usb.go121
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
+}