Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 10 additions & 130 deletions src/machine/machine_atsamd21.go
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,8 @@ func handleUSB(intr interrupt.Interrupt) {
// clear stall request
setEPINTENCLR(0, sam.USB_DEVICE_EPINTENCLR_STALL1)
}
} else {
sendZlp()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line appears to have caused the regression. What is it supposed to be doing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I added to send a zlp when the other cases were not handled, which seemed to correct an issue with the USB enumeration on Windows 10, based on a comment from @sago35

Removing that line gets it to work on Linux and macOS, but does not work on Windows 10. I suppose that means we need to further investigate what Windows in sending as the initial request.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a proposal for sendZlp() below and in the comments that follow.
However, I'm not sure that this idea is correct.
#884 (comment)

The samd51 I'm trying has five USB Device EndPoint Interrupt Flags.

https://www.mouser.com/datasheet/2/268/60001507A-1130176.pdf
P.1161.

I did an additional check on atsamd51 and USB-CDC worked if you called sendZlp() on TRCPT0.
It may be better to process TRCPT0 as follows.
My environment is Windows 10 + PyPortal (samd51).

sago35@f80cc33.

Since sendZlp() clears the bottom 12 bits of PCKSIZE, it assumes that BYTE_COUNT = 0.
The PCKSIZE is described on P.1197.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR, which probably exists only in Windows, needs to be handled well.
Maybe a careful reading of the Aruduino and circuitpython sources will solve the problem.

#884 (comment)

Copy link
Member

@sago35 sago35 Mar 31, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This process is not in machine_atsamd51.go.
On the else side, sendZlp () may not be necessary or should not be called.

https://github.com/adafruit/ArduinoCore-samd/blob/master/cores/arduino/USB/USBCore.cpp#L951

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see #1013 I think you have the right idea @sago35

}

// Now the actual transfer handlers, ignore endpoint number 0 (setup)
Expand Down Expand Up @@ -1599,7 +1601,7 @@ func handleStandardSetup(setup usbSetup) bool {
} else if setup.wValueL == 0 { // ENDPOINTHALT
isEndpointHalt = false
}
sendZlp(0)
sendZlp()
return true

case usb_SET_FEATURE:
Expand All @@ -1608,7 +1610,7 @@ func handleStandardSetup(setup usbSetup) bool {
} else if setup.wValueL == 0 { // ENDPOINTHALT
isEndpointHalt = true
}
sendZlp(0)
sendZlp()
return true

case usb_SET_ADDRESS:
Expand Down Expand Up @@ -1663,7 +1665,7 @@ func handleStandardSetup(setup usbSetup) bool {
// Enable interrupt for CDC data messages from host
setEPINTENSET(usb_CDC_ENDPOINT_OUT, sam.USB_DEVICE_EPINTENSET_TRCPT0)

sendZlp(0)
sendZlp()
return true
} else {
return false
Expand All @@ -1677,7 +1679,7 @@ func handleStandardSetup(setup usbSetup) bool {
case usb_SET_INTERFACE:
usbSetInterface = setup.wValueL

sendZlp(0)
sendZlp()
return true

default:
Expand Down Expand Up @@ -1722,14 +1724,14 @@ func cdcSetup(setup usbSetup) bool {
} else {
// TODO: cancel any reset
}
sendZlp(0)
sendZlp()
}

if setup.bRequest == usb_CDC_SEND_BREAK {
// TODO: something with this value?
// breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
// return false;
sendZlp(0)
sendZlp()
}
return true
}
Expand Down Expand Up @@ -1788,128 +1790,6 @@ func receiveUSBControlPacket() []byte {
return data
}

// sendDescriptor creates and sends the various USB descriptor types that
// can be requested by the host.
func sendDescriptor(setup usbSetup) {
switch setup.wValueH {
case usb_CONFIGURATION_DESCRIPTOR_TYPE:
sendConfiguration(setup)
return
case usb_DEVICE_DESCRIPTOR_TYPE:
if setup.wLength == 8 {
// composite descriptor requested, so only send 8 bytes
dd := NewDeviceDescriptor(0xEF, 0x02, 0x01, 64, usb_VID, usb_PID, 0x100, usb_IMANUFACTURER, usb_IPRODUCT, usb_ISERIAL, 1)
sendUSBPacket(0, dd.Bytes()[:8])
} else {
// complete descriptor requested so send entire packet
dd := NewDeviceDescriptor(0x02, 0x00, 0x00, 64, usb_VID, usb_PID, 0x100, usb_IMANUFACTURER, usb_IPRODUCT, usb_ISERIAL, 1)
sendUSBPacket(0, dd.Bytes())
}
return

case usb_STRING_DESCRIPTOR_TYPE:
switch setup.wValueL {
case 0:
b := make([]byte, 4)
b[0] = 0x04
b[1] = 0x03
b[2] = 0x09
b[3] = 0x04
sendUSBPacket(0, b)
return

case usb_IPRODUCT:
prod := []byte(usb_STRING_PRODUCT)
b := make([]byte, len(prod)*2+2)
b[0] = byte(len(prod)*2 + 2)
b[1] = 0x03

for i, val := range prod {
b[i*2+2] = val
b[i*2+3] = 0
}

sendUSBPacket(0, b)
return

case usb_IMANUFACTURER:
prod := []byte(usb_STRING_MANUFACTURER)
b := make([]byte, len(prod)*2+2)
b[0] = byte(len(prod)*2 + 2)
b[1] = 0x03

for i, val := range prod {
b[i*2+2] = val
b[i*2+3] = 0
}

sendUSBPacket(0, b)
return

case usb_ISERIAL:
// TODO: allow returning a product serial number
sendZlp(0)
}

// send final zero length packet and return
sendZlp(0)
return
}

// do not know how to handle this message, so return zero
sendZlp(0)
return
}

// sendConfiguration creates and sends the configuration packet to the host.
func sendConfiguration(setup usbSetup) {
if setup.wLength == 9 {
sz := uint16(configDescriptorSize + cdcSize)
config := NewConfigDescriptor(sz, 2)
sendUSBPacket(0, config.Bytes())
} else {
iad := NewIADDescriptor(0, 2, usb_CDC_COMMUNICATION_INTERFACE_CLASS, usb_CDC_ABSTRACT_CONTROL_MODEL, 0)

cif := NewInterfaceDescriptor(usb_CDC_ACM_INTERFACE, 1, usb_CDC_COMMUNICATION_INTERFACE_CLASS, usb_CDC_ABSTRACT_CONTROL_MODEL, 0)

header := NewCDCCSInterfaceDescriptor(usb_CDC_HEADER, usb_CDC_V1_10&0xFF, (usb_CDC_V1_10>>8)&0x0FF)

controlManagement := NewACMFunctionalDescriptor(usb_CDC_ABSTRACT_CONTROL_MANAGEMENT, 6)

functionalDescriptor := NewCDCCSInterfaceDescriptor(usb_CDC_UNION, usb_CDC_ACM_INTERFACE, usb_CDC_DATA_INTERFACE)

callManagement := NewCMFunctionalDescriptor(usb_CDC_CALL_MANAGEMENT, 1, 1)

cifin := NewEndpointDescriptor((usb_CDC_ENDPOINT_ACM | usbEndpointIn), usb_ENDPOINT_TYPE_INTERRUPT, 0x10, 0x10)

dif := NewInterfaceDescriptor(usb_CDC_DATA_INTERFACE, 2, usb_CDC_DATA_INTERFACE_CLASS, 0, 0)

out := NewEndpointDescriptor((usb_CDC_ENDPOINT_OUT | usbEndpointOut), usb_ENDPOINT_TYPE_BULK, usbEndpointPacketSize, 0)

in := NewEndpointDescriptor((usb_CDC_ENDPOINT_IN | usbEndpointIn), usb_ENDPOINT_TYPE_BULK, usbEndpointPacketSize, 0)

cdc := NewCDCDescriptor(iad,
cif,
header,
controlManagement,
functionalDescriptor,
callManagement,
cifin,
dif,
out,
in)

sz := uint16(configDescriptorSize + cdcSize)
config := NewConfigDescriptor(sz, 2)

buf := make([]byte, 0, sz)
buf = append(buf, config.Bytes()...)
buf = append(buf, cdc.Bytes()...)

sendUSBPacket(0, buf)
}
}

func handleEndpoint(ep uint32) {
// get data
count := int((usbEndpointDescriptors[ep].DeviceDescBank[0].PCKSIZE.Get() >>
Expand All @@ -1930,8 +1810,8 @@ func handleEndpoint(ep uint32) {
setEPSTATUSCLR(ep, sam.USB_DEVICE_EPSTATUSCLR_BK0RDY)
}

func sendZlp(ep uint32) {
usbEndpointDescriptors[ep].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
func sendZlp() {
usbEndpointDescriptors[0].DeviceDescBank[1].PCKSIZE.ClearBits(usb_DEVICE_PCKSIZE_BYTE_COUNT_Mask << usb_DEVICE_PCKSIZE_BYTE_COUNT_Pos)
}

func epPacketSize(size uint16) uint32 {
Expand Down
Loading