diff --git a/builder/sizes_test.go b/builder/sizes_test.go index a51a371d8..e96577d9b 100644 --- a/builder/sizes_test.go +++ b/builder/sizes_test.go @@ -42,9 +42,9 @@ func TestBinarySize(t *testing.T) { // This is a small number of very diverse targets that we want to test. tests := []sizeTest{ // microcontrollers - {"hifive1b", "examples/echo", 3817, 299, 0, 2252}, - {"microbit", "examples/serial", 2820, 356, 8, 2248}, - {"wioterminal", "examples/pininterrupt", 8036, 1652, 132, 7480}, + {"hifive1b", "examples/echo", 3680, 280, 0, 2252}, + {"microbit", "examples/serial", 2694, 342, 8, 2248}, + {"wioterminal", "examples/pininterrupt", 7074, 1510, 120, 7248}, // TODO: also check wasm. Right now this is difficult, because // wasm binaries are run through wasm-opt and therefore the diff --git a/src/machine/usb/descriptor/cdc.go b/src/machine/usb/descriptor/cdc.go index ec72186e3..d32611ca7 100644 --- a/src/machine/usb/descriptor/cdc.go +++ b/src/machine/usb/descriptor/cdc.go @@ -150,6 +150,9 @@ var InterfaceCDCData = InterfaceType{ data: interfaceCDCData[:], } +// EP1 IN : CDC Call Management +// EP2 OUT: CDC OUT +// EP2 IN : CDC IN var CDC = Descriptor{ Device: DeviceCDC.Bytes(), Configuration: Append([][]byte{ @@ -160,9 +163,9 @@ var CDC = Descriptor{ ClassSpecificCDCCallManagement.Bytes(), ClassSpecificCDCACM.Bytes(), ClassSpecificCDCUnion.Bytes(), - EndpointEP1IN.Bytes(), + EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(), InterfaceCDCData.Bytes(), - EndpointEP2OUT.Bytes(), - EndpointEP3IN.Bytes(), + EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), + EndpointIN(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), }), } diff --git a/src/machine/usb/descriptor/endpoint.go b/src/machine/usb/descriptor/endpoint.go index 57a17060c..c918caed1 100644 --- a/src/machine/usb/descriptor/endpoint.go +++ b/src/machine/usb/descriptor/endpoint.go @@ -15,104 +15,44 @@ const ( TransferTypeInterrupt ) -var endpointEP1IN = [endpointTypeLen]byte{ - endpointTypeLen, - TypeEndpoint, - 0x81, // EndpointAddress - 0x03, // Attributes - 0x10, // MaxPacketSizeL - 0x00, // MaxPacketSizeH - 0x10, // Interval +type EndpointNumber uint8 + +const ( + EndpointEP1 EndpointNumber = iota + EndpointEP2 + EndpointEP3 + EndpointEP4 +) + +const ( + maxEndpoints = 4 +) + +var ( + endpointEPIn = [maxEndpoints][endpointTypeLen]byte{} + endpointEPOut = [maxEndpoints][endpointTypeLen]byte{} +) + +func EndpointIN(ep EndpointNumber, transferType uint8, maxPacketSize uint16, interval uint8) EndpointType { + e := EndpointType{data: endpointEPIn[ep][:]} + e.Length(endpointTypeLen) + e.Type(TypeEndpoint) + e.EndpointAddress(uint8(ep+1) | 0x80) // EndpointNumber is 0-based, addresses are 1-based + e.Attributes(transferType) + e.MaxPacketSize(maxPacketSize) + e.Interval(interval) + return e } -var EndpointEP1IN = EndpointType{ - data: endpointEP1IN[:], -} - -var endpointEP2OUT = [endpointTypeLen]byte{ - endpointTypeLen, - TypeEndpoint, - 0x02, // EndpointAddress - 0x02, // Attributes - 0x40, // MaxPacketSizeL - 0x00, // MaxPacketSizeH - 0x00, // Interval -} - -var EndpointEP2OUT = EndpointType{ - data: endpointEP2OUT[:], -} - -var endpointEP3IN = [endpointTypeLen]byte{ - endpointTypeLen, - TypeEndpoint, - 0x83, // EndpointAddress - 0x02, // Attributes - 0x40, // MaxPacketSizeL - 0x00, // MaxPacketSizeH - 0x00, // Interval -} - -var EndpointEP3IN = EndpointType{ - data: endpointEP3IN[:], -} - -var endpointEP4IN = [endpointTypeLen]byte{ - endpointTypeLen, - TypeEndpoint, - 0x84, // EndpointAddress - 0x03, // Attributes - 0x40, // MaxPacketSizeL - 0x00, // MaxPacketSizeH - 0x01, // Interval -} - -var EndpointEP4IN = EndpointType{ - data: endpointEP4IN[:], -} - -var endpointEP5OUT = [endpointTypeLen]byte{ - endpointTypeLen, - TypeEndpoint, - 0x05, // EndpointAddress - 0x03, // Attributes - 0x40, // MaxPacketSizeL - 0x00, // MaxPacketSizeH - 0x01, // Interval -} - -var EndpointEP5OUT = EndpointType{ - data: endpointEP5OUT[:], -} - -// Mass Storage Class bulk in endpoint -var endpointMSCIN = [endpointTypeLen]byte{ - endpointTypeLen, - TypeEndpoint, - 0x86, // EndpointAddress - TransferTypeBulk, // Attributes - 0x40, // MaxPacketSizeL (64 bytes) - 0x00, // MaxPacketSizeH - 0x00, // Interval -} - -var EndpointMSCIN = EndpointType{ - data: endpointMSCIN[:], -} - -// Mass Storage Class bulk out endpoint -var endpointMSCOUT = [endpointTypeLen]byte{ - endpointTypeLen, - TypeEndpoint, - 0x07, // EndpointAddress - TransferTypeBulk, // Attributes - 0x40, // MaxPacketSizeL (64 bytes) - 0x00, // MaxPacketSizeH - 0x00, // Interval -} - -var EndpointMSCOUT = EndpointType{ - data: endpointMSCOUT[:], +func EndpointOUT(ep EndpointNumber, transferType uint8, maxPacketSize uint16, interval uint8) EndpointType { + e := EndpointType{data: endpointEPOut[ep][:]} + e.Length(endpointTypeLen) + e.Type(TypeEndpoint) + e.EndpointAddress(uint8(ep + 1)) // EndpointNumber is 0-based, addresses are 1-based + e.Attributes(transferType) + e.MaxPacketSize(maxPacketSize) + e.Interval(interval) + return e } const ( diff --git a/src/machine/usb/descriptor/hid.go b/src/machine/usb/descriptor/hid.go index 06b980153..6ee9683c0 100644 --- a/src/machine/usb/descriptor/hid.go +++ b/src/machine/usb/descriptor/hid.go @@ -111,6 +111,11 @@ var ClassHID = ClassHIDType{ data: classHID[:], } +// EP1 IN : CDC Call Management +// EP2 OUT: CDC OUT +// EP2 IN : CDC IN +// EP3 OUT: HID OUT +// EP3 IN : HID IN var CDCHID = Descriptor{ Device: DeviceCDC.Bytes(), Configuration: Append([][]byte{ @@ -121,14 +126,14 @@ var CDCHID = Descriptor{ ClassSpecificCDCACM.Bytes(), ClassSpecificCDCUnion.Bytes(), ClassSpecificCDCCallManagement.Bytes(), - EndpointEP1IN.Bytes(), + EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(), InterfaceCDCData.Bytes(), - EndpointEP2OUT.Bytes(), - EndpointEP3IN.Bytes(), + EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), + EndpointIN(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), InterfaceHID.Bytes(), ClassHID.Bytes(), - EndpointEP4IN.Bytes(), - EndpointEP5OUT.Bytes(), + EndpointIN(EndpointEP3, TransferTypeInterrupt, 0x40, 0x01).Bytes(), + EndpointOUT(EndpointEP3, TransferTypeInterrupt, 0x40, 0x01).Bytes(), }), HID: map[uint16][]byte{ 2: Append([][]byte{ // Update ClassLength in classHID whenever the array length is modified! diff --git a/src/machine/usb/descriptor/joystick.go b/src/machine/usb/descriptor/joystick.go index 65756e0d6..725c3efa6 100644 --- a/src/machine/usb/descriptor/joystick.go +++ b/src/machine/usb/descriptor/joystick.go @@ -121,6 +121,11 @@ var JoystickDefaultHIDReport = Append([][]byte{ // CDCJoystick requires that you append the JoystickDescriptor // to the Configuration before using. This is in order to support // custom configurations. +// EP1 IN : CDC Call Management +// EP2 OUT: CDC OUT +// EP2 IN : CDC IN +// EP3 OUT: HID OUT +// EP3 IN : HID IN var CDCJoystick = Descriptor{ Device: DeviceJoystick.Bytes(), Configuration: Append([][]byte{ @@ -131,14 +136,14 @@ var CDCJoystick = Descriptor{ ClassSpecificCDCACM.Bytes(), ClassSpecificCDCUnion.Bytes(), ClassSpecificCDCCallManagement.Bytes(), - EndpointEP1IN.Bytes(), + EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(), InterfaceCDCData.Bytes(), - EndpointEP2OUT.Bytes(), - EndpointEP3IN.Bytes(), + EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), + EndpointIN(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), InterfaceHIDJoystick.Bytes(), ClassHIDJoystick.Bytes(), - EndpointEP4IN.Bytes(), - EndpointEP5OUT.Bytes(), + EndpointIN(EndpointEP3, TransferTypeInterrupt, 0x40, 0x01).Bytes(), + EndpointOUT(EndpointEP3, TransferTypeInterrupt, 0x40, 0x01).Bytes(), }), HID: map[uint16][]byte{}, } diff --git a/src/machine/usb/descriptor/midi.go b/src/machine/usb/descriptor/midi.go index fad81f31d..6524e0578 100644 --- a/src/machine/usb/descriptor/midi.go +++ b/src/machine/usb/descriptor/midi.go @@ -171,10 +171,10 @@ var ClassSpecificMIDIInEndpoint = ClassSpecificType{ const endpointMIDITypeLen = 9 -var endpointEP6IN = [endpointMIDITypeLen]byte{ +var endpointMIDIIN = [endpointMIDITypeLen]byte{ endpointMIDITypeLen, TypeEndpoint, - 0x86, // EndpointAddress + 0x83, // EndpointAddress 0x02, // Attributes 0x40, // MaxPacketSizeL 0x00, // MaxPacketSizeH @@ -183,14 +183,14 @@ var endpointEP6IN = [endpointMIDITypeLen]byte{ 0x00, // sync address } -var EndpointEP6IN = EndpointType{ - data: endpointEP6IN[:], +var EndpointMIDIIN = EndpointType{ + data: endpointMIDIIN[:], } -var endpointEP7OUT = [endpointMIDITypeLen]byte{ +var endpointMIDIOUT = [endpointMIDITypeLen]byte{ endpointMIDITypeLen, TypeEndpoint, - 0x07, // EndpointAddress + 0x03, // EndpointAddress 0x02, // Attributes 0x40, // MaxPacketSizeL 0x00, // MaxPacketSizeH @@ -199,8 +199,8 @@ var endpointEP7OUT = [endpointMIDITypeLen]byte{ 0x00, // sync address } -var EndpointEP7OUT = EndpointType{ - data: endpointEP7OUT[:], +var EndpointMIDIOUT = EndpointType{ + data: endpointMIDIOUT[:], } var configurationCDCMIDI = [configurationTypeLen]byte{ @@ -218,6 +218,11 @@ var ConfigurationCDCMIDI = ConfigurationType{ data: configurationCDCMIDI[:], } +// EP1 IN : CDC Call Management +// EP2 OUT: CDC OUT +// EP2 IN : CDC IN +// EP3 OUT: MIDI OUT (custom endpoint descriptor) +// EP3 IN : MIDI IN (custom endpoint descriptor) var CDCMIDI = Descriptor{ Device: DeviceCDC.Bytes(), Configuration: Append([][]byte{ @@ -228,10 +233,10 @@ var CDCMIDI = Descriptor{ ClassSpecificCDCACM.Bytes(), ClassSpecificCDCUnion.Bytes(), ClassSpecificCDCCallManagement.Bytes(), - EndpointEP1IN.Bytes(), + EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(), InterfaceCDCData.Bytes(), - EndpointEP2OUT.Bytes(), - EndpointEP3IN.Bytes(), + EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), + EndpointIN(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), InterfaceAssociationMIDI.Bytes(), InterfaceAudio.Bytes(), ClassSpecificAudioInterface.Bytes(), @@ -241,9 +246,9 @@ var CDCMIDI = Descriptor{ ClassSpecificMIDIInJack2.Bytes(), ClassSpecificMIDIOutJack1.Bytes(), ClassSpecificMIDIOutJack2.Bytes(), - EndpointEP7OUT.Bytes(), + EndpointMIDIOUT.Bytes(), ClassSpecificMIDIOutEndpoint.Bytes(), - EndpointEP6IN.Bytes(), + EndpointMIDIIN.Bytes(), ClassSpecificMIDIInEndpoint.Bytes(), }), } diff --git a/src/machine/usb/descriptor/msc.go b/src/machine/usb/descriptor/msc.go index 55c6ddd85..42e0088b9 100644 --- a/src/machine/usb/descriptor/msc.go +++ b/src/machine/usb/descriptor/msc.go @@ -52,7 +52,17 @@ var ConfigurationMSC = ConfigurationType{ data: configurationMSC[:], } +var ( + EndpointMSCIN = EndpointIN(EndpointEP3, TransferTypeBulk, 0x40, 0x00) + EndpointMSCOUT = EndpointOUT(EndpointEP3, TransferTypeBulk, 0x40, 0x00) +) + // Mass Storage Class +// EP1 IN : CDC Call Management +// EP2 OUT: CDC OUT +// EP2 IN : CDC IN +// EP3 OUT: MSC OUT +// EP3 IN : MSC IN var MSC = Descriptor{ Device: DeviceCDC.Bytes(), Configuration: Append([][]byte{ @@ -63,10 +73,10 @@ var MSC = Descriptor{ ClassSpecificCDCACM.Bytes(), ClassSpecificCDCUnion.Bytes(), ClassSpecificCDCCallManagement.Bytes(), - EndpointEP1IN.Bytes(), + EndpointIN(EndpointEP1, TransferTypeInterrupt, 0x10, 0x10).Bytes(), InterfaceCDCData.Bytes(), - EndpointEP2OUT.Bytes(), - EndpointEP3IN.Bytes(), + EndpointOUT(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), + EndpointIN(EndpointEP2, TransferTypeBulk, 0x40, 0x00).Bytes(), InterfaceAssociationMSC.Bytes(), InterfaceMSC.Bytes(), EndpointMSCIN.Bytes(), diff --git a/src/machine/usb/usb.go b/src/machine/usb/usb.go index 40983a9a3..1d2dad435 100644 --- a/src/machine/usb/usb.go +++ b/src/machine/usb/usb.go @@ -74,13 +74,13 @@ const ( CONTROL_ENDPOINT = 0 CDC_ENDPOINT_ACM = 1 CDC_ENDPOINT_OUT = 2 - CDC_ENDPOINT_IN = 3 - HID_ENDPOINT_IN = 4 // for Interrupt In - HID_ENDPOINT_OUT = 5 // for Interrupt Out - MIDI_ENDPOINT_IN = 6 // for Bulk In - MIDI_ENDPOINT_OUT = 7 // for Bulk Out - MSC_ENDPOINT_IN = 6 // for Bulk In - MSC_ENDPOINT_OUT = 7 // for Bulk Out + CDC_ENDPOINT_IN = 2 + HID_ENDPOINT_IN = 3 // for Interrupt In + HID_ENDPOINT_OUT = 3 // for Interrupt Out + MIDI_ENDPOINT_IN = 3 // for Bulk In + MIDI_ENDPOINT_OUT = 3 // for Bulk Out + MSC_ENDPOINT_IN = 3 // for Bulk In + MSC_ENDPOINT_OUT = 3 // for Bulk Out // bmRequestType REQUEST_HOSTTODEVICE = 0x00