machine/usb/hid/joystick: move joystick under HID as it belongs and also remove duplicate code

Signed-off-by: deadprogram <ron@hybridgroup.com>
Этот коммит содержится в:
deadprogram 2023-03-31 15:40:40 +02:00 коммит произвёл Ron Evans
родитель 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 Обычный файл
Просмотреть файл

@ -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)
}