aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/machine/machine_atsamd21.go
diff options
context:
space:
mode:
authorsago35 <[email protected]>2022-06-02 08:29:13 +0900
committerRon Evans <[email protected]>2022-06-11 09:44:09 +0200
commit1b2e764835fb5278de144caf059cb094bad4db23 (patch)
tree1a28c06af78d4a1d2db023a752817ae2ecc42808 /src/machine/machine_atsamd21.go
parent2c93a4085cf3b8783d10129698ddaaa2d9e1fbc4 (diff)
downloadtinygo-1b2e764835fb5278de144caf059cb094bad4db23.tar.gz
tinygo-1b2e764835fb5278de144caf059cb094bad4db23.zip
samd21,samd51,nrf52840: add support for USBHID (keyboard / mouse)
Diffstat (limited to 'src/machine/machine_atsamd21.go')
-rw-r--r--src/machine/machine_atsamd21.go53
1 files changed, 45 insertions, 8 deletions
diff --git a/src/machine/machine_atsamd21.go b/src/machine/machine_atsamd21.go
index 9b18a3130..d88190254 100644
--- a/src/machine/machine_atsamd21.go
+++ b/src/machine/machine_atsamd21.go
@@ -1746,7 +1746,8 @@ type USBCDC struct {
}
var (
- USB = &USBCDC{Buffer: NewRingBuffer()}
+ USB = &USBCDC{Buffer: NewRingBuffer()}
+ waitHidTxc bool
)
const (
@@ -1999,6 +2000,9 @@ func handleUSB(intr interrupt.Interrupt) {
if (flags & sam.USB_DEVICE_INTFLAG_SOF) > 0 {
USB.Flush()
// if you want to blink LED showing traffic, this would be the place...
+ if hidCallback != nil && !waitHidTxc {
+ hidCallback()
+ }
}
// Endpoint 0 Setup interrupt
@@ -2021,6 +2025,9 @@ func handleUSB(intr 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
}
}
@@ -2059,6 +2066,9 @@ func handleUSB(intr interrupt.Interrupt) {
if i == usb_CDC_ENDPOINT_IN {
USB.waitTxc = false
}
+ case usb_HID_ENDPOINT_IN:
+ setEPINTFLAG(i, sam.USB_DEVICE_EPINTFLAG_TRCPT1)
+ waitHidTxc = false
}
}
}
@@ -2156,7 +2166,7 @@ func handleStandardSetup(setup usbSetup) bool {
}
}
- sendUSBPacket(0, buf)
+ sendUSBPacket(0, buf, setup.wLength)
return true
case usb_CLEAR_FEATURE:
@@ -2212,7 +2222,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:
@@ -2229,6 +2239,11 @@ func handleStandardSetup(setup usbSetup) bool {
// Enable interrupt for CDC data messages from host
setEPINTENSET(usb_CDC_ENDPOINT_OUT, sam.USB_DEVICE_EPINTENSET_TRCPT0)
+ // Enable interrupt for HID messages from host
+ if hidCallback != nil {
+ setEPINTENSET(usb_HID_ENDPOINT_IN, sam.USB_DEVICE_EPINTENSET_TRCPT1)
+ }
+
sendZlp()
return true
} else {
@@ -2237,7 +2252,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:
@@ -2263,7 +2278,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
}
}
@@ -2306,9 +2321,31 @@ 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_EPINTFLAG_TRCPT1)
+
+ // send data by setting bank ready
+ setEPSTATUSSET(ep, sam.USB_DEVICE_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]))))
@@ -2318,7 +2355,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) {