samd21,samd51,nrf52840: add support for USBHID (keyboard / mouse)

This commit is contained in:
sago35
2022-06-02 08:29:13 +09:00
committed by Ron Evans
parent 2c93a4085c
commit 1b2e764835
13 changed files with 1510 additions and 479 deletions
+46 -8
View File
@@ -1987,7 +1987,8 @@ type USBCDC struct {
var (
// USB is a USB CDC interface.
USB = &USBCDC{Buffer: NewRingBuffer()}
USB = &USBCDC{Buffer: NewRingBuffer()}
waitHidTxc bool
)
const (
@@ -2241,6 +2242,9 @@ func handleUSBIRQ(interrupt.Interrupt) {
// Start of frame
if (flags & sam.USB_DEVICE_INTFLAG_SOF) > 0 {
USB.Flush()
if hidCallback != nil && !waitHidTxc {
hidCallback()
}
// if you want to blink LED showing traffic, this would be the place...
}
@@ -2264,6 +2268,9 @@ func handleUSBIRQ(interrupt.Interrupt) {
// Class Interface Requests
if setup.wIndex == usb_CDC_ACM_INTERFACE {
ok = cdcSetup(setup)
} else if setup.bmRequestType == usb_SET_REPORT_TYPE && setup.bRequest == usb_SET_IDLE {
sendZlp()
ok = true
}
}
@@ -2302,6 +2309,9 @@ func handleUSBIRQ(interrupt.Interrupt) {
if i == usb_CDC_ENDPOINT_IN {
USB.waitTxc = false
}
case usb_HID_ENDPOINT_IN:
setEPINTFLAG(i, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1)
waitHidTxc = false
}
}
}
@@ -2399,7 +2409,7 @@ func handleStandardSetup(setup usbSetup) bool {
}
}
sendUSBPacket(0, buf)
sendUSBPacket(0, buf, setup.wLength)
return true
case usb_CLEAR_FEATURE:
@@ -2455,7 +2465,7 @@ func handleStandardSetup(setup usbSetup) bool {
case usb_GET_CONFIGURATION:
buff := []byte{usbConfiguration}
sendUSBPacket(0, buff)
sendUSBPacket(0, buff, setup.wLength)
return true
case usb_SET_CONFIGURATION:
@@ -2472,6 +2482,11 @@ func handleStandardSetup(setup usbSetup) bool {
// Enable interrupt for CDC data messages from host
setEPINTENSET(usb_CDC_ENDPOINT_OUT, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT0)
// Enable interrupt for HID messages from host
if hidCallback != nil {
setEPINTENSET(usb_HID_ENDPOINT_IN, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)
}
sendZlp()
return true
} else {
@@ -2480,7 +2495,7 @@ func handleStandardSetup(setup usbSetup) bool {
case usb_GET_INTERFACE:
buff := []byte{usbSetInterface}
sendUSBPacket(0, buff)
sendUSBPacket(0, buff, setup.wLength)
return true
case usb_SET_INTERFACE:
@@ -2506,7 +2521,7 @@ func cdcSetup(setup usbSetup) bool {
b[5] = byte(usbLineInfo.bParityType)
b[6] = byte(usbLineInfo.bDataBits)
sendUSBPacket(0, b[:])
sendUSBPacket(0, b[:], setup.wLength)
return true
}
}
@@ -2549,9 +2564,32 @@ func cdcSetup(setup usbSetup) bool {
return false
}
// SendUSBHIDPacket sends a packet for USBHID (interrupt / in).
func SendUSBHIDPacket(ep uint32, data []byte) bool {
if waitHidTxc {
return false
}
sendUSBPacket(ep, data, 0)
// clear transfer complete flag
setEPINTFLAG(ep, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_TRCPT1)
// send data by setting bank ready
setEPSTATUSSET(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSSET_BK1RDY)
waitHidTxc = true
return true
}
//go:noinline
func sendUSBPacket(ep uint32, data []byte) {
copy(udd_ep_in_cache_buffer[ep][:], data)
func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
l := uint16(len(data))
if 0 < maxsize && maxsize < l {
l = maxsize
}
copy(udd_ep_in_cache_buffer[ep][:], data[:l])
// Set endpoint address for sending data
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
@@ -2561,7 +2599,7 @@ func sendUSBPacket(ep uint32, data []byte) {
// set byte count, which is total number of bytes to be sent
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(uint32((len(data) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos))
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits((uint32(l) & usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask) << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
}
func receiveUSBControlPacket() ([cdcLineInfoSize]byte, error) {