-
Notifications
You must be signed in to change notification settings - Fork 11
GIGA R1: devices such as FTDI adapters with control endpoint transfer size=8 reading device descriptor does not work #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Are you using the most recent version from GitHub? I had this 8 byte issue before, pretty sure using the version from GitHub fixed this. |
I think the last setSizeControlEndpoint was not there before:
Without that last |
Actually I think I'm wrong, I have been testing loads of midi devices and one of them returns the size requested in buf[7], so 8. using instead:
And this device then enumerates. |
Incorrectly it seems, ignore me! |
Right, I think this is related to : #31 (with 8 bytes instead of 64) The device I have here wants to deal with 8 byte packets, I guess the same as your one. So when it tries to get the full 18 bytes to get the VID and PID, this going to require 3 packets. The existing code should request these three packets but it doesn't work for me here:
![]() for status : 0 = URB_IDLE, 1=URB_DONE, 2 = URB_NOTREADY So you can see the first URB_DONE, then the code requests another 8 byte packet, we get two URB_IDLE then multiple URB_NOTREADY where the code keeps retrying the last 8 bytes. May be different there but that's what I'm seeing here. |
I just tried a prolific one I have here but it works, it is using 64 byte packets though. |
I am running version 0.2.0 - and I don't see any other changes since then. Mine is slightly mucked up for debug, plus maybe forced to not simple callbacks... Looking at the data from Logic Analyzer:
The line:
So ID vendor(bytes 8-9): 0x403 and Product: 0x601 But it returned vid 0x103... Maybe like it skipped the middle packet. Maybe assuming end point size of 16? |
Is the device you are having trouble with returning 8 in buf[7]? What I was seeing with midi devices was that I was never getting > 64 bytes returned, so just a single packet. I was not seeing what you are seeing there with multiple packets with the existing code. They all had 64 byte packets. |
Yes it is returning 0x8 in buf[7] Where as the PL2303 device the USB data looks like:
So it has 64 byte control packets. And retrieved the proper VID/PID... Before it crashes... Currently in the Red blink... |
So with 64 byte packets here with the existing code the issue I was seeing was when the configuration data was > 64 bytes, only 64 bytes were ever returned. Changing to using HAL_HCD_HC_SubmitRequest() to request the full amount of data, say 101 bytes then fixed this issue for me. Which is what I was going on about in the other issue. I now have a midi device that only uses 8 byte packets, this is not working correctly at all HAL_HCD_HC_SubmitRequest() is not returning all the data with an 8 byte packet. Interestingly if I set the packet size to 64 and then request 8 times more data I get the 64 byte packets with the correct 8 bytes at the beginning of each. At the moment for me here I'm wondering about an underlying HAL issue with 8 byte packets. |
Could be HAL or their library, not sure where the code is that detects that requested data exceeded the size of a packet, and then requests or waits for the right number of data packets to come back in this case and pack the data into the correct buffer... Let alone what is there any support anywhere in this library and/or HAL when I plug in a high speed device who typically might send 512 byte packets, although I think the control endpoint stays at max 64 byte... |
The code as it is is using the code I posted above to split the packets, this code is in this repository. So they never call HAL_HCD_HC_SubmitRequest() with greater than the packet size, they do all the work here. This is the code I was pretty sure is not working, so I changed it to let HAL_HCD_HC_SubmitRequest() split the packets as it already does this for you and this solved my issues with 64 byte packets and everything now works. You can see what I did in the PR in the other issue: #33 Unfortunately HAL_HCD_HC_SubmitRequest() doesn't seem to be working with 8 byte packets, the top level code looks fine it is requesting the correct number of packets, something is going wrong though. I hate USB stuff! |
Concerning packet sizes but from the device side I also found this one: arduino/ArduinoCore-mbed#736 |
@alrvid - Not sure if you are the main person on this library? @AndrewCapon - I am guessing that the code is losing packets. Note: I renamed the issue as I believe it is not specific to FTDI. I am also not sure how specific this is to reading the device descriptor, or if it might manifest issues, whenever a response to a request might span multiple USB packets. Or potentially if the device might generate a burst of data. More specifics about this manifestation: The USB analyzer code I have running on my Saleae Logic Analyzer shows that:
Probably does not show it very well, but there is about 8ms from the time of the request to the response. You can see this by the areas of blue at the top which is from the HLA analyzer showing the packet data. Zooming in on the 3 packet area: Looking at debug output
You can see it completely missed the data of the 2nd IN packet. And in fact used the first two bytes of the 3rd packet and assumed it received 8 bytes. i.e. it did not look at the actual size of data in the IN packet. Interesting that the USBHost::getDeviceDescriptor call has parameter to return the size of data returned, the return value actually just returns the size of data requested (or size of a device descriptor).... As a test, I tried hacking the 2nd request to get the descriptor from asking for 18 bytes and instead only ask for 16. And it returned all 0s after the first 8 bytes... Again, it lost the 2nd packet. Guessing: that maybe you don't have a request queued up in time to receive the 2nd part of the data. Sorry, I don't know enough about this board, to understand it's lower level mechanisms on queueing up requests. On some other systems, I believe there are ways to queue up multiple requests, such that when the hardware fills one, it is setup to handle the next, not sure if that is possible here or not. |
It also appears to be failing with CH340G like devices such as:
Comes back |
Hi @KurtE , From my fumblings I have noticed lengths reported and number of bytes logged in the USB debug messages cannot be trusted! I am sadly lacking a USB analyser, I do have a Saleae clone though, it is only 400mhz though. What is yours? I am looking into the USB_NOTREADY/NAK thing, I am guessing the issue may be originating here. What I don't understand though is that devices should not NAK on Setup messages, so we should never see NAKs when getting the device description (but I am here). Is this your understanding as well? |
Morning @AndrewCapon, I also don't have a full USB analyzer. Like a Beagle 12 (about $500) or 480 (about $1300 and up), which would be great for analyzing this stuff. I do however have a few Saleae logic analyzers. The main one I use is their Pro 8. Which has gone up in price a lot since I purchased it... You can still get the non-pro 8 as a student or as a hobbyist for about $250. They come with a USB analyzer setup for LS and FS (but can not handle HS). They have not yet updated it to support their newer High Level analyzer stuff, so I took a stab at it, which is working reasonably well for me.,,, Note: I was hoping that your stuff in your PR #33 would help with the stuff I am seeing. So far still no luck. Will double check I put in the change correctly. So far still not getting the configuration descriptor for some of these boards... Will double check I have it in the same way you do. |
Afternoon @KurtE Have you got a little breakout board for the usb signals then? PR 33 would help I'm guessing with 64 byte packets because that works here, it doesn't work with 8 byte packets here though, I'm trying to get to the bottom of it. Unfortunately I have messed my back up so can't sit at the desk so am trying to use an old laptop with Remote Desktop so the going is slow :) Basically what I am seeing is loads of NAKs, I can re-add in the code to handle NAKs (retransmit) which then means the descriptors work but it then goes wonky elsewhere. |
Sorry about your back... The center two pins are the D+ and D-... On my own boards, like the one in the picture (Micromod Teensy), I added breakout pins which are the two on the left of the USB Host connector, for those signals to make it easy. I will try a bit more with your changes to see what is happening. This code looks considerably different than the code USBHostGiga, So I might try a few more things out on that library to see how it differs on handling the packets. I don't understand why the released code, Tries to restrict the request down to one packet and then try to start up new request for next packet... I could be completely wrong, but I believe that the Channels on these boards are setup to handle transfers > packet_size... That is the OTG_HCTSIZx registers, look like they have fields for Transfer size, and then the 19 bits, then a packet count 10 bits. So I would think it should just handle it. I believe that it funnels down to HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma) which does:
So wondering if I am reading the stuff wrong, or there were problems with it or ??? |
The STM HAL stuff does handle multiple packets, the PR 33 I put in changes the "MBED" code to use this functionality. The existing MBED code does not though, the MBED code is never requesting more than one packet at a time, they do the handling of multiple packets themselves. If you look at the code I removed:
On a URB_DONE they (MBED) transmit the next packet, until all packets are done. they are doing this via They also handle the NAK (URB_NOTREADY) and re transmit the last packet. This is the code that I did not think was working , so the PR33 stops the MBED code doing this packet splitting and lets the underlying STM HAL code do it. (partly with the code bit you just posted) This PR 33 fixed all my problems for 64 byte packets. But it is not working with 8 byte packets here. |
Also of course our 8 byte issues may be different :) Mine seem to be based on NAKs. |
Thanks, as I mentioned, I think I brought in your changes... But might have messed up some... I also just now synced up the current GITHUB code changes, and then did a Winmerge to the one in libraries folder. Will try again. My gut tells me that a lot of these NAKs and data lost with current code is due to them doing the one packet at a time. An in between the time they process the one packet and issue new request for the next one, it may have lost one or more packets and then things get confused. |
Yes I think there is definitely a disconnect there, that code gets called every 20us. For the NAKs the existing code is terribly wrong it just spams the HAL submitrequest. but the bad news, even with letting the HAL deal with the full size and some more common sense NAK code (retry, wait 10 ms before another retry) I’m still getting missed data, and I’m guessing it is the data at the start. Need to check. I have dealt with the stm32 HAL device code before and that was pretty strange, maybe the host side us similar :) thanks for the pic about how you gave the usb connected, I would not gave thought of doing that! |
@AndrewCapon, For some reason, I did some more editing of my copy of the library with your changes. And AFAIK, I did not change anything related to these changes, but now in several cases it is now reading in the FTDI device descriptor (8 byte control endpoint)... Also was able to read some Teensy boards configuration descriptors, which was failing. It is still failing to read in the Arduino UNO R4 MINIMA, will investigate this some more... Maybe tomorrow or the next day or so. I am now curious, about when it connected up to the Teensy Micromod, I think it connected at USB FS (64 byte packets). The Teensy also support HS (512 byte packets). I think the USB on these STM boards support HS? Wondering if the library supports it... Maybe time to investigate. |
Morning @KurtE I have made a change that may be useful, I won't add it to the PR as I have loads of hacked stuff I am working on. in
to
This should help with any NAKs which the underlying HAL code doesn't handle itself. With the problem device I have here though I am still getting missed data even though all the data is being received into the USB fifo it is not ending up in the correct place, will be looking into this today. I'm getting close I think! |
So some success:
|
I am thinking though that this is more luck than judgement, I think there is another timing issue I have not quite got yet. here is the code to use rather than the previously posted code, it might help. I'm still investigating what exactly is going on though because this still failed sometimes. (don't worry about the recount bit not doing anything, still using that to investigate and it may well go in the end)
|
Ok a slight rethink, this code works with all the midi devices I have just tried. (Disconnect and reconnect seems buggy but I'm guessing that is something unrelated) The other devices even though they are 64 byte bulk packets were actually still using 8 byte control packets, the difference is they do not need the re-request from the NAKs, everything is handled correctly by the HAL. Doing the re-request confused the HAL. So we have one that needs the re-request and others that don't. The new Idea is that we basically ignore NAK/URB_NOTREADY for 10ms after any USB_TYPE_IDLE (this is on the transfer descriptor (td)). If we are still getting them after 10ms we resend the request.
|
Actually seems to work through a hub as well! As long as you only plug in one device in that is :) Two devices and red lights of doom, will investigate tomorrow. I need to get hubs working to have multiple controllers... |
@AndrewCapon @mjs513 - I am getting several warnings, plus an error on the line: |
Hi @KurtE Sorry that's some of my test code that I didn't remove, just delete that line. I will update the PR today. I have also managed to get multiple devices going, there is an issue with the MBED Hub code though, once a device is connected the HUB code seems to stop working and it doesn't recognise new devices. Will look into that a bit today... |
@AndrewCapon - changes on issue arduino-libraries#32
@AndrewCapon @mjs513 - Not sure if this is best place to mention. I think I still have one problem child with reading in descriptors. In this case it is a HID descriptor for a Wacom tablet. This descriptor is 759 bytes long. It errors out on the read on the GIGA. I verified it reads fine on Teensy. And the parser there properly decoded it.
Which failed as mentioned on the line: *** Failed to read in HID Report Descriptor *** On Teensy Micromod:
|
Hi @KurtE Can you set the debug fully on in dbg.h:
And post the log here. |
|
Hi @KurtE Can you try changing in
Try making that retry count larger, maybe 20, then 50, then 100 to see if that makes it work. Really this retry count should be based on a timer as |
Thanks, will try and let you know soon. |
Did not notice any difference. I think I may need to debug more... I am not seeing the tablet responding to the request... |
I guess you need to find out where that |
What's the time between the NAK and the STALL? Also yesterday I was a bit confused, these HID requests are on the Control Endpoint not the Interrupt Endpoint? Also as a quick test can you set |
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? |
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... |
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 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: 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):
|
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"
max_hc_pkt_count is 256 so that's not the problem, it calculates (8 byte packets) that we need 95 packets correctly. Then:
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 #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. 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...
The text was updated successfully, but these errors were encountered: