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 (
|
||||
"log"
|
||||
"machine/usb/joystick"
|
||||
"machine/usb/hid/joystick"
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
|
|
@ -50,6 +50,8 @@ func handler() {
|
|||
}
|
||||
}
|
||||
|
||||
var DefaultSetupHandler = setupHandler
|
||||
|
||||
func setupHandler(setup usb.Setup) bool {
|
||||
ok := false
|
||||
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)
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче