machine/usb: refactorings to move functionality under machine/usb package
Signed-off-by: deadprogram <ron@hybridgroup.com>
Этот коммит содержится в:
родитель
ea36fea5a9
коммит
3c2d2a93d3
9 изменённых файлов: 279 добавлений и 271 удалений
|
@ -5,6 +5,7 @@ package machine
|
|||
|
||||
import (
|
||||
"device/sam"
|
||||
"machine/usb"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -117,7 +118,7 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
// End of reset
|
||||
if (flags & sam.USB_DEVICE_INTFLAG_EORST) > 0 {
|
||||
// Configure control endpoint
|
||||
initEndpoint(0, usb_ENDPOINT_TYPE_CONTROL)
|
||||
initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL)
|
||||
|
||||
usbConfiguration = 0
|
||||
|
||||
|
@ -136,14 +137,14 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
setEPINTFLAG(0, sam.USB_DEVICE_EPINTFLAG_RXSTP)
|
||||
|
||||
// parse setup
|
||||
setup := newUSBSetup(udd_ep_out_cache_buffer[0][:])
|
||||
setup := usb.NewSetup(udd_ep_out_cache_buffer[0][:])
|
||||
|
||||
// Clear the Bank 0 ready flag on Control OUT
|
||||
setEPSTATUSCLR(0, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
||||
usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
|
||||
ok := false
|
||||
if (setup.BmRequestType & usb_REQUEST_TYPE) == usb_REQUEST_STANDARD {
|
||||
if (setup.BmRequestType & usb.REQUEST_TYPE) == usb.REQUEST_STANDARD {
|
||||
// Standard Requests
|
||||
ok = handleStandardSetup(setup)
|
||||
} else {
|
||||
|
@ -192,7 +193,7 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
|
||||
func initEndpoint(ep, config uint32) {
|
||||
switch config {
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn:
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
||||
|
@ -200,11 +201,11 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, ((usb_ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||
|
||||
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
||||
|
@ -212,7 +213,7 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, ((usb_ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
|
||||
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
|
||||
|
||||
// receive interrupts when current transfer complete
|
||||
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT0)
|
||||
|
@ -223,10 +224,10 @@ func initEndpoint(ep, config uint32) {
|
|||
// ready for next transfer
|
||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
|
||||
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut:
|
||||
// TODO: not really anything, seems like...
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointIn:
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
||||
|
@ -234,14 +235,14 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, ((usb_ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||
|
||||
// NAK on endpoint IN, the bank is not yet filled in.
|
||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK1RDY)
|
||||
|
||||
setEPINTENSET(ep, sam.USB_DEVICE_EPINTENSET_TRCPT1)
|
||||
|
||||
case usb_ENDPOINT_TYPE_CONTROL:
|
||||
case usb.ENDPOINT_TYPE_CONTROL:
|
||||
// Control OUT
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
@ -250,7 +251,7 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb_ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE0_Pos))
|
||||
|
||||
// Control IN
|
||||
// set packet size
|
||||
|
@ -260,7 +261,7 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb_ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_EPCFG_EPTYPE1_Pos))
|
||||
|
||||
// Prepare OUT endpoint for receive
|
||||
// set multi packet size for expected number of receive bytes on control OUT
|
||||
|
@ -277,7 +278,7 @@ func initEndpoint(ep, config uint32) {
|
|||
}
|
||||
}
|
||||
|
||||
func handleUSBSetAddress(setup USBSetup) bool {
|
||||
func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
// set packet size 64 with auto Zlp after transfer
|
||||
usbEndpointDescriptors[0].DeviceDescBank[1].PCKSIZE.Set((epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos) |
|
||||
uint32(1<<31)) // autozlp
|
||||
|
|
|
@ -5,6 +5,7 @@ package machine
|
|||
|
||||
import (
|
||||
"device/sam"
|
||||
"machine/usb"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -120,7 +121,7 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
// End of reset
|
||||
if (flags & sam.USB_DEVICE_INTFLAG_EORST) > 0 {
|
||||
// Configure control endpoint
|
||||
initEndpoint(0, usb_ENDPOINT_TYPE_CONTROL)
|
||||
initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL)
|
||||
|
||||
usbConfiguration = 0
|
||||
|
||||
|
@ -139,14 +140,14 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
setEPINTFLAG(0, sam.USB_DEVICE_ENDPOINT_EPINTFLAG_RXSTP)
|
||||
|
||||
// parse setup
|
||||
setup := newUSBSetup(udd_ep_out_cache_buffer[0][:])
|
||||
setup := usb.NewSetup(udd_ep_out_cache_buffer[0][:])
|
||||
|
||||
// Clear the Bank 0 ready flag on Control OUT
|
||||
setEPSTATUSCLR(0, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK0RDY)
|
||||
usbEndpointDescriptors[0].DeviceDescBank[0].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
|
||||
|
||||
ok := false
|
||||
if (setup.BmRequestType & usb_REQUEST_TYPE) == usb_REQUEST_STANDARD {
|
||||
if (setup.BmRequestType & usb.REQUEST_TYPE) == usb.REQUEST_STANDARD {
|
||||
// Standard Requests
|
||||
ok = handleStandardSetup(setup)
|
||||
} else {
|
||||
|
@ -195,7 +196,7 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
|
||||
func initEndpoint(ep, config uint32) {
|
||||
switch config {
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn:
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
||||
|
@ -203,11 +204,11 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, ((usb_ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
|
||||
setEPCFG(ep, ((usb.ENDPOINT_TYPE_INTERRUPT + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
|
||||
|
||||
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
||||
|
@ -215,7 +216,7 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, ((usb_ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
|
||||
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
|
||||
|
||||
// receive interrupts when current transfer complete
|
||||
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT0)
|
||||
|
@ -226,10 +227,10 @@ func initEndpoint(ep, config uint32) {
|
|||
// ready for next transfer
|
||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK0RDY)
|
||||
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut:
|
||||
// TODO: not really anything, seems like...
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointIn:
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
||||
|
@ -237,14 +238,14 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, ((usb_ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
|
||||
setEPCFG(ep, ((usb.ENDPOINT_TYPE_BULK + 1) << sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
|
||||
|
||||
// NAK on endpoint IN, the bank is not yet filled in.
|
||||
setEPSTATUSCLR(ep, sam.USB_DEVICE_ENDPOINT_EPSTATUSCLR_BK1RDY)
|
||||
|
||||
setEPINTENSET(ep, sam.USB_DEVICE_ENDPOINT_EPINTENSET_TRCPT1)
|
||||
|
||||
case usb_ENDPOINT_TYPE_CONTROL:
|
||||
case usb.ENDPOINT_TYPE_CONTROL:
|
||||
// Control OUT
|
||||
// set packet size
|
||||
usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.SetBits(epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos)
|
||||
|
@ -253,7 +254,7 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[0].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_out_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb_ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE0_Pos))
|
||||
|
||||
// Control IN
|
||||
// set packet size
|
||||
|
@ -263,7 +264,7 @@ func initEndpoint(ep, config uint32) {
|
|||
usbEndpointDescriptors[ep].DeviceDescBank[1].ADDR.Set(uint32(uintptr(unsafe.Pointer(&udd_ep_in_cache_buffer[ep]))))
|
||||
|
||||
// set endpoint type
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb_ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
|
||||
setEPCFG(ep, getEPCFG(ep)|((usb.ENDPOINT_TYPE_CONTROL+1)<<sam.USB_DEVICE_ENDPOINT_EPCFG_EPTYPE1_Pos))
|
||||
|
||||
// Prepare OUT endpoint for receive
|
||||
// set multi packet size for expected number of receive bytes on control OUT
|
||||
|
@ -280,7 +281,7 @@ func initEndpoint(ep, config uint32) {
|
|||
}
|
||||
}
|
||||
|
||||
func handleUSBSetAddress(setup USBSetup) bool {
|
||||
func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
// set packet size 64 with auto Zlp after transfer
|
||||
usbEndpointDescriptors[0].DeviceDescBank[1].PCKSIZE.Set((epPacketSize(64) << usb_DEVICE_PCKSIZE_SIZE_Pos) |
|
||||
uint32(1<<31)) // autozlp
|
||||
|
|
|
@ -6,6 +6,7 @@ package machine
|
|||
import (
|
||||
"device/arm"
|
||||
"device/nrf"
|
||||
"machine/usb"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
"unsafe"
|
||||
|
@ -100,7 +101,7 @@ func handleUSBIRQ(interrupt.Interrupt) {
|
|||
if (nrf.USBD.EVENTCAUSE.Get() & nrf.USBD_EVENTCAUSE_READY) > 0 {
|
||||
|
||||
// Configure control endpoint
|
||||
initEndpoint(0, usb_ENDPOINT_TYPE_CONTROL)
|
||||
initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL)
|
||||
nrf.USBD.USBPULLUP.Set(1)
|
||||
|
||||
usbConfiguration = 0
|
||||
|
@ -115,10 +116,10 @@ func handleUSBIRQ(interrupt.Interrupt) {
|
|||
// previous data was too big for one packet, so send a second
|
||||
ptr := sendOnEP0DATADONE.ptr
|
||||
count := sendOnEP0DATADONE.count
|
||||
if count > usbEndpointPacketSize {
|
||||
sendOnEP0DATADONE.offset += usbEndpointPacketSize
|
||||
if count > usb.EndpointPacketSize {
|
||||
sendOnEP0DATADONE.offset += usb.EndpointPacketSize
|
||||
sendOnEP0DATADONE.ptr = &udd_ep_control_cache_buffer[sendOnEP0DATADONE.offset]
|
||||
count = usbEndpointPacketSize
|
||||
count = usb.EndpointPacketSize
|
||||
}
|
||||
sendOnEP0DATADONE.count -= count
|
||||
sendViaEPIn(
|
||||
|
@ -148,7 +149,7 @@ func handleUSBIRQ(interrupt.Interrupt) {
|
|||
setup := parseUSBSetupRegisters()
|
||||
|
||||
ok := false
|
||||
if (setup.BmRequestType & usb_REQUEST_TYPE) == usb_REQUEST_STANDARD {
|
||||
if (setup.BmRequestType & usb.REQUEST_TYPE) == usb.REQUEST_STANDARD {
|
||||
// Standard Requests
|
||||
ok = handleStandardSetup(setup)
|
||||
} else {
|
||||
|
@ -202,8 +203,8 @@ func handleUSBIRQ(interrupt.Interrupt) {
|
|||
}
|
||||
}
|
||||
|
||||
func parseUSBSetupRegisters() USBSetup {
|
||||
return USBSetup{
|
||||
func parseUSBSetupRegisters() usb.Setup {
|
||||
return usb.Setup{
|
||||
BmRequestType: uint8(nrf.USBD.BMREQUESTTYPE.Get()),
|
||||
BRequest: uint8(nrf.USBD.BREQUEST.Get()),
|
||||
WValueL: uint8(nrf.USBD.WVALUEL.Get()),
|
||||
|
@ -215,23 +216,23 @@ func parseUSBSetupRegisters() USBSetup {
|
|||
|
||||
func initEndpoint(ep, config uint32) {
|
||||
switch config {
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn:
|
||||
enableEPIn(ep)
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
|
||||
nrf.USBD.INTENSET.Set(nrf.USBD_INTENSET_ENDEPOUT0 << ep)
|
||||
nrf.USBD.SIZE.EPOUT[ep].Set(0)
|
||||
enableEPOut(ep)
|
||||
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut:
|
||||
nrf.USBD.INTENSET.Set(nrf.USBD_INTENSET_ENDEPOUT0 << ep)
|
||||
nrf.USBD.SIZE.EPOUT[ep].Set(0)
|
||||
enableEPOut(ep)
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointIn:
|
||||
enableEPIn(ep)
|
||||
|
||||
case usb_ENDPOINT_TYPE_CONTROL:
|
||||
case usb.ENDPOINT_TYPE_CONTROL:
|
||||
enableEPIn(0)
|
||||
enableEPOut(0)
|
||||
nrf.USBD.INTENSET.Set(nrf.USBD_INTENSET_ENDEPOUT0 |
|
||||
|
@ -261,11 +262,11 @@ func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
|
|||
|
||||
if ep == 0 {
|
||||
copy(udd_ep_control_cache_buffer[:], data[:count])
|
||||
if count > usbEndpointPacketSize {
|
||||
sendOnEP0DATADONE.offset = usbEndpointPacketSize
|
||||
if count > usb.EndpointPacketSize {
|
||||
sendOnEP0DATADONE.offset = usb.EndpointPacketSize
|
||||
sendOnEP0DATADONE.ptr = &udd_ep_control_cache_buffer[sendOnEP0DATADONE.offset]
|
||||
sendOnEP0DATADONE.count = count - usbEndpointPacketSize
|
||||
count = usbEndpointPacketSize
|
||||
sendOnEP0DATADONE.count = count - usb.EndpointPacketSize
|
||||
count = usb.EndpointPacketSize
|
||||
}
|
||||
sendViaEPIn(
|
||||
ep,
|
||||
|
@ -316,7 +317,7 @@ func enableEPIn(ep uint32) {
|
|||
nrf.USBD.EPINEN.Set(epinen)
|
||||
}
|
||||
|
||||
func handleUSBSetAddress(setup USBSetup) bool {
|
||||
func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
// nrf USBD handles this
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ package machine
|
|||
import (
|
||||
"device/arm"
|
||||
"device/rp"
|
||||
"machine/usb"
|
||||
"runtime/interrupt"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -58,10 +59,10 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
// Setup packet received
|
||||
if (status & rp.USBCTRL_REGS_INTS_SETUP_REQ) > 0 {
|
||||
rp.USBCTRL_REGS.SIE_STATUS.Set(rp.USBCTRL_REGS_SIE_STATUS_SETUP_REC)
|
||||
setup := newUSBSetup(usbDPSRAM.setupBytes())
|
||||
setup := usb.NewSetup(usbDPSRAM.setupBytes())
|
||||
|
||||
ok := false
|
||||
if (setup.BmRequestType & usb_REQUEST_TYPE) == usb_REQUEST_STANDARD {
|
||||
if (setup.BmRequestType & usb.REQUEST_TYPE) == usb.REQUEST_STANDARD {
|
||||
// Standard Requests
|
||||
ok = handleStandardSetup(setup)
|
||||
} else {
|
||||
|
@ -84,8 +85,8 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
ep := uint32(0)
|
||||
data := sendOnEP0DATADONE.data
|
||||
count := len(data) - sendOnEP0DATADONE.offset
|
||||
if ep == 0 && count > usbEndpointPacketSize {
|
||||
count = usbEndpointPacketSize
|
||||
if ep == 0 && count > usb.EndpointPacketSize {
|
||||
count = usb.EndpointPacketSize
|
||||
}
|
||||
|
||||
sendViaEPIn(ep, data[sendOnEP0DATADONE.offset:], count)
|
||||
|
@ -122,7 +123,7 @@ func handleUSBIRQ(intr interrupt.Interrupt) {
|
|||
// Bus is reset
|
||||
if (status & rp.USBCTRL_REGS_INTS_BUS_RESET) > 0 {
|
||||
rp.USBCTRL_REGS.SIE_STATUS.Set(rp.USBCTRL_REGS_SIE_STATUS_BUS_RESET)
|
||||
initEndpoint(0, usb_ENDPOINT_TYPE_CONTROL)
|
||||
initEndpoint(0, usb.ENDPOINT_TYPE_CONTROL)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,31 +133,31 @@ func initEndpoint(ep, config uint32) {
|
|||
val |= offset
|
||||
|
||||
switch config {
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn:
|
||||
val |= usbEpControlEndpointTypeInterrupt
|
||||
usbDPSRAM.EPxControl[ep].In = val
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointOut:
|
||||
val |= usbEpControlEndpointTypeBulk
|
||||
usbDPSRAM.EPxControl[ep].Out = val
|
||||
usbDPSRAM.EPxBufferControl[ep].Out = USBBufferLen & usbBuf0CtrlLenMask
|
||||
usbDPSRAM.EPxBufferControl[ep].Out |= usbBuf0CtrlAvail
|
||||
|
||||
case usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointOut:
|
||||
case usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointOut:
|
||||
// TODO: not really anything, seems like...
|
||||
|
||||
case usb_ENDPOINT_TYPE_BULK | usbEndpointIn:
|
||||
case usb.ENDPOINT_TYPE_BULK | usb.EndpointIn:
|
||||
val |= usbEpControlEndpointTypeBulk
|
||||
usbDPSRAM.EPxControl[ep].In = val
|
||||
|
||||
case usb_ENDPOINT_TYPE_CONTROL:
|
||||
case usb.ENDPOINT_TYPE_CONTROL:
|
||||
val |= usbEpControlEndpointTypeControl
|
||||
usbDPSRAM.EPxBufferControl[ep].Out = usbBuf0CtrlAvail
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func handleUSBSetAddress(setup USBSetup) bool {
|
||||
func handleUSBSetAddress(setup usb.Setup) bool {
|
||||
sendUSBPacket(0, []byte{}, 0)
|
||||
|
||||
// last, set the device address to that requested by host
|
||||
|
@ -189,8 +190,8 @@ func sendUSBPacket(ep uint32, data []byte, maxsize uint16) {
|
|||
}
|
||||
|
||||
if ep == 0 {
|
||||
if count > usbEndpointPacketSize {
|
||||
count = usbEndpointPacketSize
|
||||
if count > usb.EndpointPacketSize {
|
||||
count = usb.EndpointPacketSize
|
||||
|
||||
sendOnEP0DATADONE.offset = count
|
||||
sendOnEP0DATADONE.data = data
|
||||
|
@ -298,14 +299,14 @@ var (
|
|||
func (d *USBDPSRAM) setupBytes() []byte {
|
||||
var buf [8]byte
|
||||
|
||||
buf[0] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].In)
|
||||
buf[1] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].In >> 8)
|
||||
buf[2] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].In >> 16)
|
||||
buf[3] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].In >> 24)
|
||||
buf[4] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].Out)
|
||||
buf[5] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].Out >> 8)
|
||||
buf[6] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].Out >> 16)
|
||||
buf[7] = byte(d.EPxControl[usb_CONTROL_ENDPOINT].Out >> 24)
|
||||
buf[0] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In)
|
||||
buf[1] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In >> 8)
|
||||
buf[2] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In >> 16)
|
||||
buf[3] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In >> 24)
|
||||
buf[4] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out)
|
||||
buf[5] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out >> 8)
|
||||
buf[6] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out >> 16)
|
||||
buf[7] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out >> 24)
|
||||
|
||||
return buf[:]
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ package machine
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"runtime/volatile"
|
||||
"machine/usb"
|
||||
)
|
||||
|
||||
type USBDevice struct {
|
||||
|
@ -27,15 +27,9 @@ type Serialer interface {
|
|||
RTS() bool
|
||||
}
|
||||
|
||||
var usbDescriptor = descriptorCDC
|
||||
var usbDescriptor = usb.DescriptorCDC
|
||||
|
||||
const (
|
||||
usbDescriptorConfigCDC = 1 << iota
|
||||
usbDescriptorConfigHID
|
||||
usbDescriptorConfigMIDI
|
||||
)
|
||||
|
||||
var usbDescriptorConfig uint8 = usbDescriptorConfigCDC
|
||||
var usbDescriptorConfig uint8 = usb.DescriptorConfigCDC
|
||||
|
||||
// strToUTF16LEDescriptor converts a utf8 string into a string descriptor
|
||||
// note: the following code only converts ascii characters to UTF16LE. In order
|
||||
|
@ -44,7 +38,7 @@ var usbDescriptorConfig uint8 = usbDescriptorConfigCDC
|
|||
// binary.
|
||||
func strToUTF16LEDescriptor(in string, out []byte) {
|
||||
out[0] = byte(len(out))
|
||||
out[1] = usb_STRING_DESCRIPTOR_TYPE
|
||||
out[1] = usb.STRING_DESCRIPTOR_TYPE
|
||||
for i, rune := range in {
|
||||
out[(i<<1)+2] = byte(rune)
|
||||
out[(i<<1)+3] = 0
|
||||
|
@ -52,11 +46,6 @@ func strToUTF16LEDescriptor(in string, out []byte) {
|
|||
return
|
||||
}
|
||||
|
||||
var (
|
||||
// TODO: allow setting these
|
||||
usb_STRING_LANGUAGE = [2]uint16{(3 << 8) | (2 + 2), 0x0409} // English
|
||||
)
|
||||
|
||||
const cdcLineInfoSize = 7
|
||||
|
||||
var (
|
||||
|
@ -65,7 +54,7 @@ var (
|
|||
)
|
||||
|
||||
var (
|
||||
usbEndpointDescriptors [numberOfEndpoints]usbDeviceDescriptor
|
||||
usbEndpointDescriptors [usb.NumberOfEndpoints]usb.DeviceDescriptor
|
||||
|
||||
udd_ep_control_cache_buffer [256]uint8
|
||||
udd_ep_in_cache_buffer [7][64]uint8
|
||||
|
@ -78,191 +67,71 @@ var (
|
|||
usbSetInterface uint8
|
||||
)
|
||||
|
||||
const (
|
||||
usb_IMANUFACTURER = 1
|
||||
usb_IPRODUCT = 2
|
||||
usb_ISERIAL = 3
|
||||
|
||||
usb_ENDPOINT_TYPE_DISABLE = 0xFF
|
||||
usb_ENDPOINT_TYPE_CONTROL = 0x00
|
||||
usb_ENDPOINT_TYPE_ISOCHRONOUS = 0x01
|
||||
usb_ENDPOINT_TYPE_BULK = 0x02
|
||||
usb_ENDPOINT_TYPE_INTERRUPT = 0x03
|
||||
|
||||
usb_DEVICE_DESCRIPTOR_TYPE = 1
|
||||
usb_CONFIGURATION_DESCRIPTOR_TYPE = 2
|
||||
usb_STRING_DESCRIPTOR_TYPE = 3
|
||||
usb_INTERFACE_DESCRIPTOR_TYPE = 4
|
||||
usb_ENDPOINT_DESCRIPTOR_TYPE = 5
|
||||
usb_DEVICE_QUALIFIER = 6
|
||||
usb_OTHER_SPEED_CONFIGURATION = 7
|
||||
usb_SET_REPORT_TYPE = 33
|
||||
usb_HID_REPORT_TYPE = 34
|
||||
|
||||
usbEndpointOut = 0x00
|
||||
usbEndpointIn = 0x80
|
||||
|
||||
numberOfEndpoints = 8
|
||||
usbEndpointPacketSize = 64 // 64 for Full Speed, EPT size max is 1024
|
||||
|
||||
// standard requests
|
||||
usb_GET_STATUS = 0
|
||||
usb_CLEAR_FEATURE = 1
|
||||
usb_SET_FEATURE = 3
|
||||
usb_SET_ADDRESS = 5
|
||||
usb_GET_DESCRIPTOR = 6
|
||||
usb_SET_DESCRIPTOR = 7
|
||||
usb_GET_CONFIGURATION = 8
|
||||
usb_SET_CONFIGURATION = 9
|
||||
usb_GET_INTERFACE = 10
|
||||
usb_SET_INTERFACE = 11
|
||||
|
||||
// non standard requests
|
||||
usb_SET_IDLE = 10
|
||||
|
||||
usb_DEVICE_CLASS_COMMUNICATIONS = 0x02
|
||||
usb_DEVICE_CLASS_HUMAN_INTERFACE = 0x03
|
||||
usb_DEVICE_CLASS_STORAGE = 0x08
|
||||
usb_DEVICE_CLASS_VENDOR_SPECIFIC = 0xFF
|
||||
|
||||
usb_CONFIG_POWERED_MASK = 0x40
|
||||
usb_CONFIG_BUS_POWERED = 0x80
|
||||
usb_CONFIG_SELF_POWERED = 0xC0
|
||||
usb_CONFIG_REMOTE_WAKEUP = 0x20
|
||||
|
||||
// Interface
|
||||
numberOfInterfaces = 3
|
||||
usb_CDC_ACM_INTERFACE = 0 // CDC ACM
|
||||
usb_CDC_DATA_INTERFACE = 1 // CDC Data
|
||||
usb_CDC_FIRST_ENDPOINT = 1
|
||||
usb_HID_INTERFACE = 2 // HID
|
||||
|
||||
// Endpoint
|
||||
usb_CONTROL_ENDPOINT = 0
|
||||
usb_CDC_ENDPOINT_ACM = 1
|
||||
usb_CDC_ENDPOINT_OUT = 2
|
||||
usb_CDC_ENDPOINT_IN = 3
|
||||
usb_HID_ENDPOINT_IN = 4
|
||||
usb_MIDI_ENDPOINT_OUT = 5
|
||||
usb_MIDI_ENDPOINT_IN = 6
|
||||
|
||||
// bmRequestType
|
||||
usb_REQUEST_HOSTTODEVICE = 0x00
|
||||
usb_REQUEST_DEVICETOHOST = 0x80
|
||||
usb_REQUEST_DIRECTION = 0x80
|
||||
|
||||
usb_REQUEST_STANDARD = 0x00
|
||||
usb_REQUEST_CLASS = 0x20
|
||||
usb_REQUEST_VENDOR = 0x40
|
||||
usb_REQUEST_TYPE = 0x60
|
||||
|
||||
usb_REQUEST_DEVICE = 0x00
|
||||
usb_REQUEST_INTERFACE = 0x01
|
||||
usb_REQUEST_ENDPOINT = 0x02
|
||||
usb_REQUEST_OTHER = 0x03
|
||||
usb_REQUEST_RECIPIENT = 0x1F
|
||||
|
||||
usb_REQUEST_DEVICETOHOST_CLASS_INTERFACE = (usb_REQUEST_DEVICETOHOST | usb_REQUEST_CLASS | usb_REQUEST_INTERFACE)
|
||||
usb_REQUEST_HOSTTODEVICE_CLASS_INTERFACE = (usb_REQUEST_HOSTTODEVICE | usb_REQUEST_CLASS | usb_REQUEST_INTERFACE)
|
||||
usb_REQUEST_DEVICETOHOST_STANDARD_INTERFACE = (usb_REQUEST_DEVICETOHOST | usb_REQUEST_STANDARD | usb_REQUEST_INTERFACE)
|
||||
)
|
||||
|
||||
var (
|
||||
usbTxHandler [numberOfEndpoints]func()
|
||||
usbRxHandler [numberOfEndpoints]func([]byte)
|
||||
usbSetupHandler [numberOfInterfaces]func(USBSetup) bool
|
||||
usbTxHandler [usb.NumberOfEndpoints]func()
|
||||
usbRxHandler [usb.NumberOfEndpoints]func([]byte)
|
||||
usbSetupHandler [usb.NumberOfInterfaces]func(usb.Setup) bool
|
||||
|
||||
endPoints = []uint32{
|
||||
usb_CONTROL_ENDPOINT: usb_ENDPOINT_TYPE_CONTROL,
|
||||
usb_CDC_ENDPOINT_ACM: (usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointIn),
|
||||
usb_CDC_ENDPOINT_OUT: (usb_ENDPOINT_TYPE_BULK | usbEndpointOut),
|
||||
usb_CDC_ENDPOINT_IN: (usb_ENDPOINT_TYPE_BULK | usbEndpointIn),
|
||||
usb_HID_ENDPOINT_IN: (usb_ENDPOINT_TYPE_DISABLE), // Interrupt In
|
||||
usb_MIDI_ENDPOINT_OUT: (usb_ENDPOINT_TYPE_DISABLE), // Bulk Out
|
||||
usb_MIDI_ENDPOINT_IN: (usb_ENDPOINT_TYPE_DISABLE), // Bulk In
|
||||
usb.CONTROL_ENDPOINT: usb.ENDPOINT_TYPE_CONTROL,
|
||||
usb.CDC_ENDPOINT_ACM: (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn),
|
||||
usb.CDC_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut),
|
||||
usb.CDC_ENDPOINT_IN: (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn),
|
||||
usb.HID_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Interrupt In
|
||||
usb.MIDI_ENDPOINT_OUT: (usb.ENDPOINT_TYPE_DISABLE), // Bulk Out
|
||||
usb.MIDI_ENDPOINT_IN: (usb.ENDPOINT_TYPE_DISABLE), // Bulk In
|
||||
}
|
||||
)
|
||||
|
||||
// usbDeviceDescBank is the USB device endpoint descriptor.
|
||||
type usbDeviceDescBank struct {
|
||||
ADDR volatile.Register32
|
||||
PCKSIZE volatile.Register32
|
||||
EXTREG volatile.Register16
|
||||
STATUS_BK volatile.Register8
|
||||
_reserved [5]volatile.Register8
|
||||
}
|
||||
|
||||
type usbDeviceDescriptor struct {
|
||||
DeviceDescBank [2]usbDeviceDescBank
|
||||
}
|
||||
|
||||
type USBSetup struct {
|
||||
BmRequestType uint8
|
||||
BRequest uint8
|
||||
WValueL uint8
|
||||
WValueH uint8
|
||||
WIndex uint16
|
||||
WLength uint16
|
||||
}
|
||||
|
||||
func newUSBSetup(data []byte) USBSetup {
|
||||
u := USBSetup{}
|
||||
u.BmRequestType = uint8(data[0])
|
||||
u.BRequest = uint8(data[1])
|
||||
u.WValueL = uint8(data[2])
|
||||
u.WValueH = uint8(data[3])
|
||||
u.WIndex = uint16(data[4]) | (uint16(data[5]) << 8)
|
||||
u.WLength = uint16(data[6]) | (uint16(data[7]) << 8)
|
||||
return u
|
||||
}
|
||||
|
||||
// sendDescriptor creates and sends the various USB descriptor types that
|
||||
// can be requested by the host.
|
||||
func sendDescriptor(setup USBSetup) {
|
||||
func sendDescriptor(setup usb.Setup) {
|
||||
switch setup.WValueH {
|
||||
case usb_CONFIGURATION_DESCRIPTOR_TYPE:
|
||||
case usb.CONFIGURATION_DESCRIPTOR_TYPE:
|
||||
sendUSBPacket(0, usbDescriptor.Configuration, setup.WLength)
|
||||
return
|
||||
case usb_DEVICE_DESCRIPTOR_TYPE:
|
||||
case usb.DEVICE_DESCRIPTOR_TYPE:
|
||||
// composite descriptor
|
||||
if (usbDescriptorConfig & usbDescriptorConfigHID) > 0 {
|
||||
usbDescriptor = descriptorCDCHID
|
||||
} else if (usbDescriptorConfig & usbDescriptorConfigMIDI) > 0 {
|
||||
usbDescriptor = descriptorCDCMIDI
|
||||
} else {
|
||||
usbDescriptor = descriptorCDC
|
||||
switch {
|
||||
case (usbDescriptorConfig & usb.DescriptorConfigHID) > 0:
|
||||
usbDescriptor = usb.DescriptorCDCHID
|
||||
case (usbDescriptorConfig & usb.DescriptorConfigMIDI) > 0:
|
||||
usbDescriptor = usb.DescriptorCDCMIDI
|
||||
default:
|
||||
usbDescriptor = usb.DescriptorCDC
|
||||
}
|
||||
|
||||
usbDescriptor.Configure(usb_VID, usb_PID)
|
||||
sendUSBPacket(0, usbDescriptor.Device, setup.WLength)
|
||||
return
|
||||
|
||||
case usb_STRING_DESCRIPTOR_TYPE:
|
||||
case usb.STRING_DESCRIPTOR_TYPE:
|
||||
switch setup.WValueL {
|
||||
case 0:
|
||||
b := []byte{0x04, 0x03, 0x09, 0x04}
|
||||
sendUSBPacket(0, b, setup.WLength)
|
||||
|
||||
case usb_IPRODUCT:
|
||||
case usb.IPRODUCT:
|
||||
b := make([]byte, (len(usb_STRING_PRODUCT)<<1)+2)
|
||||
strToUTF16LEDescriptor(usb_STRING_PRODUCT, b)
|
||||
sendUSBPacket(0, b, setup.WLength)
|
||||
|
||||
case usb_IMANUFACTURER:
|
||||
case usb.IMANUFACTURER:
|
||||
b := make([]byte, (len(usb_STRING_MANUFACTURER)<<1)+2)
|
||||
strToUTF16LEDescriptor(usb_STRING_MANUFACTURER, b)
|
||||
sendUSBPacket(0, b, setup.WLength)
|
||||
|
||||
case usb_ISERIAL:
|
||||
case usb.ISERIAL:
|
||||
// TODO: allow returning a product serial number
|
||||
SendZlp()
|
||||
}
|
||||
return
|
||||
case usb_HID_REPORT_TYPE:
|
||||
case usb.HID_REPORT_TYPE:
|
||||
if h, ok := usbDescriptor.HID[setup.WIndex]; ok {
|
||||
sendUSBPacket(0, h, setup.WLength)
|
||||
return
|
||||
}
|
||||
case usb_DEVICE_QUALIFIER:
|
||||
case usb.DEVICE_QUALIFIER:
|
||||
// skip
|
||||
default:
|
||||
}
|
||||
|
@ -272,9 +141,9 @@ func sendDescriptor(setup USBSetup) {
|
|||
return
|
||||
}
|
||||
|
||||
func handleStandardSetup(setup USBSetup) bool {
|
||||
func handleStandardSetup(setup usb.Setup) bool {
|
||||
switch setup.BRequest {
|
||||
case usb_GET_STATUS:
|
||||
case usb.GET_STATUS:
|
||||
buf := []byte{0, 0}
|
||||
|
||||
if setup.BmRequestType != 0 { // endpoint
|
||||
|
@ -286,7 +155,7 @@ func handleStandardSetup(setup USBSetup) bool {
|
|||
sendUSBPacket(0, buf, setup.WLength)
|
||||
return true
|
||||
|
||||
case usb_CLEAR_FEATURE:
|
||||
case usb.CLEAR_FEATURE:
|
||||
if setup.WValueL == 1 { // DEVICEREMOTEWAKEUP
|
||||
isRemoteWakeUpEnabled = false
|
||||
} else if setup.WValueL == 0 { // ENDPOINTHALT
|
||||
|
@ -295,7 +164,7 @@ func handleStandardSetup(setup USBSetup) bool {
|
|||
SendZlp()
|
||||
return true
|
||||
|
||||
case usb_SET_FEATURE:
|
||||
case usb.SET_FEATURE:
|
||||
if setup.WValueL == 1 { // DEVICEREMOTEWAKEUP
|
||||
isRemoteWakeUpEnabled = true
|
||||
} else if setup.WValueL == 0 { // ENDPOINTHALT
|
||||
|
@ -304,23 +173,23 @@ func handleStandardSetup(setup USBSetup) bool {
|
|||
SendZlp()
|
||||
return true
|
||||
|
||||
case usb_SET_ADDRESS:
|
||||
case usb.SET_ADDRESS:
|
||||
return handleUSBSetAddress(setup)
|
||||
|
||||
case usb_GET_DESCRIPTOR:
|
||||
case usb.GET_DESCRIPTOR:
|
||||
sendDescriptor(setup)
|
||||
return true
|
||||
|
||||
case usb_SET_DESCRIPTOR:
|
||||
case usb.SET_DESCRIPTOR:
|
||||
return false
|
||||
|
||||
case usb_GET_CONFIGURATION:
|
||||
case usb.GET_CONFIGURATION:
|
||||
buff := []byte{usbConfiguration}
|
||||
sendUSBPacket(0, buff, setup.WLength)
|
||||
return true
|
||||
|
||||
case usb_SET_CONFIGURATION:
|
||||
if setup.BmRequestType&usb_REQUEST_RECIPIENT == usb_REQUEST_DEVICE {
|
||||
case usb.SET_CONFIGURATION:
|
||||
if setup.BmRequestType&usb.REQUEST_RECIPIENT == usb.REQUEST_DEVICE {
|
||||
for i := 1; i < len(endPoints); i++ {
|
||||
initEndpoint(uint32(i), endPoints[i])
|
||||
}
|
||||
|
@ -333,12 +202,12 @@ func handleStandardSetup(setup USBSetup) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
case usb_GET_INTERFACE:
|
||||
case usb.GET_INTERFACE:
|
||||
buff := []byte{usbSetInterface}
|
||||
sendUSBPacket(0, buff, setup.WLength)
|
||||
return true
|
||||
|
||||
case usb_SET_INTERFACE:
|
||||
case usb.SET_INTERFACE:
|
||||
usbSetInterface = setup.WValueL
|
||||
|
||||
SendZlp()
|
||||
|
@ -349,30 +218,30 @@ func handleStandardSetup(setup USBSetup) bool {
|
|||
}
|
||||
}
|
||||
|
||||
func EnableCDC(txHandler func(), rxHandler func([]byte), setupHandler func(USBSetup) bool) {
|
||||
usbDescriptorConfig |= usbDescriptorConfigCDC
|
||||
endPoints[usb_CDC_ENDPOINT_ACM] = (usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointIn)
|
||||
endPoints[usb_CDC_ENDPOINT_OUT] = (usb_ENDPOINT_TYPE_BULK | usbEndpointOut)
|
||||
endPoints[usb_CDC_ENDPOINT_IN] = (usb_ENDPOINT_TYPE_BULK | usbEndpointIn)
|
||||
usbRxHandler[usb_CDC_ENDPOINT_OUT] = rxHandler
|
||||
usbTxHandler[usb_CDC_ENDPOINT_IN] = txHandler
|
||||
usbSetupHandler[usb_CDC_ACM_INTERFACE] = setupHandler // 0x02 (Communications and CDC Control)
|
||||
usbSetupHandler[usb_CDC_DATA_INTERFACE] = nil // 0x0A (CDC-Data)
|
||||
func EnableCDC(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool) {
|
||||
usbDescriptorConfig |= usb.DescriptorConfigCDC
|
||||
endPoints[usb.CDC_ENDPOINT_ACM] = (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn)
|
||||
endPoints[usb.CDC_ENDPOINT_OUT] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut)
|
||||
endPoints[usb.CDC_ENDPOINT_IN] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn)
|
||||
usbRxHandler[usb.CDC_ENDPOINT_OUT] = rxHandler
|
||||
usbTxHandler[usb.CDC_ENDPOINT_IN] = txHandler
|
||||
usbSetupHandler[usb.CDC_ACM_INTERFACE] = setupHandler // 0x02 (Communications and CDC Control)
|
||||
usbSetupHandler[usb.CDC_DATA_INTERFACE] = nil // 0x0A (CDC-Data)
|
||||
}
|
||||
|
||||
// EnableHID enables HID. This function must be executed from the init().
|
||||
func EnableHID(txHandler func(), rxHandler func([]byte), setupHandler func(USBSetup) bool) {
|
||||
usbDescriptorConfig |= usbDescriptorConfigHID
|
||||
endPoints[usb_HID_ENDPOINT_IN] = (usb_ENDPOINT_TYPE_INTERRUPT | usbEndpointIn)
|
||||
usbTxHandler[usb_HID_ENDPOINT_IN] = txHandler
|
||||
usbSetupHandler[usb_HID_INTERFACE] = setupHandler // 0x03 (HID - Human Interface Device)
|
||||
func EnableHID(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool) {
|
||||
usbDescriptorConfig |= usb.DescriptorConfigHID
|
||||
endPoints[usb.HID_ENDPOINT_IN] = (usb.ENDPOINT_TYPE_INTERRUPT | usb.EndpointIn)
|
||||
usbTxHandler[usb.HID_ENDPOINT_IN] = txHandler
|
||||
usbSetupHandler[usb.HID_INTERFACE] = setupHandler // 0x03 (HID - Human Interface Device)
|
||||
}
|
||||
|
||||
// EnableMIDI enables MIDI. This function must be executed from the init().
|
||||
func EnableMIDI(txHandler func(), rxHandler func([]byte), setupHandler func(USBSetup) bool) {
|
||||
usbDescriptorConfig |= usbDescriptorConfigMIDI
|
||||
endPoints[usb_MIDI_ENDPOINT_OUT] = (usb_ENDPOINT_TYPE_BULK | usbEndpointOut)
|
||||
endPoints[usb_MIDI_ENDPOINT_IN] = (usb_ENDPOINT_TYPE_BULK | usbEndpointIn)
|
||||
usbRxHandler[usb_MIDI_ENDPOINT_OUT] = rxHandler
|
||||
usbTxHandler[usb_MIDI_ENDPOINT_IN] = txHandler
|
||||
func EnableMIDI(txHandler func(), rxHandler func([]byte), setupHandler func(usb.Setup) bool) {
|
||||
usbDescriptorConfig |= usb.DescriptorConfigMIDI
|
||||
endPoints[usb.MIDI_ENDPOINT_OUT] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointOut)
|
||||
endPoints[usb.MIDI_ENDPOINT_IN] = (usb.ENDPOINT_TYPE_BULK | usb.EndpointIn)
|
||||
usbRxHandler[usb.MIDI_ENDPOINT_OUT] = rxHandler
|
||||
usbTxHandler[usb.MIDI_ENDPOINT_IN] = txHandler
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package cdc
|
|||
import (
|
||||
"errors"
|
||||
"machine"
|
||||
"machine/usb"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
|
@ -128,7 +129,7 @@ func cdcCallbackRx(b []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func cdcSetup(setup machine.USBSetup) bool {
|
||||
func cdcSetup(setup usb.Setup) bool {
|
||||
if setup.BmRequestType == usb_REQUEST_DEVICETOHOST_CLASS_INTERFACE {
|
||||
if setup.BRequest == usb_CDC_GET_LINE_CODING {
|
||||
var b [cdcLineInfoSize]byte
|
||||
|
|
|
@ -1,15 +1,27 @@
|
|||
//go:build sam || nrf52840 || rp2040
|
||||
// +build sam nrf52840 rp2040
|
||||
package usb
|
||||
|
||||
package machine
|
||||
import "runtime/volatile"
|
||||
|
||||
type USBDescriptor struct {
|
||||
// DeviceDescBank is the USB device endpoint descriptor.
|
||||
type DeviceDescBank struct {
|
||||
ADDR volatile.Register32
|
||||
PCKSIZE volatile.Register32
|
||||
EXTREG volatile.Register16
|
||||
STATUS_BK volatile.Register8
|
||||
_reserved [5]volatile.Register8
|
||||
}
|
||||
|
||||
type DeviceDescriptor struct {
|
||||
DeviceDescBank [2]DeviceDescBank
|
||||
}
|
||||
|
||||
type Descriptor struct {
|
||||
Device []byte
|
||||
Configuration []byte
|
||||
HID map[uint16][]byte
|
||||
}
|
||||
|
||||
func (d *USBDescriptor) Configure(idVendor, idProduct uint16) {
|
||||
func (d *Descriptor) Configure(idVendor, idProduct uint16) {
|
||||
d.Device[8] = byte(idVendor)
|
||||
d.Device[9] = byte(idVendor >> 8)
|
||||
d.Device[10] = byte(idProduct)
|
||||
|
@ -19,7 +31,7 @@ func (d *USBDescriptor) Configure(idVendor, idProduct uint16) {
|
|||
d.Configuration[3] = byte(len(d.Configuration) >> 8)
|
||||
}
|
||||
|
||||
var descriptorCDC = USBDescriptor{
|
||||
var DescriptorCDC = Descriptor{
|
||||
Device: []byte{
|
||||
0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01,
|
||||
},
|
||||
|
@ -38,7 +50,7 @@ var descriptorCDC = USBDescriptor{
|
|||
},
|
||||
}
|
||||
|
||||
var descriptorCDCHID = USBDescriptor{
|
||||
var DescriptorCDCHID = Descriptor{
|
||||
Device: []byte{
|
||||
0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01,
|
||||
},
|
||||
|
@ -72,7 +84,7 @@ var descriptorCDCHID = USBDescriptor{
|
|||
},
|
||||
}
|
||||
|
||||
var descriptorCDCMIDI = USBDescriptor{
|
||||
var DescriptorCDCMIDI = Descriptor{
|
||||
Device: []byte{
|
||||
0x12, 0x01, 0x00, 0x02, 0xef, 0x02, 0x01, 0x40, 0x86, 0x28, 0x2d, 0x80, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01,
|
||||
},
|
|
@ -3,6 +3,7 @@ package hid
|
|||
import (
|
||||
"errors"
|
||||
"machine"
|
||||
"machine/usb"
|
||||
)
|
||||
|
||||
// from usb-hid.go
|
||||
|
@ -48,7 +49,7 @@ func handler() {
|
|||
}
|
||||
}
|
||||
|
||||
func setupHandler(setup machine.USBSetup) bool {
|
||||
func setupHandler(setup usb.Setup) bool {
|
||||
ok := false
|
||||
if setup.BmRequestType == usb_SET_REPORT_TYPE && setup.BRequest == usb_SET_IDLE {
|
||||
machine.SendZlp()
|
||||
|
|
121
src/machine/usb/usb.go
Обычный файл
121
src/machine/usb/usb.go
Обычный файл
|
@ -0,0 +1,121 @@
|
|||
package usb
|
||||
|
||||
var (
|
||||
// TODO: allow setting these
|
||||
STRING_LANGUAGE = [2]uint16{(3 << 8) | (2 + 2), 0x0409} // English
|
||||
)
|
||||
|
||||
const (
|
||||
DescriptorConfigCDC = 1 << iota
|
||||
DescriptorConfigHID
|
||||
DescriptorConfigMIDI
|
||||
)
|
||||
|
||||
const (
|
||||
IMANUFACTURER = 1
|
||||
IPRODUCT = 2
|
||||
ISERIAL = 3
|
||||
|
||||
ENDPOINT_TYPE_DISABLE = 0xFF
|
||||
ENDPOINT_TYPE_CONTROL = 0x00
|
||||
ENDPOINT_TYPE_ISOCHRONOUS = 0x01
|
||||
ENDPOINT_TYPE_BULK = 0x02
|
||||
ENDPOINT_TYPE_INTERRUPT = 0x03
|
||||
|
||||
DEVICE_DESCRIPTOR_TYPE = 1
|
||||
CONFIGURATION_DESCRIPTOR_TYPE = 2
|
||||
STRING_DESCRIPTOR_TYPE = 3
|
||||
INTERFACE_DESCRIPTOR_TYPE = 4
|
||||
ENDPOINT_DESCRIPTOR_TYPE = 5
|
||||
DEVICE_QUALIFIER = 6
|
||||
OTHER_SPEED_CONFIGURATION = 7
|
||||
SET_REPORT_TYPE = 33
|
||||
HID_REPORT_TYPE = 34
|
||||
|
||||
EndpointOut = 0x00
|
||||
EndpointIn = 0x80
|
||||
|
||||
NumberOfEndpoints = 8
|
||||
EndpointPacketSize = 64 // 64 for Full Speed, EPT size max is 1024
|
||||
|
||||
// standard requests
|
||||
GET_STATUS = 0
|
||||
CLEAR_FEATURE = 1
|
||||
SET_FEATURE = 3
|
||||
SET_ADDRESS = 5
|
||||
GET_DESCRIPTOR = 6
|
||||
SET_DESCRIPTOR = 7
|
||||
GET_CONFIGURATION = 8
|
||||
SET_CONFIGURATION = 9
|
||||
GET_INTERFACE = 10
|
||||
SET_INTERFACE = 11
|
||||
|
||||
// non standard requests
|
||||
SET_IDLE = 10
|
||||
|
||||
DEVICE_CLASS_COMMUNICATIONS = 0x02
|
||||
DEVICE_CLASS_HUMAN_INTERFACE = 0x03
|
||||
DEVICE_CLASS_STORAGE = 0x08
|
||||
DEVICE_CLASS_VENDOR_SPECIFIC = 0xFF
|
||||
|
||||
CONFIG_POWERED_MASK = 0x40
|
||||
CONFIG_BUS_POWERED = 0x80
|
||||
CONFIG_SELF_POWERED = 0xC0
|
||||
CONFIG_REMOTE_WAKEUP = 0x20
|
||||
|
||||
// Interface
|
||||
NumberOfInterfaces = 3
|
||||
CDC_ACM_INTERFACE = 0 // CDC ACM
|
||||
CDC_DATA_INTERFACE = 1 // CDC Data
|
||||
CDC_FIRST_ENDPOINT = 1
|
||||
HID_INTERFACE = 2 // HID
|
||||
|
||||
// Endpoint
|
||||
CONTROL_ENDPOINT = 0
|
||||
CDC_ENDPOINT_ACM = 1
|
||||
CDC_ENDPOINT_OUT = 2
|
||||
CDC_ENDPOINT_IN = 3
|
||||
HID_ENDPOINT_IN = 4
|
||||
MIDI_ENDPOINT_OUT = 5
|
||||
MIDI_ENDPOINT_IN = 6
|
||||
|
||||
// bmRequestType
|
||||
REQUEST_HOSTTODEVICE = 0x00
|
||||
REQUEST_DEVICETOHOST = 0x80
|
||||
REQUEST_DIRECTION = 0x80
|
||||
|
||||
REQUEST_STANDARD = 0x00
|
||||
REQUEST_CLASS = 0x20
|
||||
REQUEST_VENDOR = 0x40
|
||||
REQUEST_TYPE = 0x60
|
||||
|
||||
REQUEST_DEVICE = 0x00
|
||||
REQUEST_INTERFACE = 0x01
|
||||
REQUEST_ENDPOINT = 0x02
|
||||
REQUEST_OTHER = 0x03
|
||||
REQUEST_RECIPIENT = 0x1F
|
||||
|
||||
REQUEST_DEVICETOHOST_CLASS_INTERFACE = (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE)
|
||||
REQUEST_HOSTTODEVICE_CLASS_INTERFACE = (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
|
||||
REQUEST_DEVICETOHOST_STANDARD_INTERFACE = (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE)
|
||||
)
|
||||
|
||||
type Setup struct {
|
||||
BmRequestType uint8
|
||||
BRequest uint8
|
||||
WValueL uint8
|
||||
WValueH uint8
|
||||
WIndex uint16
|
||||
WLength uint16
|
||||
}
|
||||
|
||||
func NewSetup(data []byte) Setup {
|
||||
u := Setup{}
|
||||
u.BmRequestType = uint8(data[0])
|
||||
u.BRequest = uint8(data[1])
|
||||
u.WValueL = uint8(data[2])
|
||||
u.WValueH = uint8(data[3])
|
||||
u.WIndex = uint16(data[4]) | (uint16(data[5]) << 8)
|
||||
u.WLength = uint16(data[6]) | (uint16(data[7]) << 8)
|
||||
return u
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче