mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-08 04:53:42 +00:00
refactor(usb): dynamic endpoint descriptor generation
Replace static endpoint variables with EndpointIN and EndpointOUT functions. Allows flexible endpoint remapping across USB configs. Map CDC, HID, MIDI and MSC USB devices to bidirectional endpoints consistently across different configurations.
This commit is contained in:
committed by
Ron Evans
parent
2328d1e799
commit
c3f1832d9a
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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{},
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user