arduino-libraries / Arduino_USBHostMbed5

Apache License 2.0
4 stars 10 forks source link

GIGA R1: devices such as FTDI adapters with control endpoint transfer size=8 reading device descriptor does not work #32

Open KurtE opened 11 months ago

KurtE commented 11 months ago

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:

16.308830162 ; SETUP ; 0x0 ; 0x0 ; [GET_DESCRIPTOR - DEVICE #:0 I:0x0 L:0x8] ;  0x80 0x6 0x0 0x1 0x0 0x0 0x8 0x0
16.308907428 ; IN ; 0x0 ; 0x0 ;  ;  0x12 0x1 0x0 0x2 0x0 0x0 0x0 0x8
16.308963208 ; SETUP ; 0x0 ; 0x0 ; SET_ADDRESS I:0x0 L:0x0] ;  0x0 0x5 0x1 0x0 0x0 0x0 0x0 0x0
16.317414284 ; SETUP ; 0x0 ; 0x1 ; [GET_DESCRIPTOR - DEVICE #:0 I:0x0 L:0x8] ;  0x80 0x6 0x0 0x1 0x0 0x0 0x8 0x0
16.317496376 ; IN ; 0x0 ; 0x1 ;  ;  0x12 0x1 0x0 0x2 0x0 0x0 0x0 0x8
20.478046968 ; SETUP ; 0x0 ; 0x1 ; [GET_DESCRIPTOR - DEVICE #:0 I:0x0 L:0x12] ;  0x80 0x6 0x0 0x1 0x0 0x0 0x12 0x0
20.478125602 ; IN ; 0x0 ; 0x1 ;  ;  0x12 0x1 0x0 0x2 0x0 0x0 0x0 0x8
20.478314948 ; IN ; 0x0 ; 0x1 ;  ;  0x3 0x4 0x1 0x60 0x0 0x6 0x1 0x2
20.478336022 ; IN ; 0x0 ; 0x1 ;  ;  0x3 0x1
20.502892408 ; SETUP ; 0x0 ; 0x1 ; [GET_DESCRIPTOR - CONFIG #:0 I:0x0 L:0x9] ;  0x80 0x6 0x0 0x2 0x0 0x0 0x9 0x0
20.503027744 ; IN ; 0x0 ; 0x1 ;  ;  0x9 0x2 0x20 0x0 0x1 0x1 0x0 0xa0
20.50305689 ; IN ; 0x0 ; 0x1 ;  ;  0x2d
20.510192198 ; SETUP ; 0x0 ; 0x1 ; [GET_DESCRIPTOR - CONFIG #:0 I:0x0 L:0x20] ;  0x80 0x6 0x0 0x2 0x0 0x0 0x20 0x0
20.510326864 ; IN ; 0x0 ; 0x1 ;  ;  0x9 0x2 0x20 0x0 0x1 0x1 0x0 0xa0
20.510358858 ; IN ; 0x0 ; 0x1 ;  ;  0x2d 0x9 0x4 0x0 0x0 0x2 0xff 0xff
20.510387752 ; IN ; 0x0 ; 0x1 ;  ;  0xff 0x2 0x7 0x5 0x81 0x2 0x40 0x0
20.510416558 ; IN ; 0x0 ; 0x1 ;  ;  0x0 0x7 0x5 0x2 0x2 0x40 0x0 0x0

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...

AndrewCapon commented 10 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?

KurtE commented 10 months ago

image

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 image

And a different tablet USB HS - has two report descriptors: First is only 18 bytes image

Second one is 119 bytes: But again 8 byte control endpoint so lots of packets... spread over a lot of time: image

On the Teensy with the tablet that fails on GIGA: image

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?

AndrewCapon commented 10 months ago

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...

KurtE commented 10 months ago

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: image 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: image

And each of those sections within those portions are asking multiple times sometimes 15 times or so. image

But this is the control end point... For later on when waiting for input it is just asking once per frame.

AndrewCapon commented 10 months ago

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.

KurtE commented 10 months ago

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...

AndrewCapon commented 10 months ago

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.

AndrewCapon commented 10 months ago

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
AndrewCapon commented 10 months ago

Just tried a HUION one as well, also worked as well, even smaller descriptor size though.

AndrewCapon commented 10 months ago

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.

AndrewCapon commented 10 months ago

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.

AndrewCapon commented 10 months ago

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...

AndrewCapon commented 10 months ago

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.

KurtE commented 10 months ago

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