mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-24 06:19:04 +00:00
machine/usb: support bidirectional endpoints by dynamic registration (#5447)
* machine/usb: support bidirectional endpoints by dynamic registration
This commit is contained in:
@@ -44,7 +44,7 @@ func TestBinarySize(t *testing.T) {
|
|||||||
// microcontrollers
|
// microcontrollers
|
||||||
{"hifive1b", "examples/echo", 3817, 299, 0, 2252},
|
{"hifive1b", "examples/echo", 3817, 299, 0, 2252},
|
||||||
{"microbit", "examples/serial", 2820, 356, 8, 2248},
|
{"microbit", "examples/serial", 2820, 356, 8, 2248},
|
||||||
{"wioterminal", "examples/pininterrupt", 7330, 1550, 120, 7248},
|
{"wioterminal", "examples/pininterrupt", 7930, 1650, 132, 7472},
|
||||||
|
|
||||||
// TODO: also check wasm. Right now this is difficult, because
|
// TODO: also check wasm. Right now this is difficult, because
|
||||||
// wasm binaries are run through wasm-opt and therefore the
|
// wasm binaries are run through wasm-opt and therefore the
|
||||||
|
|||||||
@@ -23,19 +23,6 @@ const (
|
|||||||
NumberOfUSBEndpoints = 8
|
NumberOfUSBEndpoints = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
endPoints = []uint32{
|
|
||||||
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
|
|
||||||
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
|
|
||||||
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
|
|
||||||
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
|
|
||||||
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
|
|
||||||
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
|
|
||||||
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
|
|
||||||
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
|
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
|
||||||
func (dev *USBDevice) Configure(config UARTConfig) {
|
func (dev *USBDevice) Configure(config UARTConfig) {
|
||||||
if dev.initcomplete {
|
if dev.initcomplete {
|
||||||
|
|||||||
@@ -23,19 +23,6 @@ const (
|
|||||||
NumberOfUSBEndpoints = 8
|
NumberOfUSBEndpoints = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
endPoints = []uint32{
|
|
||||||
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
|
|
||||||
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
|
|
||||||
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
|
|
||||||
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
|
|
||||||
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
|
|
||||||
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
|
|
||||||
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
|
|
||||||
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
|
// Configure the USB peripheral. The config is here for compatibility with the UART interface.
|
||||||
func (dev *USBDevice) Configure(config UARTConfig) {
|
func (dev *USBDevice) Configure(config UARTConfig) {
|
||||||
if dev.initcomplete {
|
if dev.initcomplete {
|
||||||
|
|||||||
@@ -22,17 +22,6 @@ var (
|
|||||||
epinen uint32
|
epinen uint32
|
||||||
epouten uint32
|
epouten uint32
|
||||||
easyDMABusy volatile.Register8
|
easyDMABusy volatile.Register8
|
||||||
|
|
||||||
endPoints = []uint32{
|
|
||||||
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
|
|
||||||
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
|
|
||||||
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
|
|
||||||
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
|
|
||||||
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
|
|
||||||
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
|
|
||||||
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
|
|
||||||
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// enterCriticalSection is used to protect access to easyDMA - only one thing
|
// enterCriticalSection is used to protect access to easyDMA - only one thing
|
||||||
|
|||||||
@@ -16,17 +16,6 @@ var (
|
|||||||
data []byte
|
data []byte
|
||||||
pid uint32
|
pid uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
endPoints = []uint32{
|
|
||||||
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
|
|
||||||
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
|
|
||||||
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
|
|
||||||
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
|
|
||||||
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
|
|
||||||
usb.HID_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt Out
|
|
||||||
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
|
|
||||||
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initEndpoint(ep, config uint32) {
|
func initEndpoint(ep, config uint32) {
|
||||||
|
|||||||
+25
-4
@@ -14,9 +14,21 @@ type USBDevice struct {
|
|||||||
InitEndpointComplete bool
|
InitEndpointComplete bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type usbEndpointEntry struct {
|
||||||
|
Endpoint uint32
|
||||||
|
Config uint32
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
USBDev = &USBDevice{}
|
USBDev = &USBDevice{}
|
||||||
USBCDC Serialer
|
USBCDC Serialer
|
||||||
|
|
||||||
|
endPoints = []usbEndpointEntry{
|
||||||
|
{
|
||||||
|
Endpoint: usb.CONTROL_ENDPOINT,
|
||||||
|
Config: usb.ENDPOINT_TYPE_CONTROL,
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func initUSB() {
|
func initUSB() {
|
||||||
@@ -277,8 +289,11 @@ func handleStandardSetup(setup usb.Setup) bool {
|
|||||||
|
|
||||||
case usb.SET_CONFIGURATION:
|
case usb.SET_CONFIGURATION:
|
||||||
if setup.BmRequestType&usb.REQUEST_RECIPIENT == usb.REQUEST_DEVICE {
|
if setup.BmRequestType&usb.REQUEST_RECIPIENT == usb.REQUEST_DEVICE {
|
||||||
for i := 1; i < len(endPoints); i++ {
|
for _, entry := range endPoints {
|
||||||
initEndpoint(uint32(i), endPoints[i])
|
if entry.Endpoint == usb.CONTROL_ENDPOINT {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
initEndpoint(uint32(entry.Endpoint), entry.Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
usbConfiguration = setup.WValueL
|
usbConfiguration = setup.WValueL
|
||||||
@@ -359,12 +374,18 @@ func ConfigureUSBEndpoint(desc descriptor.Descriptor, epSettings []usb.EndpointC
|
|||||||
|
|
||||||
for _, ep := range epSettings {
|
for _, ep := range epSettings {
|
||||||
if ep.IsIn {
|
if ep.IsIn {
|
||||||
endPoints[ep.Index] = uint32(ep.Type | usb.EndpointIn)
|
endPoints = append(endPoints, usbEndpointEntry{
|
||||||
|
Endpoint: uint32(ep.Index),
|
||||||
|
Config: uint32(ep.Type | usb.EndpointIn),
|
||||||
|
})
|
||||||
if ep.TxHandler != nil {
|
if ep.TxHandler != nil {
|
||||||
usbTxHandler[ep.Index] = ep.TxHandler
|
usbTxHandler[ep.Index] = ep.TxHandler
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
endPoints[ep.Index] = uint32(ep.Type | usb.EndpointOut)
|
endPoints = append(endPoints, usbEndpointEntry{
|
||||||
|
Endpoint: uint32(ep.Index),
|
||||||
|
Config: uint32(ep.Type | usb.EndpointOut),
|
||||||
|
})
|
||||||
if ep.RxHandler != nil {
|
if ep.RxHandler != nil {
|
||||||
usbRxHandler[ep.Index] = func(b []byte) bool {
|
usbRxHandler[ep.Index] = func(b []byte) bool {
|
||||||
ep.RxHandler(b)
|
ep.RxHandler(b)
|
||||||
|
|||||||
Reference in New Issue
Block a user