Open KurtE opened 11 months ago
I wonder if it is something with the lower level (STM) NAK handling.
From what I understand from the traces the teensy is receiving multiple NAKs while the device works it out and then the data, looks good.
The GIGA is getting a single NAK and then a STALL.
Does that sound about right?
Same as before, except it sends it 1 more time, which still returns stalled. And then back to only SOF packets every ms for about a second until I issue the next request
I should mention that it does work on some devices, here is keyboard USB LS 8 byte control packets
And a different tablet USB HS - has two report descriptors: First is only 18 bytes
Second one is 119 bytes: But again 8 byte control endpoint so lots of packets... spread over a lot of time:
On the Teensy with the tablet that fails on GIGA:
So yes 3 NAKs before it responds true. But the time between when the request finished sending until the In attempt that starts retrieving data is about 21us
So wondering if timing?
Can you notice any differences between the USB data going from the teensy/giga to the tablet?
I do have a Wacom tablet somewhere but I have no idea where it is, I will attempt to spot it tomorrow...
As I mentioned, I wonder if some of this is about timing and the usage of the frames. That is I think the current code will check for the IN data something like once per frame.
It was hard for me to see exactly where the SOF frames are in some of these captures, so I spent a little time this morning hacking up a new HLA that put a "*" up at each SOF...
So for example with the last tablet I mentioned, (HUION) with the 119 byte HID descriptor which takes 15 data packets.
Again looks like we only ask for data once per 1ms frame: In this case the device is really slow so maybe does not matter as much:
On the Micromod: The USB Frames are sliced up into more parts. Probably depending on how many things are wanting some of the USB Band width. But for example the slow responding device for the HID descriptor shown earlier, Here is showing the frame with the request and start of the next frame:
And each of those sections within those portions are asking multiple times sometimes 15 times or so.
But this is the control end point... For later on when waiting for input it is just asking once per frame.
Doesn't It depend on the device: so if it is using frames it is 1ms, if it is using microframes it is 125us.
For (BULK and CONTROL) the underlying HAL/STM code will ask for another packet after it receives a packet, so every (1-n) ms or every (1-n) 125us depending on the device.
For input if using interrupt endpoints like HID then it is always 1ms.
I am also not an expert on some of this stuff, I have browsed through the USB documents some, such that I have some basic understandings.
I have also done a reasonable amount of work on the sort of layers above this low level stuff. PaulStoffregen does most/all of this lower stuff on the Teensy.
One of the websites I often go to with USB questions is: https://beyondlogic.org/usbnutshell/usb4.shtml#Control
If you go to the bottom of the above page, it talks about some of the bandwidth management stuff...
That is for ISO and INTERRUPT endpoints though.
When dealing with BULK and CONTROL I am pretty sure the transfer throughput is based on (Frames & packet size) or (Microframes & packet size).
So if the device is using Frames and an 8 byte packet and you are transferring 64 bytes it will take 8ms at best. 8 bytes per frame (1ms)
If the device is using Microframes and an 8 byte packet and you are transferring 64 bytes then it will take 1ms at best. 8 bytes per microframe (125us)
Edit: And looking at this: https://www.microchip.com/en-us/education/developer-help/learn-solutions/wired/usb/how-usb-works/frame
What I said is correct for CONTROL but it looks like BULK can have up to 19 transfers per frame or 13 transfers per microframe.
I found my cheap Wacom, unfortunately it works though (smaller HID Descriptor size):
*** starting Device information sketch ***
No USB[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBDeviceConnected.cpp:88]init dev: 0x2400f84c
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:634]USBEndpoint created (0x2400f1a4): type: 0, dir: 1, size: 8, addr: 0, state: USB_TYPE_IDLE
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:647]Resetting hub 0, port 1
host device connected
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:162]usb_thread read device descriptor on dev: 0x2400f84c
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:181]Address of 0x2400f84c: 1
[USB_INFO: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:206]New device connected: 0x2400f84c [hub: 0 - port: 1]
Device:0x2400f84c
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:963]dev: 0x2400f84c nb_intf: 0
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:964]dev: 0x2400f84c nb_intf_attached: 0
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:970]Enumerate dev: 0x2400f84c
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:986]CLASS: 00 VID: 056A PID: 00D2
VID: 56A, PID: d2
Speed: 0
Size of configuration Descriptor: 59
[USB_DBG: src/USBDumperDevice.cpp:406]TOTAL_LENGTH: 59 NUM_INTERF: 2
bNumInterfaces: 2
bConfigurationValue: 1
iConfiguration: 0
bmAttributes: 128
bMaxPower: 49
bInterfaceNumber: 0
bAlternateSetting: 0
Number of endpoints: 1
bInterfaceClass: 3
bInterfaceSubClass: 1
bInterfaceProtocol: 2
iInterface: 0
HID Descriptor size: 176
81 Attrributes: 3 Size: 9
Interval: 4
>>>>> USBDumperDevice::getHIDDesc(0) called <<<<<
HID Report Descriptor (0x24011228) size: 176
05 01 // Usage Page(1) - 09 02 // Usage(2) - A1 01 // Collection(1) top Usage(10000) 85 01 // Report ID(1) 09 01 // Usage(1) - A1 00 // Collection(0) 05 09 // Usage Page(9) - 19 01 // Usage Minimum(1) - (BUTTON 1) 29 05 // Usage Maximum(5) - (BUTTON 5) 15 00 // Logical Minimum(0) 25 01 // Logical maximum(1) 95 05 // Report Count(5) 75 01 // Report Size(1) 81 02 // Input(2) // ( 95 01 // Report Count(1) 75 03 // Report Size(3) 81 01 // Input(1) // ( 05 01 // Usage Page(1) - 09 30 // Usage(30) - 09 31 // Usage(31) - 15 81 // Logical Minimum(81) 25 7F // Logical maximum(7f) 75 08 // Report Size(8) 95 02 // Report Count(2) 81 06 // Input(6) // ( C0 C0 05 0D // Usage Page(d) - 09 01 // Usage(1) - A1 01 // Collection(1) top Usage(d0000) 85 02 // Report ID(2) A1 00 // Collection(0) 06 00 FF // Usage Page(ff00) - 09 01 // Usage(1) - 15 00 // Logical Minimum(0) 26 FF 00 // Logical maximum(ff) 75 08 // Report Size(8) 95 08 // Report Count(8) 81 02 // Input(2) // ( C0 09 01 // Usage(1) - 85 02 // Report ID(2) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 03 // Report ID(3) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 04 // Report ID(4) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 05 // Report ID(5) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 10 // Report ID(10) 95 02 // Report Count(2) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 11 // Report ID(11) 95 10 // Report Count(10) B1 02// Feature(2) // ( 09 01 // Usage(1) - 85 13 // Report ID(13) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 20 // Report ID(20) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 21 // Report ID(21) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 06 // Report ID(6) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 07 // Report ID(7) 95 01 // Report Count(1) B1 02 // Feature(2) // ( 09 01 // Usage(1) - 85 14 // Report ID(14) 95 01 // Report Count(1) B1 02 // Feature(2) // ( C0 bInterfaceNumber: 1
bAlternateSetting: 0
Number of endpoints: 1
bInterfaceClass: 3
bInterfaceSubClass: 0
bInterfaceProtocol: 0
iInterface: 0
HID Descriptor size: 75
82 Attrributes: 3 Size: 64
Interval: 4
>>>>> USBDumperDevice::getHIDDesc(1) called <<<<<
HID Report Descriptor (0x24011290) size: 75
06 00 FF // Usage Page(ff00) - 09 01 // Usage(1) - A1 01 // Collection(1) top Usage(ff000000) 85 02 // Report ID(2) 05 0D // Usage Page(d) - 09 22 // Usage(22) - A1 00 // Collection(0) 06 00 FF // Usage Page(ff00) - 09 01 // Usage(1) - 15 00 // Logical Minimum(0) 26 FF 00 // Logical maximum(ff) 75 08 // Report Size(8) 95 02 // Report Count(2) 81 02 // Input(2) // ( 05 01 // Usage Page(1) - 09 30 // Usage(30) - 35 00 // Physical Minimum(0) 46 E0 2E // Physical Maximum(2ee0) 26 E0 01 // Logical maximum(1e0) 75 10 // Report Size(10) 95 01 // Report Count(1) 81 02 // Input(2) // ( 09 31 // Usage(31) - 46 40 1F // Physical Maximum(1f40) 26 40 01 // Logical maximum(140) 81 02 // Input(2)// ( 06 00 FF // Usage Page(ff00) - 09 01 // Usage(1) - 26 FF 00 // Logical maximum(ff) 75 08 // Report Size(8) 95 0D // Report Count(d) 81 02 // Input(2) // ( C0 C0[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:902]TOTAL_LENGTH: 59 NUM_INTERF: 2
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:999]CONFIGURATION DESCRIPTOR:
09 02 3B 00 02 01 00 80 31 09 04 00 00 01 03 01 02 00 09 21 00 01 00 01 22 B0 00 07 05 81 03 09 00 04 09 04 01 00 01 03 00 00 00 09 21 00 01 00 01 22 4B 00 07 05 82 03 40 00 04
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:1051]dev: 0x2400f84c has 2 intf
parseInterface nb:0
bInterfaceClass = 3
bInterfaceSubClass = 1
bProtocol = 2
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:1060]ADD INTF 0 on device 0x2400f84c: class: 3, subclass: 1, proto: 2
useEndpoint(0, 3, 2)
parseInterface nb:1
bInterfaceClass = 3
bInterfaceSubClass = 0
bProtocol = 0
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:1012]Set configuration 1 on dev: 0x2400f84c
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:1025]dev 0x2400f84c is enumerated
New Debug device: VID:056a PID:00d2 [dev: 0x2400f84c - intf: 0]
[USB_DBG: lib/Arduino_USBHostMbed5/src/USBHost/USBHost.h:172]register driver for dev: 0x2400f84c on intf: 0
USB host device(56a:d2) connected
Manufacturer: Wacom Co.,Ltd.
Product: CTH-461
Just tried a HUION one as well, also worked as well, even smaller descriptor size though.
I'm running through in the debugger with a size of 759
Looking in `stm32h7xx_ii_usb.c"
/* Compute the expected number of packets associated to the transfer */
if (hc->xfer_len > 0U)
{
num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
if (num_packets > max_hc_pkt_count)
{
num_packets = max_hc_pkt_count;
hc->XferSize = (uint32_t)num_packets * hc->max_packet;
}
}
else
{
num_packets = 1U;
}
max_hc_pkt_count is 256 so that's not the problem, it calculates (8 byte packets) that we need 95 packets correctly.
Then:
/*
* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of
* max_packet size.
*/
if (hc->ep_is_in != 0U)
{
hc->XferSize = (uint32_t)num_packets * hc->max_packet;
}
else
{
hc->XferSize = hc->xfer_len;
}
We get a XferSize of 760 here.
So it looks like the underlying stuff is calculating the packets needed correctly.
Hi @KurtE
While I was looking at the HUION tablet I noticed that we were sometimes still getting USB interrupt flooding despite the NAK fixes.
So I looked into this and tracked it down to the "Channel Halted Interrupt".
I have updated https://github.com/arduino-libraries/Arduino_USBHostMbed5/pull/42 to also stop this CHH interrupt flooding.
Might be worth you giving this version a go, maybe there is an outside chance this might have something to do with your issue.
Hold off on those recent changes, with the CHH interrupt flooding turned off we are not getting any data from the interrupt endpoint, looking into it...
Ok fixed that issue, the CHH flooding is only disabled for the CONTROL endpoints now.
Might be worth a go to see if it sorts your issue, slim chance I would guess.
Thanks, will give your changes a try and see if they help. May wait until I get more coffee in me. About 4:45am here...
Note: The wacom tablet with the large HID has 64 byte control endpoint size. So only about 12 packets needed
As I have mentioned on the forum: https://forum.arduino.cc/t/can-not-find-examples-for-usbhostserial/1182486/17 I am trying to hack up some code similar to the USBHostSerial code that works with other USB to Serial adapters other than those which are CDC ACM devices. Ones like FTDI, Prolific...
On the forum thread: I posted an example sketch which reproduces this, but just about any sketch that will print out the wrong IDS. VID: 0103 PID: 0000
Where other code bases on some other Arduinos, plus Windows and Ubuntu return the IDs: vid=403 pid=6001
Note: I just tried plugging it in to the GIGA board, with my Logic Analyzer hooked up to it, with my modified USB Analyzer and HLA, which helps reduce the data down...
The Packets that I received on the GIGA:
I don't have time today, but it almost looks like the device is still only returning a max of something like 8 bytes at a time... And You are probably indexing off the end of the data, and maybe not waiting for the additional data packets to be returned.
If I remember correctly on the Teensy USBHost code, we first asked for the device descriptor, for its first 8 bytes, and then update the control endpoint to the size specified in those first 8 bytes and then asked for the whole endpoint...