arduino-libraries / Arduino_USBHostMbed5

Apache License 2.0
4 stars 11 forks source link

GIGA R1 - USBHost issues #31

Open AndrewCapon opened 1 year ago

AndrewCapon commented 1 year ago

Hi Guys,

I have managed to get a hacked version running a Midi Host:

[USB_TRANSFER: .pio/libdeps/giga_m7/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:1100]----- BULK READ [dev: 0x24010554 - MIDI - hub: 0 - port: 1 - addr: 1 - ep: 81]------
[USB_EVENT: .pio/libdeps/giga_m7/Arduino_USBHostMbed5/src/USBHost/USBHost.cpp:274]call callback on td 0x2400161f [ep: 0x2400ffdc state: USB_TYPE_IDLE - dev: 0x24010554 - MIDI]
READ SUCCESS [64 bytes transferred - td: 0x2400161F] on ep: [0x2400ffdc - addr: 81]: 0B B0 4F 5B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

[USB_INFO: .pio/libdeps/giga_m7/Arduino_USBHostMbed5/src/USBHostMIDI/USBHostMIDI.cpp:102] MIDI MESSAGE b, b0, 4f, 5b

Along the way I have found the following:

First issue: Getting the configuration descriptor was not working, this was due to only a maximum of 64 bytes being returned, so any data after this was being lost.

In USBEndpoint_STM.cpp :

  1. queueTransfer() will only call HAL_HCD_HC_SubmitRequest with a maximum size of 64.
  2. HAL_HCD_HC_NotifyURBChange_Callback() has code on URB_DONE to call HAL_HCD_HC_SubmitRequest() to get the next packet of data, the call works but something is going wrong. We do not get another URB_DONE, so the maximum data returned is 64 bytes.

HAL_HCD_HC_SubmitRequest() can internally handle this packet splitting, you can just request all the data needed and it will work it out. I changed the code to do this and now the data is returned correctly. There is still an issue with control->ep_queue.get(TD_TIMEOUT_CTRL); timing out that I need to look into, the data is there but we get the timeout.

Second issue: The dreaded MBED_CONF_PLATFORM_CALLBACK_NONTRIVIAL=0 causing the callbacks to fail. See https://github.com/arduino-libraries/Arduino_USBHostMbed5/issues/29#issuecomment-1783933038

This was fixed by forcing MBED_CONF_PLATFORM_CALLBACK_NONTRIVIAL=1 in callback.h

So I guess the question is if the maximum size of 64 bytes is a known issue?

AndrewCapon commented 1 year ago

I have looked into the issue with the timeouts.

Basically what I was seeing was that if I had a break in the debugger, after the addTransfer() on the control->ep_queue.get(TD_TIMEOUT_CTRL) line then we got no timeout and correct data with my changes.

So here is what I was seeing without this breakpoint:

Screenshot 2023-10-30 at 05 45 25

Status is one of:

  URB_IDLE = 0
  URB_DONE = 1
  URB_NOTREADY = 2
  URB_NYET = 3
  URB_ERROR = 4
  URB_STALL =5

bulk.ctrl is a HAL_HCD_HC_NotifyURBChange_Callback() for the bulk or ctrl.

So we can see the first status we get is URB_NOTREADY after 62us.

The existing code to handle URB_NOTREADY will take this as meaning the device was not ready and will call HAL_HCD_HC_SubmitRequest() again.

We then get a URB_NOTREADY again a little later and it does the same, this drives it all into a URB_STALL state and in the end the queue will timeout.

I'm not a USB expert in anyway but I'm a little unsure that the device can respond in 62us (and it is always around this time), I would be thinking 125us which is more around where we see the stall.

So I'm not really sure that URB_NOTREADY signifies that the device is not ready but more likely something within the HAL USB code?

So I cut out the URB_NOTREADY code as a test and we now get this:

Screenshot 2023-10-30 at 05 52 02

Bingo, everything works. we get a status of URB_DONE, transferCompleted() is called and the queue.get() works. The full amount of data is available.

So it looks like the URB_NOTREADY code needs a bit of work.

I have tested all my changes with midi devices and mass storage devices and it all works.

AndrewCapon commented 1 year ago

I added a pr so you can see the code changes: https://github.com/arduino-libraries/Arduino_USBHostMbed5/pull/33

AndrewCapon commented 1 year ago

I have tested 6 midi devices here, 5 work fine.

1 has a problem and seems to require URB_NOTREADY handling, but not all the time.

I'm really not sure that URB_NOTREADY can be trusted!