From 8f33721b882b79f6f224698823bf5e3354fccd3b Mon Sep 17 00:00:00 2001 From: Kenneth Bell Date: Wed, 5 Oct 2022 16:18:56 +0100 Subject: [PATCH] usb: remove allocs in ISR --- src/machine/machine_rp2040_usb.go | 27 ++++++++++++++----------- src/machine/usb.go | 33 ++++++++++++++++++++----------- src/machine/usb/cdc/usbcdc.go | 19 +++++++++--------- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/src/machine/machine_rp2040_usb.go b/src/machine/machine_rp2040_usb.go index 108f6838..ce94ec94 100644 --- a/src/machine/machine_rp2040_usb.go +++ b/src/machine/machine_rp2040_usb.go @@ -305,23 +305,26 @@ type USBBuffer struct { } var ( - usbDPSRAM = (*USBDPSRAM)(unsafe.Pointer(uintptr(0x50100000))) - epXdata0 [16]bool + usbDPSRAM = (*USBDPSRAM)(unsafe.Pointer(uintptr(0x50100000))) + epXdata0 [16]bool + setupBytes [8]byte ) func (d *USBDPSRAM) setupBytes() []byte { - var buf [8]byte - buf[0] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In.Get()) - buf[1] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In.Get() >> 8) - buf[2] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In.Get() >> 16) - buf[3] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].In.Get() >> 24) - buf[4] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out.Get()) - buf[5] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out.Get() >> 8) - buf[6] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out.Get() >> 16) - buf[7] = byte(d.EPxControl[usb.CONTROL_ENDPOINT].Out.Get() >> 24) + data := d.EPxControl[usb.CONTROL_ENDPOINT].In.Get() + setupBytes[0] = byte(data) + setupBytes[1] = byte(data >> 8) + setupBytes[2] = byte(data >> 16) + setupBytes[3] = byte(data >> 24) - return buf[:] + data = d.EPxControl[usb.CONTROL_ENDPOINT].Out.Get() + setupBytes[4] = byte(data) + setupBytes[5] = byte(data >> 8) + setupBytes[6] = byte(data >> 16) + setupBytes[7] = byte(data >> 24) + + return setupBytes[:] } func (d *USBDPSRAM) clear() { diff --git a/src/machine/usb.go b/src/machine/usb.go index 313920a7..3fbec539 100644 --- a/src/machine/usb.go +++ b/src/machine/usb.go @@ -72,6 +72,13 @@ var udd_ep_in_cache_buffer [7][64]uint8 //go:align 4 var udd_ep_out_cache_buffer [7][64]uint8 +// usb_trans_buffer max size is 255 since that is max size +// for a descriptor (bLength is 1 byte), and the biggest use +// for this buffer is to transmit string descriptors. If +// this buffer is used for new purposes in future the length +// must be revisited. +var usb_trans_buffer [255]uint8 + var ( usbTxHandler [usb.NumberOfEndpoints]func() usbRxHandler [usb.NumberOfEndpoints]func([]byte) @@ -113,16 +120,19 @@ func sendDescriptor(setup usb.Setup) { case usb.STRING_DESCRIPTOR_TYPE: switch setup.WValueL { case 0: - b := []byte{0x04, 0x03, 0x09, 0x04} - sendUSBPacket(0, b, setup.WLength) + usb_trans_buffer[0] = 0x04 + usb_trans_buffer[1] = 0x03 + usb_trans_buffer[2] = 0x09 + usb_trans_buffer[3] = 0x04 + sendUSBPacket(0, usb_trans_buffer[:4], setup.WLength) case usb.IPRODUCT: - b := make([]byte, (len(usb_STRING_PRODUCT)<<1)+2) + b := usb_trans_buffer[:(len(usb_STRING_PRODUCT)<<1)+2] strToUTF16LEDescriptor(usb_STRING_PRODUCT, b) sendUSBPacket(0, b, setup.WLength) case usb.IMANUFACTURER: - b := make([]byte, (len(usb_STRING_MANUFACTURER)<<1)+2) + b := usb_trans_buffer[:(len(usb_STRING_MANUFACTURER)<<1)+2] strToUTF16LEDescriptor(usb_STRING_MANUFACTURER, b) sendUSBPacket(0, b, setup.WLength) @@ -149,15 +159,16 @@ func sendDescriptor(setup usb.Setup) { func handleStandardSetup(setup usb.Setup) bool { switch setup.BRequest { case usb.GET_STATUS: - buf := []byte{0, 0} + usb_trans_buffer[0] = 0 + usb_trans_buffer[1] = 0 if setup.BmRequestType != 0 { // endpoint if isEndpointHalt { - buf[0] = 1 + usb_trans_buffer[0] = 1 } } - sendUSBPacket(0, buf, setup.WLength) + sendUSBPacket(0, usb_trans_buffer[:2], setup.WLength) return true case usb.CLEAR_FEATURE: @@ -189,8 +200,8 @@ func handleStandardSetup(setup usb.Setup) bool { return false case usb.GET_CONFIGURATION: - buff := []byte{usbConfiguration} - sendUSBPacket(0, buff, setup.WLength) + usb_trans_buffer[0] = usbConfiguration + sendUSBPacket(0, usb_trans_buffer[:1], setup.WLength) return true case usb.SET_CONFIGURATION: @@ -208,8 +219,8 @@ func handleStandardSetup(setup usb.Setup) bool { } case usb.GET_INTERFACE: - buff := []byte{usbSetInterface} - sendUSBPacket(0, buff, setup.WLength) + usb_trans_buffer[0] = usbSetInterface + sendUSBPacket(0, usb_trans_buffer[:1], setup.WLength) return true case usb.SET_INTERFACE: diff --git a/src/machine/usb/cdc/usbcdc.go b/src/machine/usb/cdc/usbcdc.go index b341f494..5b5ffbf7 100644 --- a/src/machine/usb/cdc/usbcdc.go +++ b/src/machine/usb/cdc/usbcdc.go @@ -129,19 +129,20 @@ func cdcCallbackRx(b []byte) { } } +var cdcSetupBuff [cdcLineInfoSize]byte + 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 - b[0] = byte(usbLineInfo.dwDTERate) - b[1] = byte(usbLineInfo.dwDTERate >> 8) - b[2] = byte(usbLineInfo.dwDTERate >> 16) - b[3] = byte(usbLineInfo.dwDTERate >> 24) - b[4] = byte(usbLineInfo.bCharFormat) - b[5] = byte(usbLineInfo.bParityType) - b[6] = byte(usbLineInfo.bDataBits) + cdcSetupBuff[0] = byte(usbLineInfo.dwDTERate) + cdcSetupBuff[1] = byte(usbLineInfo.dwDTERate >> 8) + cdcSetupBuff[2] = byte(usbLineInfo.dwDTERate >> 16) + cdcSetupBuff[3] = byte(usbLineInfo.dwDTERate >> 24) + cdcSetupBuff[4] = byte(usbLineInfo.bCharFormat) + cdcSetupBuff[5] = byte(usbLineInfo.bParityType) + cdcSetupBuff[6] = byte(usbLineInfo.bDataBits) - machine.SendUSBInPacket(0, b[:]) + machine.SendUSBInPacket(0, cdcSetupBuff[:]) return true } }