machine/usb/hid/joystick: move joystick under HID as it belongs and also remove duplicate code
Signed-off-by: deadprogram <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
7d83e76833
коммит
9e97566b5f
6 изменённых файлов: 80 добавлений и 150 удалений
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"machine/usb/joystick"
|
"machine/usb/hid/joystick"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,6 +50,8 @@ func handler() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var DefaultSetupHandler = setupHandler
|
||||||
|
|
||||||
func setupHandler(setup usb.Setup) bool {
|
func setupHandler(setup usb.Setup) bool {
|
||||||
ok := false
|
ok := false
|
||||||
if setup.BmRequestType == usb.SET_REPORT_TYPE && setup.BRequest == usb.SET_IDLE {
|
if setup.BmRequestType == usb.SET_REPORT_TYPE && setup.BRequest == usb.SET_IDLE {
|
||||||
|
|
77
src/machine/usb/hid/joystick/joystick.go
Обычный файл
77
src/machine/usb/hid/joystick/joystick.go
Обычный файл
|
@ -0,0 +1,77 @@
|
||||||
|
package joystick
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"machine/usb"
|
||||||
|
"machine/usb/hid"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Joystick *joystick
|
||||||
|
|
||||||
|
type joystick struct {
|
||||||
|
State
|
||||||
|
buf *hid.RingBuffer
|
||||||
|
waitTxc bool
|
||||||
|
rxHandlerFunc func(b []byte)
|
||||||
|
setupFunc func(setup usb.Setup) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if Joystick == nil {
|
||||||
|
Joystick = newJoystick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newJoystick() *joystick {
|
||||||
|
def := DefaultDefinitions()
|
||||||
|
js := &joystick{
|
||||||
|
State: def.NewState(),
|
||||||
|
buf: hid.NewRingBuffer(),
|
||||||
|
}
|
||||||
|
machine.EnableJoystick(js.handler, js.rxHandler, hid.DefaultSetupHandler, def.Descriptor())
|
||||||
|
return js
|
||||||
|
}
|
||||||
|
|
||||||
|
// Port returns the USB Joystick port.
|
||||||
|
func Port() *joystick {
|
||||||
|
return Joystick
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *joystick) handler() {
|
||||||
|
m.waitTxc = false
|
||||||
|
if b, ok := m.buf.Get(); ok {
|
||||||
|
m.waitTxc = true
|
||||||
|
hid.SendUSBPacket(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *joystick) tx(b []byte) {
|
||||||
|
if machine.USBDev.InitEndpointComplete {
|
||||||
|
if m.waitTxc {
|
||||||
|
m.buf.Put(b)
|
||||||
|
} else {
|
||||||
|
m.waitTxc = true
|
||||||
|
hid.SendUSBPacket(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *joystick) ready() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *joystick) rxHandler(b []byte) {
|
||||||
|
if m.rxHandlerFunc != nil {
|
||||||
|
m.rxHandlerFunc(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// to InterruptOut
|
||||||
|
func (m *joystick) SendReport(reportID byte, b []byte) {
|
||||||
|
m.tx(append([]byte{reportID}, b...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *joystick) SendState() {
|
||||||
|
b, _ := m.State.MarshalBinary()
|
||||||
|
m.tx(b)
|
||||||
|
}
|
|
@ -1,52 +0,0 @@
|
||||||
package joystick
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime/volatile"
|
|
||||||
)
|
|
||||||
|
|
||||||
const bufferSize = 32
|
|
||||||
|
|
||||||
// RingBuffer is ring buffer implementation inspired by post at
|
|
||||||
// https://www.embeddedrelated.com/showthread/comp.arch.embedded/77084-1.php
|
|
||||||
type RingBuffer struct {
|
|
||||||
rxbuffer [bufferSize][16]byte
|
|
||||||
head volatile.Register8
|
|
||||||
tail volatile.Register8
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRingBuffer returns a new ring buffer.
|
|
||||||
func NewRingBuffer() *RingBuffer {
|
|
||||||
return &RingBuffer{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used returns how many bytes in buffer have been used.
|
|
||||||
func (rb *RingBuffer) Used() uint8 {
|
|
||||||
return uint8(rb.head.Get() - rb.tail.Get())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put stores a byte in the buffer. If the buffer is already
|
|
||||||
// full, the method will return false.
|
|
||||||
func (rb *RingBuffer) Put(val []byte) bool {
|
|
||||||
if rb.Used() != bufferSize {
|
|
||||||
rb.head.Set(rb.head.Get() + 1)
|
|
||||||
copy(rb.rxbuffer[rb.head.Get()%bufferSize][:], val)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns a byte from the buffer. If the buffer is empty,
|
|
||||||
// the method will return a false as the second value.
|
|
||||||
func (rb *RingBuffer) Get() ([]byte, bool) {
|
|
||||||
if rb.Used() != 0 {
|
|
||||||
rb.tail.Set(rb.tail.Get() + 1)
|
|
||||||
return rb.rxbuffer[rb.tail.Get()%bufferSize][:], true
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear resets the head and tail pointer to zero.
|
|
||||||
func (rb *RingBuffer) Clear() {
|
|
||||||
rb.head.Set(0)
|
|
||||||
rb.tail.Set(0)
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
package joystick
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
"machine/usb"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
jsEndpointOut = usb.HID_ENDPOINT_OUT // from PC
|
|
||||||
jsEndpointIn = usb.HID_ENDPOINT_IN // to PC
|
|
||||||
)
|
|
||||||
|
|
||||||
var js *Joystick
|
|
||||||
|
|
||||||
type Joystick struct {
|
|
||||||
State
|
|
||||||
buf *RingBuffer
|
|
||||||
waitTxc bool
|
|
||||||
rxHandlerFunc func(b []byte)
|
|
||||||
setupFunc func(setup usb.Setup) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func Enable(def Definitions, rxHandlerFunc func(b []byte),
|
|
||||||
setupFunc func(setup usb.Setup) bool, hidDesc []byte) *Joystick {
|
|
||||||
m := &Joystick{
|
|
||||||
buf: NewRingBuffer(),
|
|
||||||
State: def.NewState(),
|
|
||||||
}
|
|
||||||
m.State = def.NewState()
|
|
||||||
if setupFunc == nil {
|
|
||||||
setupFunc = m.setupFunc
|
|
||||||
}
|
|
||||||
machine.EnableJoystick(m.handler, rxHandlerFunc, setupFunc, hidDesc)
|
|
||||||
js = m
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// Port returns the USB Joystick port.
|
|
||||||
func Port() *Joystick {
|
|
||||||
if js == nil {
|
|
||||||
def := DefaultDefinitions()
|
|
||||||
js = &Joystick{
|
|
||||||
State: def.NewState(),
|
|
||||||
buf: NewRingBuffer(),
|
|
||||||
}
|
|
||||||
machine.EnableJoystick(js.handler, nil, js.setupFunc, def.Descriptor())
|
|
||||||
}
|
|
||||||
return js
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Joystick) sendUSBPacket(b []byte) {
|
|
||||||
machine.SendUSBInPacket(jsEndpointIn, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// from InterruptIn
|
|
||||||
func (m *Joystick) handler() {
|
|
||||||
m.waitTxc = false
|
|
||||||
if b, ok := m.buf.Get(); ok {
|
|
||||||
m.waitTxc = true
|
|
||||||
m.sendUSBPacket(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Joystick) setup(setup usb.Setup) bool {
|
|
||||||
if setup.BmRequestType == usb.SET_REPORT_TYPE && setup.BRequest == usb.SET_IDLE {
|
|
||||||
machine.SendZlp()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Joystick) rxHandler(b []byte) {
|
|
||||||
if m.rxHandlerFunc != nil {
|
|
||||||
m.rxHandlerFunc(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Joystick) tx(b []byte) {
|
|
||||||
if machine.USBDev.InitEndpointComplete {
|
|
||||||
if m.waitTxc {
|
|
||||||
m.buf.Put(b)
|
|
||||||
} else {
|
|
||||||
m.waitTxc = true
|
|
||||||
m.sendUSBPacket(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// to InterruptOut
|
|
||||||
func (m *Joystick) SendReport(reportID byte, b []byte) {
|
|
||||||
m.tx(append([]byte{reportID}, b...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Joystick) SendState() {
|
|
||||||
b, _ := m.State.MarshalBinary()
|
|
||||||
m.tx(b)
|
|
||||||
}
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче