machine/usb: allow USB Endpoint settings to be changed externally
Этот коммит содержится в:
родитель
d1eb642d45
коммит
069e4f0d98
5 изменённых файлов: 130 добавлений и 46 удалений
|
@ -263,47 +263,52 @@ func EnableCDC(txHandler func(), rxHandler func([]byte), setupHandler func(usb.S
|
|||
usbDescriptor = descriptor.CDC
|
||||
}
|
||||
// Initialization of endpoints is required even for non-CDC
|
||||
endPoints[usb.CDC_ENDPOINT_ACM] = (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn)
|
||||
endPoints[usb.CDC_ENDPOINT_OUT] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut)
|
||||
endPoints[usb.CDC_ENDPOINT_IN] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn)
|
||||
usbRxHandler[usb.CDC_ENDPOINT_OUT] = rxHandler
|
||||
usbTxHandler[usb.CDC_ENDPOINT_IN] = txHandler
|
||||
usbSetupHandler[usb.CDC_ACM_INTERFACE] = setupHandler // 0x02 (Communications and CDC Control)
|
||||
usbSetupHandler[usb.CDC_DATA_INTERFACE] = nil // 0x0A (CDC-Data)
|
||||
ConfigureUSBEndpoint(usbDescriptor,
|
||||
[]usb.EndpointConfig{
|
||||
{
|
||||
No: usb.CDC_ENDPOINT_ACM,
|
||||
IsIn: true,
|
||||
Type: usb.ENDPOINT_TYPE_INTERRUPT,
|
||||
},
|
||||
{
|
||||
No: usb.CDC_ENDPOINT_OUT,
|
||||
IsIn: false,
|
||||
Type: usb.ENDPOINT_TYPE_BULK,
|
||||
RxHandler: rxHandler,
|
||||
},
|
||||
{
|
||||
No: usb.CDC_ENDPOINT_IN,
|
||||
IsIn: true,
|
||||
Type: usb.ENDPOINT_TYPE_BULK,
|
||||
TxHandler: txHandler,
|
||||
},
|
||||
},
|
||||
[]usb.SetupConfig{
|
||||
{
|
||||
No: usb.CDC_ACM_INTERFACE,
|
||||
Handler: setupHandler,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// EnableHID enables HID. This function must be executed from the init().
|
||||
func EnableHID(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool) {
|
||||
usbDescriptor = descriptor.CDCHID
|
||||
endPoints[usb.HID_ENDPOINT_IN] = (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn)
|
||||
usbTxHandler[usb.HID_ENDPOINT_IN] = txHandler
|
||||
usbSetupHandler[usb.HID_INTERFACE] = setupHandler // 0x03 (HID - Human Interface Device)
|
||||
}
|
||||
func ConfigureUSBEndpoint(desc descriptor.Descriptor, epSettings []usb.EndpointConfig, setup []usb.SetupConfig) {
|
||||
usbDescriptor = desc
|
||||
|
||||
// EnableMIDI enables MIDI. This function must be executed from the init().
|
||||
func EnableMIDI(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool) {
|
||||
usbDescriptor = descriptor.CDCMIDI
|
||||
endPoints[usb.MIDI_ENDPOINT_OUT] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut)
|
||||
endPoints[usb.MIDI_ENDPOINT_IN] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn)
|
||||
usbRxHandler[usb.MIDI_ENDPOINT_OUT] = rxHandler
|
||||
usbTxHandler[usb.MIDI_ENDPOINT_IN] = txHandler
|
||||
}
|
||||
|
||||
// EnableJoystick enables HID. This function must be executed from the init().
|
||||
func EnableJoystick(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool, hidDesc []byte) {
|
||||
class, err := descriptor.FindClassHIDType(descriptor.CDCJoystick.Configuration, descriptor.ClassHIDJoystick.Bytes())
|
||||
if err != nil {
|
||||
// TODO: some way to notify about error
|
||||
return
|
||||
for _, ep := range epSettings {
|
||||
if ep.IsIn {
|
||||
endPoints[ep.No] = uint32(ep.Type | usb.EndpointIn)
|
||||
if ep.TxHandler != nil {
|
||||
usbTxHandler[ep.No] = ep.TxHandler
|
||||
}
|
||||
} else {
|
||||
endPoints[ep.No] = uint32(ep.Type | usb.EndpointOut)
|
||||
if ep.RxHandler != nil {
|
||||
usbRxHandler[ep.No] = ep.RxHandler
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class.ClassLength(uint16(len(hidDesc)))
|
||||
descriptor.CDCJoystick.HID[2] = hidDesc
|
||||
|
||||
usbDescriptor = descriptor.CDCJoystick
|
||||
endPoints[usb.HID_ENDPOINT_OUT] = (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut)
|
||||
usbRxHandler[usb.HID_ENDPOINT_OUT] = rxHandler
|
||||
endPoints[usb.HID_ENDPOINT_IN] = (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn)
|
||||
usbTxHandler[usb.HID_ENDPOINT_IN] = txHandler
|
||||
usbSetupHandler[usb.HID_INTERFACE] = setupHandler // 0x03 (HID - Human Interface Device)
|
||||
for _, s := range setup {
|
||||
usbSetupHandler[s.No] = s.Handler
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package midi
|
|||
import (
|
||||
"machine"
|
||||
"machine/usb"
|
||||
"machine/usb/descriptor"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -40,7 +41,23 @@ func newMidi() *midi {
|
|||
m := &midi{
|
||||
buf: NewRingBuffer(),
|
||||
}
|
||||
machine.EnableMIDI(m.Handler, m.RxHandler, nil)
|
||||
machine.ConfigureUSBEndpoint(descriptor.CDCMIDI,
|
||||
[]usb.EndpointConfig{
|
||||
{
|
||||
No: usb.MIDI_ENDPOINT_OUT,
|
||||
IsIn: false,
|
||||
Type: usb.ENDPOINT_TYPE_BULK,
|
||||
RxHandler: m.RxHandler,
|
||||
},
|
||||
{
|
||||
No: usb.MIDI_ENDPOINT_IN,
|
||||
IsIn: true,
|
||||
Type: usb.ENDPOINT_TYPE_BULK,
|
||||
TxHandler: m.Handler,
|
||||
},
|
||||
},
|
||||
[]usb.SetupConfig{},
|
||||
)
|
||||
return m
|
||||
}
|
||||
|
||||
|
|
14
src/machine/usb/config.go
Обычный файл
14
src/machine/usb/config.go
Обычный файл
|
@ -0,0 +1,14 @@
|
|||
package usb
|
||||
|
||||
type EndpointConfig struct {
|
||||
No uint8
|
||||
IsIn bool
|
||||
TxHandler func()
|
||||
RxHandler func([]byte)
|
||||
Type uint8
|
||||
}
|
||||
|
||||
type SetupConfig struct {
|
||||
No uint8
|
||||
Handler func(Setup) bool
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"machine"
|
||||
"machine/usb"
|
||||
"machine/usb/descriptor"
|
||||
)
|
||||
|
||||
// from usb-hid.go
|
||||
|
@ -32,7 +33,21 @@ var size int
|
|||
// calls machine.EnableHID for USB configuration
|
||||
func SetHandler(d hidDevicer) {
|
||||
if size == 0 {
|
||||
machine.EnableHID(handler, nil, setupHandler)
|
||||
machine.ConfigureUSBEndpoint(descriptor.CDCHID,
|
||||
[]usb.EndpointConfig{
|
||||
{
|
||||
No: usb.HID_ENDPOINT_IN,
|
||||
IsIn: true,
|
||||
Type: usb.ENDPOINT_TYPE_INTERRUPT,
|
||||
TxHandler: handler,
|
||||
},
|
||||
},
|
||||
[]usb.SetupConfig{
|
||||
{
|
||||
No: usb.HID_INTERFACE,
|
||||
Handler: setupHandler,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
devices[size] = d
|
||||
|
|
|
@ -3,6 +3,7 @@ package joystick
|
|||
import (
|
||||
"machine"
|
||||
"machine/usb"
|
||||
"machine/usb/descriptor"
|
||||
"machine/usb/hid"
|
||||
)
|
||||
|
||||
|
@ -32,18 +33,50 @@ func UseSettings(def Definitions, rxHandlerFunc func(b []byte), setupFunc func(s
|
|||
if setupFunc == nil {
|
||||
setupFunc = hid.DefaultSetupHandler
|
||||
}
|
||||
machine.EnableJoystick(js.handler, rxHandlerFunc, setupFunc, hidDesc)
|
||||
if rxHandlerFunc == nil {
|
||||
rxHandlerFunc = js.rxHandlerFunc
|
||||
}
|
||||
if len(hidDesc) == 0 {
|
||||
hidDesc = descriptor.JoystickDefaultHIDReport
|
||||
}
|
||||
class, err := descriptor.FindClassHIDType(descriptor.CDCJoystick.Configuration, descriptor.ClassHIDJoystick.Bytes())
|
||||
if err != nil {
|
||||
// TODO: some way to notify about error
|
||||
return nil
|
||||
}
|
||||
|
||||
class.ClassLength(uint16(len(hidDesc)))
|
||||
descriptor.CDCJoystick.HID[2] = hidDesc
|
||||
|
||||
machine.ConfigureUSBEndpoint(descriptor.CDCJoystick,
|
||||
[]usb.EndpointConfig{
|
||||
{
|
||||
No: usb.HID_ENDPOINT_OUT,
|
||||
IsIn: false,
|
||||
Type: usb.ENDPOINT_TYPE_INTERRUPT,
|
||||
RxHandler: rxHandlerFunc,
|
||||
},
|
||||
{
|
||||
No: usb.HID_ENDPOINT_IN,
|
||||
IsIn: true,
|
||||
Type: usb.ENDPOINT_TYPE_INTERRUPT,
|
||||
TxHandler: js.handler,
|
||||
},
|
||||
},
|
||||
[]usb.SetupConfig{
|
||||
{
|
||||
No: usb.HID_INTERFACE,
|
||||
Handler: setupFunc,
|
||||
},
|
||||
},
|
||||
)
|
||||
Joystick = js
|
||||
return js
|
||||
}
|
||||
|
||||
func newDefaultJoystick() *joystick {
|
||||
def := DefaultDefinitions()
|
||||
js := &joystick{
|
||||
State: def.NewState(),
|
||||
buf: hid.NewRingBuffer(),
|
||||
}
|
||||
machine.EnableJoystick(js.handler, js.rxHandler, hid.DefaultSetupHandler, def.Descriptor())
|
||||
js := UseSettings(def, nil, nil, nil)
|
||||
return js
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче